ringbuffer.go 2.1 KB

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