forked from aergoio/aergo
/
exponentmetric.go
69 lines (54 loc) · 1.56 KB
/
exponentmetric.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
/*
* @file
* @copyright defined in aergo/LICENSE.txt
*/
package metric
import (
"github.com/aergoio/aergo/p2p/p2putil"
"math"
"sync/atomic"
)
// this struct calculate roughly approximate mean value.
type exponentMetric struct {
unCalc int64
averageFactor int64
subtotal int64
average int64
inqueue *p2putil.PressableQueue
decayFactor float64
loadScore int64
}
func NewExponentMetric5(tickInterval int) DataMetric {
return NewExponentMetric(tickInterval, 60*5)
}
// NewExponentMetric15
func NewExponentMetric15(tickInterval int) DataMetric {
return NewExponentMetric(tickInterval, 15 * 60)
}
func NewExponentMetric(interval int, meanTime int) *exponentMetric {
decayFactor := math.Exp(-float64(interval)/float64(meanTime))
// rounded int value
avr := (meanTime + interval>>1 ) / interval
return &exponentMetric{averageFactor: int64(avr), inqueue:p2putil.NewPressableQueue(avr), decayFactor: decayFactor}
}
func (a *exponentMetric) APS() int64 {
return atomic.LoadInt64(&a.average)
}
func (a *exponentMetric) LoadScore() int64 {
return atomic.LoadInt64(&a.loadScore)
}
// Update adds n unCalc events.
func (a *exponentMetric) AddBytes(n int) {
atomic.AddInt64(&a.unCalc, int64(n))
}
func (a *exponentMetric) Calculate() {
count := atomic.LoadInt64(&a.unCalc)
atomic.AddInt64(&a.unCalc, -count)
a.subtotal += count
out := a.inqueue.Press(count)
if out != nil {
a.subtotal -= out.(int64)
}
atomic.StoreInt64(&a.average, a.subtotal / int64(a.inqueue.Size()) )
atomic.StoreInt64(&a.loadScore, count + int64(float64(a.loadScore) * a.decayFactor) )
}