12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- package io
- import (
- "bytes"
- "io"
- )
- // RingBuffer struct satisfies io.ReadWrite interface.
- //
- // ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a
- // revolving window.
- type RingBuffer struct {
- slice []byte
- start int
- end int
- size int
- }
- // NewRingBuffer method takes in a byte slice as an input and returns a RingBuffer.
- func NewRingBuffer(slice []byte) *RingBuffer {
- ringBuf := RingBuffer{
- slice: slice,
- }
- return &ringBuf
- }
- // Write method inserts the elements in a byte slice, and returns the number of bytes written along with any error.
- func (r *RingBuffer) Write(p []byte) (int, error) {
- for _, b := range p {
- // check if end points to invalid index, we need to circle back
- if r.end == len(r.slice) {
- r.end = 0
- }
- // check if start points to invalid index, we need to circle back
- if r.start == len(r.slice) {
- r.start = 0
- }
- // if ring buffer is filled, increment the start index
- if r.size == len(r.slice) {
- r.size--
- r.start++
- }
- r.slice[r.end] = b
- r.end++
- r.size++
- }
- return len(p), nil
- }
- // Read copies the data on the ring buffer into the byte slice provided to the method.
- // Returns the read count along with any error encountered while reading.
- func (r *RingBuffer) Read(p []byte) (int, error) {
- // readCount keeps track of the number of bytes read
- var readCount int
- for j := 0; j < len(p); j++ {
- // if ring buffer is empty or completely read
- // return EOF error.
- if r.size == 0 {
- return readCount, io.EOF
- }
- if r.start == len(r.slice) {
- r.start = 0
- }
- p[j] = r.slice[r.start]
- readCount++
- // increment the start pointer for ring buffer
- r.start++
- // decrement the size of ring buffer
- r.size--
- }
- return readCount, nil
- }
- // Len returns the number of unread bytes in the buffer.
- func (r *RingBuffer) Len() int {
- return r.size
- }
- // Bytes returns a copy of the RingBuffer's bytes.
- func (r RingBuffer) Bytes() []byte {
- var b bytes.Buffer
- io.Copy(&b, &r)
- return b.Bytes()
- }
- // Reset resets the ring buffer.
- func (r *RingBuffer) Reset() {
- *r = RingBuffer{
- slice: r.slice,
- }
- }
|