Skip to content

Commit f6d7c84

Browse files
authored
internal/sdkio: add RingBuffer data structure to the sdk (#417)
Adds a RingBuffer data structure. RingBuffer acts as a revolving buffer of a predefined length. It implements io.ReadWriter interface.
1 parent 30c457d commit f6d7c84

File tree

3 files changed

+395
-0
lines changed

3 files changed

+395
-0
lines changed

CHANGELOG_PENDING.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ SDK Features
1717

1818
SDK Enhancements
1919
---
20+
* `internal/sdkio`: Adds RingBuffer data structure to the sdk [#417](https://github.com/aws/aws-sdk-go-v2/pull/417)
21+
* Adds an implementation of RingBuffer data structure which acts as a revolving buffer of a predefined length. The RingBuffer implements io.ReadWriter interface.
22+
* Adds unit tests to test the behavior of the ring buffer.
2023
* `aws/ec2metadata`: Adds support for EC2Metadata client to use secure tokens provided by the IMDS ([#453](https://github.com/aws/aws-sdk-go-v2/pull/453))
2124
* Modifies and adds tests to verify the behavior of the EC2Metadata client.
2225
* `service/dynamodb/dynamodbattribute`: Adds clarifying docs on dynamodbattribute.UnixTime ([#464](https://github.com/aws/aws-sdk-go-v2/pull/464))

internal/sdkio/ringbuffer.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package sdkio
2+
3+
import "io"
4+
5+
// RingBuffer struct satisfies io.ReadWrite interface.
6+
//
7+
// ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a
8+
// revolving window.
9+
type RingBuffer struct {
10+
slice []byte
11+
start int
12+
end int
13+
size int
14+
}
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+
24+
// Write method inserts the elements in a byte slice, and returns the number of bytes written along with an error.
25+
func (r *RingBuffer) Write(p []byte) (int, error) {
26+
for _, b := range p {
27+
// check if end points to invalid index, we need to circle back
28+
if r.end == len(r.slice) {
29+
r.end = 0
30+
}
31+
// check if start points to invalid index, we need to circle back
32+
if r.start == len(r.slice) {
33+
r.start = 0
34+
}
35+
// if ring buffer is filled, increment the start index
36+
if r.size == len(r.slice) {
37+
r.size--
38+
r.start++
39+
}
40+
41+
r.slice[r.end] = b
42+
r.end++
43+
r.size++
44+
}
45+
return r.size, nil
46+
}
47+
48+
// Read copies the data on the ring buffer into the byte slice provided to the method.
49+
// Returns the read count along with Error encountered while reading
50+
func (r *RingBuffer) Read(p []byte) (int, error) {
51+
// readCount keeps track of the number of bytes read
52+
var readCount int
53+
for j := 0; j < len(p); j++ {
54+
// if ring buffer is empty or completely read
55+
// return EOF error.
56+
if r.size == 0 {
57+
return readCount, io.EOF
58+
}
59+
60+
p[j] = r.slice[r.start]
61+
readCount++
62+
// increment the start pointer for ring buffer
63+
r.start++
64+
// decrement the size of ring buffer
65+
r.size--
66+
67+
if r.start == len(r.slice) {
68+
r.start = 0
69+
}
70+
}
71+
return readCount, nil
72+
}

0 commit comments

Comments
 (0)