-
Notifications
You must be signed in to change notification settings - Fork 1
/
window.go
80 lines (67 loc) · 1.7 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
package scaling
import (
"math"
"time"
"k8s.io/apimachinery/pkg/util/clock"
)
type windowValues struct {
// Start is the time at which we started this window
Start time.Time
// Retention determines for how long we will retain values (though we always retain the latest)
Retention time.Duration
// values records all values we have recorded. Values older than Window will be removed (lazily)
values []windowValue
}
type windowValue struct {
t time.Time
value float64
}
func (w *windowValues) Reset(clock clock.Clock, retention time.Duration) {
w.Start = clock.Now()
w.Retention = retention
w.values = nil
}
func (w *windowValues) addObservation(now time.Time, value float64) {
var filtered []windowValue
// We always record the latest value, regardless of retention
filtered = append(filtered, windowValue{t: now, value: value})
for _, o := range w.values {
if now.Sub(o.t) <= w.Retention {
filtered = append(filtered, o)
}
}
w.values = filtered
}
type windowStats struct {
N int
Min float64
Max float64
LatestValue float64
HasLatest bool
LatestTimestamp time.Time
}
func (w *windowValues) stats(now time.Time, window time.Duration) windowStats {
var stats windowStats
stats.Min = math.MaxFloat64
stats.Max = -math.MaxFloat64
stats.N = 0
for _, v := range w.values {
// We always return the latest value, if we have one
if stats.LatestTimestamp.IsZero() || stats.LatestTimestamp.After(v.t) {
stats.LatestTimestamp = v.t
stats.LatestValue = v.value
stats.HasLatest = true
}
if now.Sub(v.t) > window {
continue
}
if v.value < stats.Min {
stats.Min = v.value
}
if v.value > stats.Max {
stats.Max = v.value
}
stats.N++
}
return stats
}