github.com/QuangTung97/bigcache@v0.1.0/ringbuf.go (about) 1 package bigcache 2 3 import ( 4 "bytes" 5 ) 6 7 type ringBuf struct { 8 begin int 9 size int 10 data []byte 11 } 12 13 func newRingBuf(size int) ringBuf { 14 return ringBuf{ 15 begin: 0, 16 size: 0, 17 data: make([]byte, size), 18 } 19 } 20 21 func (r *ringBuf) append(data []byte) int { 22 n := len(data) 23 max := len(r.data) 24 end := r.getEnd() 25 copy(r.data[end:], data) 26 if end+n > max { 27 firstPart := max - end 28 copy(r.data, data[firstPart:]) 29 } 30 r.size += n 31 return end 32 } 33 34 func (r *ringBuf) appendEmpty(n int) { 35 r.size += n 36 } 37 38 func (r *ringBuf) readAt(data []byte, offset int) { 39 offset = offset % len(r.data) 40 41 n := len(data) 42 max := len(r.data) 43 copy(data, r.data[offset:]) 44 if offset+n > max { 45 firstPart := max - offset 46 copy(data[firstPart:], r.data) 47 } 48 } 49 50 func (r *ringBuf) writeAt(data []byte, offset int) { 51 offset = offset % len(r.data) 52 53 n := len(data) 54 max := len(r.data) 55 copy(r.data[offset:], data) 56 if offset+n > max { 57 firstPart := max - offset 58 secondPart := n - firstPart 59 copy(r.data[:secondPart], data[firstPart:]) 60 } 61 } 62 63 func (r *ringBuf) getBegin() int { 64 return r.begin 65 } 66 67 func (r *ringBuf) getEnd() int { 68 return (r.begin + r.size) % len(r.data) 69 } 70 71 func (r *ringBuf) getAvailable() int { 72 return len(r.data) - r.size 73 } 74 75 func (r *ringBuf) increaseBegin(n int) { 76 r.begin = (r.begin + n) % len(r.data) 77 } 78 79 func (r *ringBuf) skip(n int) { 80 r.increaseBegin(n) 81 r.size -= n 82 } 83 84 func (r *ringBuf) bytesEqual(from int, data []byte) bool { 85 from = from % len(r.data) 86 87 n := len(data) 88 toOffset := from + n 89 max := len(r.data) 90 if toOffset > max { 91 firstPart := max - from 92 secondPart := n - firstPart 93 if !bytes.Equal(r.data[from:], data[:firstPart]) { 94 return false 95 } 96 return bytes.Equal(r.data[:secondPart], data[firstPart:]) 97 } 98 return bytes.Equal(r.data[from:toOffset], data) 99 } 100 101 func (r *ringBuf) evacuateContinuousSource(from int, end int, size int) { 102 max := len(r.data) 103 104 if end+size > max { 105 firstPart := max - end 106 secondPart := size - firstPart 107 copy(r.data[end:], r.data[from:]) 108 copy(r.data[:secondPart], r.data[from+firstPart:]) 109 } else { 110 copy(r.data[end:end+size], r.data[from:]) 111 } 112 } 113 114 func (r *ringBuf) evacuate(size int) int { 115 begin := r.getBegin() 116 end := r.getEnd() 117 max := len(r.data) 118 119 if begin+size > max { 120 firstPart := max - begin 121 secondPart := size - firstPart 122 r.evacuateContinuousSource(begin, end, firstPart) 123 r.evacuateContinuousSource(0, end+firstPart, secondPart) 124 } else { 125 r.evacuateContinuousSource(begin, end, size) 126 } 127 128 r.increaseBegin(size) 129 return end 130 }