1 package ring
2 3 type BufferFloat64 struct {
4 Buf []float64
5 Cursor int
6 Full bool
7 }
8 9 // NewBufferFloat64 creates a new ring buffer of float64 values
10 func NewBufferFloat64(size int) *BufferFloat64 {
11 return &BufferFloat64{
12 Buf: make([]float64, size),
13 Cursor: -1,
14 }
15 }
16 17 // Get returns the value at the given index or nil if nothing
18 func (b *BufferFloat64) Get(index int) (out *float64) {
19 bl := len(b.Buf)
20 if index < bl {
21 cursor := b.Cursor + index
22 if cursor > bl {
23 cursor = cursor - bl
24 }
25 return &b.Buf[cursor]
26 }
27 return
28 }
29 30 // Len returns the length of the buffer, which grows until it fills, after which
31 // this will always return the size of the buffer
32 func (b *BufferFloat64) Len() (length int) {
33 if b.Full {
34 return len(b.Buf)
35 }
36 return b.Cursor
37 }
38 39 // Add a new value to the cursor position of the ring buffer
40 func (b *BufferFloat64) Add(value float64) {
41 b.Cursor++
42 if b.Cursor == len(b.Buf) {
43 b.Cursor = 0
44 if !b.Full {
45 b.Full = true
46 }
47 }
48 b.Buf[b.Cursor] = value
49 }
50 51 // ForEach is an iterator that can be used to process every element in the
52 // buffer
53 func (b *BufferFloat64) ForEach(fn func(v float64) error) (e error) {
54 c := b.Cursor
55 i := c + 1
56 if i == len(b.Buf) {
57 // D.Ln("hit the end")
58 i = 0
59 }
60 if !b.Full {
61 // D.Ln("buffer not yet full")
62 i = 0
63 }
64 // D.Ln(b.Buf)
65 for ; ; i++ {
66 if i == len(b.Buf) {
67 // D.Ln("passed the end")
68 i = 0
69 }
70 if i == c {
71 // D.Ln("reached cursor again")
72 break
73 }
74 // D.Ln(i, b.Cursor)
75 if e = fn(b.Buf[i]); e != nil {
76 break
77 }
78 }
79 return
80 }
81