...

Source file src/github.com/aws/smithy-go/io/ringbuffer.go

Documentation: github.com/aws/smithy-go/io

     1  package io
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  )
     7  
     8  // RingBuffer struct satisfies io.ReadWrite interface.
     9  //
    10  // ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a
    11  // revolving window.
    12  type RingBuffer struct {
    13  	slice []byte
    14  	start int
    15  	end   int
    16  	size  int
    17  }
    18  
    19  // NewRingBuffer method takes in a byte slice as an input and returns a RingBuffer.
    20  func NewRingBuffer(slice []byte) *RingBuffer {
    21  	ringBuf := RingBuffer{
    22  		slice: slice,
    23  	}
    24  	return &ringBuf
    25  }
    26  
    27  // Write method inserts the elements in a byte slice, and returns the number of bytes written along with any error.
    28  func (r *RingBuffer) Write(p []byte) (int, error) {
    29  	for _, b := range p {
    30  		// check if end points to invalid index, we need to circle back
    31  		if r.end == len(r.slice) {
    32  			r.end = 0
    33  		}
    34  		// check if start points to invalid index, we need to circle back
    35  		if r.start == len(r.slice) {
    36  			r.start = 0
    37  		}
    38  		// if ring buffer is filled, increment the start index
    39  		if r.size == len(r.slice) {
    40  			r.size--
    41  			r.start++
    42  		}
    43  
    44  		r.slice[r.end] = b
    45  		r.end++
    46  		r.size++
    47  	}
    48  	return len(p), nil
    49  }
    50  
    51  // Read copies the data on the ring buffer into the byte slice provided to the method.
    52  // Returns the read count along with any error encountered while reading.
    53  func (r *RingBuffer) Read(p []byte) (int, error) {
    54  	// readCount keeps track of the number of bytes read
    55  	var readCount int
    56  	for j := 0; j < len(p); j++ {
    57  		// if ring buffer is empty or completely read
    58  		// return EOF error.
    59  		if r.size == 0 {
    60  			return readCount, io.EOF
    61  		}
    62  
    63  		if r.start == len(r.slice) {
    64  			r.start = 0
    65  		}
    66  
    67  		p[j] = r.slice[r.start]
    68  		readCount++
    69  		// increment the start pointer for ring buffer
    70  		r.start++
    71  		// decrement the size of ring buffer
    72  		r.size--
    73  	}
    74  	return readCount, nil
    75  }
    76  
    77  // Len returns the number of unread bytes in the buffer.
    78  func (r *RingBuffer) Len() int {
    79  	return r.size
    80  }
    81  
    82  // Bytes returns a copy of the RingBuffer's bytes.
    83  func (r RingBuffer) Bytes() []byte {
    84  	var b bytes.Buffer
    85  	io.Copy(&b, &r)
    86  	return b.Bytes()
    87  }
    88  
    89  // Reset resets the ring buffer.
    90  func (r *RingBuffer) Reset() {
    91  	*r = RingBuffer{
    92  		slice: r.slice,
    93  	}
    94  }
    95  

View as plain text