github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/net/ringbuffer/ring_buffer.go (about) 1 package ringbuffer 2 3 import ( 4 "errors" 5 "unsafe" 6 7 "github.com/angenalZZZ/gofunc/net/internal" 8 "github.com/angenalZZZ/gofunc/net/pool/bytebuffer" 9 ) 10 11 const initSize = 1 << 12 // 4096 bytes for the first-time allocation on ring-buffer. 12 13 // ErrIsEmpty will be returned when trying to read a empty ring-buffer. 14 var ErrIsEmpty = errors.New("ring-buffer is empty") 15 16 // RingBuffer is a circular buffer that implement io.ReaderWriter interface. 17 type RingBuffer struct { 18 buf []byte 19 size int 20 mask int 21 r int // next position to read 22 w int // next position to write 23 isEmpty bool 24 } 25 26 // New returns a new RingBuffer whose buffer has the given size. 27 func New(size int) *RingBuffer { 28 if size == 0 { 29 return &RingBuffer{isEmpty: true} 30 } 31 size = internal.CeilToPowerOfTwo(size) 32 return &RingBuffer{ 33 buf: make([]byte, size), 34 size: size, 35 mask: size - 1, 36 isEmpty: true, 37 } 38 } 39 40 // LazyRead reads the bytes with given length but will not move the pointer of "read". 41 func (r *RingBuffer) LazyRead(len int) (head []byte, tail []byte) { 42 if r.isEmpty { 43 return 44 } 45 46 if len <= 0 { 47 return 48 } 49 50 if r.w > r.r { 51 n := r.w - r.r // Length 52 if n > len { 53 n = len 54 } 55 head = r.buf[r.r : r.r+n] 56 return 57 } 58 59 n := r.size - r.r + r.w // Length 60 if n > len { 61 n = len 62 } 63 64 if r.r+n <= r.size { 65 head = r.buf[r.r : r.r+n] 66 } else { 67 c1 := r.size - r.r 68 head = r.buf[r.r:] 69 c2 := n - c1 70 tail = r.buf[:c2] 71 } 72 73 return 74 } 75 76 // LazyReadAll reads the all bytes in this ring-buffer but will not move the pointer of "read". 77 func (r *RingBuffer) LazyReadAll() (head []byte, tail []byte) { 78 if r.isEmpty { 79 return 80 } 81 82 if r.w > r.r { 83 head = r.buf[r.r:r.w] 84 return 85 } 86 87 head = r.buf[r.r:] 88 if r.w != 0 { 89 tail = r.buf[:r.w] 90 } 91 92 return 93 } 94 95 // Shift shifts the "read" pointer. 96 func (r *RingBuffer) Shift(n int) { 97 if n <= 0 { 98 return 99 } 100 101 if n < r.Length() { 102 r.r = (r.r + n) & r.mask 103 if r.r == r.w { 104 r.isEmpty = true 105 } 106 } else { 107 r.Reset() 108 } 109 } 110 111 // Read reads up to len(p) bytes into p. It returns the number of bytes read (0 <= n <= len(p)) and any error 112 // encountered. 113 // Even if Read returns n < len(p), it may use all of p as scratch space during the call. 114 // If some data is available but not len(p) bytes, Read conventionally returns what is available instead of waiting 115 // for more. 116 // When Read encounters an error or end-of-file condition after successfully reading n > 0 bytes, 117 // it returns the number of bytes read. It may return the (non-nil) error from the same call or return the 118 // error (and n == 0) from a subsequent call. 119 // Callers should always process the n > 0 bytes returned before considering the error err. 120 // Doing so correctly handles I/O errors that happen after reading some bytes and also both of the allowed EOF 121 // behaviors. 122 func (r *RingBuffer) Read(p []byte) (n int, err error) { 123 if len(p) == 0 { 124 return 0, nil 125 } 126 127 if r.isEmpty { 128 return 0, ErrIsEmpty 129 } 130 131 if r.w > r.r { 132 n = r.w - r.r 133 if n > len(p) { 134 n = len(p) 135 } 136 copy(p, r.buf[r.r:r.r+n]) 137 r.r = r.r + n 138 if r.r == r.w { 139 r.isEmpty = true 140 } 141 return 142 } 143 144 n = r.size - r.r + r.w 145 if n > len(p) { 146 n = len(p) 147 } 148 149 if r.r+n <= r.size { 150 copy(p, r.buf[r.r:r.r+n]) 151 } else { 152 c1 := r.size - r.r 153 copy(p, r.buf[r.r:]) 154 c2 := n - c1 155 copy(p[c1:], r.buf[:c2]) 156 } 157 r.r = (r.r + n) & r.mask 158 if r.r == r.w { 159 r.isEmpty = true 160 } 161 162 return n, err 163 } 164 165 // ReadByte reads and returns the next byte from the input or ErrIsEmpty. 166 func (r *RingBuffer) ReadByte() (b byte, err error) { 167 if r.isEmpty { 168 return 0, ErrIsEmpty 169 } 170 b = r.buf[r.r] 171 r.r++ 172 if r.r == r.size { 173 r.r = 0 174 } 175 if r.r == r.w { 176 r.isEmpty = true 177 } 178 179 return b, err 180 } 181 182 // Write writes len(p) bytes from p to the underlying buf. 183 // It returns the number of bytes written from p (n == len(p) > 0) and any error encountered that caused the write to 184 // stop early. 185 // If the length of p is greater than the writable capacity of this ring-buffer, it will allocate more memory to 186 // this ring-buffer. 187 // Write must not modify the slice data, even temporarily. 188 func (r *RingBuffer) Write(p []byte) (n int, err error) { 189 n = len(p) 190 if n == 0 { 191 return 0, nil 192 } 193 194 free := r.Free() 195 if n > free { 196 r.malloc(n - free) 197 } 198 199 if r.w >= r.r { 200 c1 := r.size - r.w 201 if c1 >= n { 202 copy(r.buf[r.w:], p) 203 r.w += n 204 } else { 205 copy(r.buf[r.w:], p[:c1]) 206 c2 := n - c1 207 copy(r.buf, p[c1:]) 208 r.w = c2 209 } 210 } else { 211 copy(r.buf[r.w:], p) 212 r.w += n 213 } 214 215 if r.w == r.size { 216 r.w = 0 217 } 218 219 r.isEmpty = false 220 221 return n, err 222 } 223 224 // WriteByte writes one byte into buffer 225 func (r *RingBuffer) WriteByte(c byte) error { 226 if r.Free() < 1 { 227 r.malloc(1) 228 } 229 r.buf[r.w] = c 230 r.w++ 231 232 if r.w == r.size { 233 r.w = 0 234 } 235 r.isEmpty = false 236 237 return nil 238 } 239 240 // Length returns the length of available read bytes. 241 func (r *RingBuffer) Length() int { 242 if r.r == r.w { 243 if r.isEmpty { 244 return 0 245 } 246 return r.size 247 } 248 249 if r.w > r.r { 250 return r.w - r.r 251 } 252 253 return r.size - r.r + r.w 254 } 255 256 // Len returns the length of the underlying buffer. 257 func (r *RingBuffer) Len() int { 258 return len(r.buf) 259 } 260 261 // Cap returns the size of the underlying buffer. 262 func (r *RingBuffer) Cap() int { 263 return r.size 264 } 265 266 // Free returns the length of available bytes to write. 267 func (r *RingBuffer) Free() int { 268 if r.r == r.w { 269 if r.isEmpty { 270 return r.size 271 } 272 return 0 273 } 274 275 if r.w < r.r { 276 return r.r - r.w 277 } 278 279 return r.size - r.w + r.r 280 } 281 282 // WriteString writes the contents of the string s to buffer, which accepts a slice of bytes. 283 func (r *RingBuffer) WriteString(s string) (n int, err error) { 284 x := (*[2]uintptr)(unsafe.Pointer(&s)) 285 h := [3]uintptr{x[0], x[1], x[1]} 286 buf := *(*[]byte)(unsafe.Pointer(&h)) 287 return r.Write(buf) 288 } 289 290 // ByteBuffer returns all available read bytes. It does not move the read pointer and only copy the available data. 291 func (r *RingBuffer) ByteBuffer() *bytebuffer.ByteBuffer { 292 if r.isEmpty { 293 return nil 294 } else if r.w == r.r { 295 bb := bytebuffer.Get() 296 _, _ = bb.Write(r.buf[r.r:]) 297 _, _ = bb.Write(r.buf[:r.w]) 298 return bb 299 } 300 301 bb := bytebuffer.Get() 302 if r.w > r.r { 303 _, _ = bb.Write(r.buf[r.r:r.w]) 304 return bb 305 } 306 307 _, _ = bb.Write(r.buf[r.r:]) 308 309 if r.w != 0 { 310 _, _ = bb.Write(r.buf[:r.w]) 311 } 312 313 return bb 314 } 315 316 // WithByteBuffer combines the available read bytes and the given bytes. It does not move the read pointer and 317 // only copy the available data. 318 func (r *RingBuffer) WithByteBuffer(b []byte) *bytebuffer.ByteBuffer { 319 if r.isEmpty { 320 return &bytebuffer.ByteBuffer{B: b} 321 } else if r.w == r.r { 322 bb := bytebuffer.Get() 323 _, _ = bb.Write(r.buf[r.r:]) 324 _, _ = bb.Write(r.buf[:r.w]) 325 _, _ = bb.Write(b) 326 return bb 327 } 328 329 bb := bytebuffer.Get() 330 if r.w > r.r { 331 _, _ = bb.Write(r.buf[r.r:r.w]) 332 _, _ = bb.Write(b) 333 return bb 334 } 335 336 _, _ = bb.Write(r.buf[r.r:]) 337 338 if r.w != 0 { 339 _, _ = bb.Write(r.buf[:r.w]) 340 } 341 _, _ = bb.Write(b) 342 343 return bb 344 } 345 346 // IsFull returns this ringbuffer is full. 347 func (r *RingBuffer) IsFull() bool { 348 return r.r == r.w && !r.isEmpty 349 } 350 351 // IsEmpty returns this ringbuffer is empty. 352 func (r *RingBuffer) IsEmpty() bool { 353 return r.isEmpty 354 } 355 356 // Reset the read pointer and writer pointer to zero. 357 func (r *RingBuffer) Reset() { 358 r.r = 0 359 r.w = 0 360 r.isEmpty = true 361 } 362 363 func (r *RingBuffer) malloc(cap int) { 364 var newCap int 365 if r.size == 0 && initSize >= cap { 366 newCap = initSize 367 } else { 368 newCap = internal.CeilToPowerOfTwo(r.size + cap) 369 } 370 newBuf := make([]byte, newCap) 371 oldLen := r.Length() 372 _, _ = r.Read(newBuf) 373 r.r = 0 374 r.w = oldLen 375 r.size = newCap 376 r.mask = newCap - 1 377 r.buf = newBuf 378 }