1
1
package measurements
2
2
3
3
import (
4
+ "fmt"
5
+ "math"
4
6
"sync"
5
7
)
6
8
9
+ // ExponentialWarmUpFunction describes a warmup function
10
+ type ExponentialWarmUpFunction func (currentValue , newSampleValue float64 ) float64
11
+
7
12
// ExponentialAverageMeasurement is an exponential average measurement implementation.
8
13
type ExponentialAverageMeasurement struct {
9
14
value float64
10
- sum float64
11
15
window int
12
16
warmupWindow int
17
+ warmupFunc ExponentialWarmUpFunction
13
18
count int
14
19
15
20
mu sync.RWMutex
@@ -19,10 +24,18 @@ type ExponentialAverageMeasurement struct {
19
24
func NewExponentialAverageMeasurement (
20
25
window int ,
21
26
warmupWindow int ,
27
+ warmupFunc func (currentValue , newSampleValue float64 ) float64 ,
22
28
) * ExponentialAverageMeasurement {
29
+ if warmupFunc == nil {
30
+ warmupFunc = ExponentialWarmUpFunction (func (currentValue , newSampleValue float64 ) float64 {
31
+ return math .Min (currentValue , newSampleValue )
32
+ })
33
+ }
34
+
23
35
return & ExponentialAverageMeasurement {
24
36
window : window ,
25
37
warmupWindow : warmupWindow ,
38
+ warmupFunc : warmupFunc ,
26
39
}
27
40
}
28
41
@@ -32,12 +45,10 @@ func (m *ExponentialAverageMeasurement) Add(value float64) (float64, bool) {
32
45
defer m .mu .Unlock ()
33
46
if m .count == 0 {
34
47
m .count ++
35
- m .sum = value
36
48
m .value = value
37
49
} else if m .count < m .warmupWindow {
38
50
m .count ++
39
- m .sum += value
40
- m .value = m .sum / float64 (m .count )
51
+ m .value = m .warmupFunc (m .value , value )
41
52
} else {
42
53
f := factor (m .window )
43
54
m .value = m .value * (1 - f ) + value * f
@@ -58,7 +69,6 @@ func (m *ExponentialAverageMeasurement) Reset() {
58
69
defer m .mu .Unlock ()
59
70
m .value = 0
60
71
m .count = 0
61
- m .sum = 0
62
72
}
63
73
64
74
// Update will update the value given an operation function
@@ -71,3 +81,12 @@ func (m *ExponentialAverageMeasurement) Update(operation func(value float64) flo
71
81
func factor (n int ) float64 {
72
82
return 2.0 / float64 (n + 1 )
73
83
}
84
+
85
+ func (m * ExponentialAverageMeasurement ) String () string {
86
+ m .mu .RLock ()
87
+ defer m .mu .RUnlock ()
88
+ return fmt .Sprintf (
89
+ "ExponentialAverageMeasurement{value=%0.5f, count=%d, window=%d, warmupWindow=%d}" ,
90
+ m .value , m .count , m .window , m .warmupWindow ,
91
+ )
92
+ }
0 commit comments