-
Notifications
You must be signed in to change notification settings - Fork 0
/
window.go
107 lines (91 loc) · 2.39 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package rolling
// Bucket contains multiple float64 points.
type Bucket struct {
Points []float64
Count int64
next *Bucket
}
// Append appends the given value to the bucket.
func (b *Bucket) Append(val float64) {
b.Points = append(b.Points, val)
b.Count++
}
// Add adds the given value to the point.
func (b *Bucket) Add(offset int, val float64) {
b.Points[offset] += val
b.Count++
}
// Reset empties the bucket.
func (b *Bucket) Reset() {
b.Points = b.Points[:0]
b.Count = 0
}
// Next returns the next bucket.
func (b *Bucket) Next() *Bucket {
return b.next
}
// Window contains multiple buckets.
type Window struct {
window []Bucket
size int
}
// WindowOpts contains the arguments for creating Window.
type WindowOpts struct {
Size int
}
// NewWindow creates a new Window based on WindowOpts.
func NewWindow(opts WindowOpts) *Window {
buckets := make([]Bucket, opts.Size)
for offset := range buckets {
buckets[offset] = Bucket{Points: make([]float64, 0)}
nextOffset := offset + 1
if nextOffset == opts.Size {
nextOffset = 0
}
buckets[offset].next = &buckets[nextOffset]
}
return &Window{window: buckets, size: opts.Size}
}
// ResetWindow empties all buckets within the window.
func (w *Window) ResetWindow() {
for offset := range w.window {
w.ResetBucket(offset)
}
}
// ResetBucket empties the bucket based on the given offset.
func (w *Window) ResetBucket(offset int) {
w.window[offset].Reset()
}
// ResetBuckets empties the buckets based on the given offsets.
func (w *Window) ResetBuckets(offsets []int) {
for _, offset := range offsets {
w.ResetBucket(offset)
}
}
// Append appends the given value to the bucket where index equals the given offset.
func (w *Window) Append(offset int, val float64) {
w.window[offset].Append(val)
}
// Add adds the given value to the latest point within bucket where index equals the given offset.
func (w *Window) Add(offset int, val float64) {
if w.window[offset].Count == 0 {
w.window[offset].Append(val)
return
}
w.window[offset].Add(0, val)
}
// Bucket returns the bucket where index equals the given offset.
func (w *Window) Bucket(offset int) Bucket {
return w.window[offset]
}
// Size returns the size of the window.
func (w *Window) Size() int {
return w.size
}
// Iterator returns the bucket iterator.
func (w *Window) Iterator(offset int, count int) Iterator {
return Iterator{
count: count,
cur: &w.window[offset],
}
}