ringbuf.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package freecache
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "io"
  7. )
  8. var ErrOutOfRange = errors.New("out of range")
  9. // Ring buffer has a fixed size, when data exceeds the
  10. // size, old data will be overwritten by new data.
  11. // It only contains the data in the stream from begin to end
  12. type RingBuf struct {
  13. begin int64 // beginning offset of the data stream.
  14. end int64 // ending offset of the data stream.
  15. data []byte
  16. index int //range from '0' to 'len(rb.data)-1'
  17. }
  18. func NewRingBuf(size int, begin int64) (rb RingBuf) {
  19. rb.data = make([]byte, size)
  20. rb.begin = begin
  21. rb.end = begin
  22. rb.index = 0
  23. return
  24. }
  25. // Create a copy of the buffer.
  26. func (rb *RingBuf) Dump() []byte {
  27. dump := make([]byte, len(rb.data))
  28. copy(dump, rb.data)
  29. return dump
  30. }
  31. func (rb *RingBuf) String() string {
  32. return fmt.Sprintf("[size:%v, start:%v, end:%v, index:%v]", len(rb.data), rb.begin, rb.end, rb.index)
  33. }
  34. func (rb *RingBuf) Size() int64 {
  35. return int64(len(rb.data))
  36. }
  37. func (rb *RingBuf) Begin() int64 {
  38. return rb.begin
  39. }
  40. func (rb *RingBuf) End() int64 {
  41. return rb.end
  42. }
  43. // read up to len(p), at off of the data stream.
  44. func (rb *RingBuf) ReadAt(p []byte, off int64) (n int, err error) {
  45. if off > rb.end || off < rb.begin {
  46. err = ErrOutOfRange
  47. return
  48. }
  49. var readOff int
  50. if rb.end-rb.begin < int64(len(rb.data)) {
  51. readOff = int(off - rb.begin)
  52. } else {
  53. readOff = rb.index + int(off-rb.begin)
  54. }
  55. if readOff >= len(rb.data) {
  56. readOff -= len(rb.data)
  57. }
  58. readEnd := readOff + int(rb.end-off)
  59. if readEnd <= len(rb.data) {
  60. n = copy(p, rb.data[readOff:readEnd])
  61. } else {
  62. n = copy(p, rb.data[readOff:])
  63. if n < len(p) {
  64. n += copy(p[n:], rb.data[:readEnd-len(rb.data)])
  65. }
  66. }
  67. if n < len(p) {
  68. err = io.EOF
  69. }
  70. return
  71. }
  72. func (rb *RingBuf) Write(p []byte) (n int, err error) {
  73. if len(p) > len(rb.data) {
  74. err = ErrOutOfRange
  75. return
  76. }
  77. for n < len(p) {
  78. written := copy(rb.data[rb.index:], p[n:])
  79. rb.end += int64(written)
  80. n += written
  81. rb.index += written
  82. if rb.index >= len(rb.data) {
  83. rb.index -= len(rb.data)
  84. }
  85. }
  86. if int(rb.end-rb.begin) > len(rb.data) {
  87. rb.begin = rb.end - int64(len(rb.data))
  88. }
  89. return
  90. }
  91. func (rb *RingBuf) WriteAt(p []byte, off int64) (n int, err error) {
  92. if off+int64(len(p)) > rb.end || off < rb.begin {
  93. err = ErrOutOfRange
  94. return
  95. }
  96. var writeOff int
  97. if rb.end-rb.begin < int64(len(rb.data)) {
  98. writeOff = int(off - rb.begin)
  99. } else {
  100. writeOff = rb.index + int(off-rb.begin)
  101. }
  102. if writeOff > len(rb.data) {
  103. writeOff -= len(rb.data)
  104. }
  105. writeEnd := writeOff + int(rb.end-off)
  106. if writeEnd <= len(rb.data) {
  107. n = copy(rb.data[writeOff:writeEnd], p)
  108. } else {
  109. n = copy(rb.data[writeOff:], p)
  110. if n < len(p) {
  111. n += copy(rb.data[:writeEnd-len(rb.data)], p[n:])
  112. }
  113. }
  114. return
  115. }
  116. func (rb *RingBuf) EqualAt(p []byte, off int64) bool {
  117. if off+int64(len(p)) > rb.end || off < rb.begin {
  118. return false
  119. }
  120. var readOff int
  121. if rb.end-rb.begin < int64(len(rb.data)) {
  122. readOff = int(off - rb.begin)
  123. } else {
  124. readOff = rb.index + int(off-rb.begin)
  125. }
  126. if readOff >= len(rb.data) {
  127. readOff -= len(rb.data)
  128. }
  129. readEnd := readOff + len(p)
  130. if readEnd <= len(rb.data) {
  131. return bytes.Equal(p, rb.data[readOff:readEnd])
  132. } else {
  133. firstLen := len(rb.data) - readOff
  134. equal := bytes.Equal(p[:firstLen], rb.data[readOff:])
  135. if equal {
  136. secondLen := len(p) - firstLen
  137. equal = bytes.Equal(p[firstLen:], rb.data[:secondLen])
  138. }
  139. return equal
  140. }
  141. }
  142. // Evacuate read the data at off, then write it to the the data stream,
  143. // Keep it from being overwritten by new data.
  144. func (rb *RingBuf) Evacuate(off int64, length int) (newOff int64) {
  145. if off+int64(length) > rb.end || off < rb.begin {
  146. return -1
  147. }
  148. var readOff int
  149. if rb.end-rb.begin < int64(len(rb.data)) {
  150. readOff = int(off - rb.begin)
  151. } else {
  152. readOff = rb.index + int(off-rb.begin)
  153. }
  154. if readOff >= len(rb.data) {
  155. readOff -= len(rb.data)
  156. }
  157. if readOff == rb.index {
  158. // no copy evacuate
  159. rb.index += length
  160. if rb.index >= len(rb.data) {
  161. rb.index -= len(rb.data)
  162. }
  163. } else if readOff < rb.index {
  164. var n = copy(rb.data[rb.index:], rb.data[readOff:readOff+length])
  165. rb.index += n
  166. if rb.index == len(rb.data) {
  167. rb.index = copy(rb.data, rb.data[readOff+n:readOff+length])
  168. }
  169. } else {
  170. var readEnd = readOff + length
  171. var n int
  172. if readEnd <= len(rb.data) {
  173. n = copy(rb.data[rb.index:], rb.data[readOff:readEnd])
  174. rb.index += n
  175. if rb.index == len(rb.data) {
  176. rb.index = copy(rb.data, rb.data[readOff+n:readEnd])
  177. }
  178. } else {
  179. n = copy(rb.data[rb.index:], rb.data[readOff:])
  180. rb.index += n
  181. var tail = length - n
  182. n = copy(rb.data[rb.index:], rb.data[:tail])
  183. rb.index += n
  184. if rb.index == len(rb.data) {
  185. rb.index = copy(rb.data, rb.data[n:tail])
  186. }
  187. }
  188. }
  189. newOff = rb.end
  190. rb.end += int64(length)
  191. if rb.begin < rb.end-int64(len(rb.data)) {
  192. rb.begin = rb.end - int64(len(rb.data))
  193. }
  194. return
  195. }
  196. func (rb *RingBuf) Resize(newSize int) {
  197. if len(rb.data) == newSize {
  198. return
  199. }
  200. newData := make([]byte, newSize)
  201. var offset int
  202. if rb.end-rb.begin == int64(len(rb.data)) {
  203. offset = rb.index
  204. }
  205. if int(rb.end-rb.begin) > newSize {
  206. discard := int(rb.end-rb.begin) - newSize
  207. offset = (offset + discard) % len(rb.data)
  208. rb.begin = rb.end - int64(newSize)
  209. }
  210. n := copy(newData, rb.data[offset:])
  211. if n < newSize {
  212. copy(newData[n:], rb.data[:offset])
  213. }
  214. rb.data = newData
  215. rb.index = 0
  216. }
  217. func (rb *RingBuf) Skip(length int64) {
  218. rb.end += length
  219. rb.index += int(length)
  220. for rb.index >= len(rb.data) {
  221. rb.index -= len(rb.data)
  222. }
  223. if int(rb.end-rb.begin) > len(rb.data) {
  224. rb.begin = rb.end - int64(len(rb.data))
  225. }
  226. }