github.com/aergoio/aergo@v1.3.1/p2p/metric/exponentmetric.go (about) 1 /* 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 6 package metric 7 8 import ( 9 "github.com/aergoio/aergo/p2p/p2putil" 10 "math" 11 "sync/atomic" 12 ) 13 14 // this struct calculate roughly approximate mean value. 15 type exponentMetric struct { 16 unCalc int64 17 averageFactor int64 18 19 subtotal int64 20 average int64 21 inqueue *p2putil.PressableQueue 22 23 decayFactor float64 24 loadScore int64 25 } 26 27 28 func NewExponentMetric5(tickInterval int) DataMetric { 29 return NewExponentMetric(tickInterval, 60*5) 30 } 31 32 // NewExponentMetric15 33 func NewExponentMetric15(tickInterval int) DataMetric { 34 return NewExponentMetric(tickInterval, 15 * 60) 35 } 36 37 func NewExponentMetric(interval int, meanTime int) *exponentMetric { 38 decayFactor := math.Exp(-float64(interval)/float64(meanTime)) 39 // rounded int value 40 avr := (meanTime + interval>>1 ) / interval 41 return &exponentMetric{averageFactor: int64(avr), inqueue:p2putil.NewPressableQueue(avr), decayFactor: decayFactor} 42 } 43 44 func (a *exponentMetric) APS() int64 { 45 return atomic.LoadInt64(&a.average) 46 } 47 48 func (a *exponentMetric) LoadScore() int64 { 49 return atomic.LoadInt64(&a.loadScore) 50 } 51 52 // Update adds n unCalc events. 53 func (a *exponentMetric) AddBytes(n int) { 54 atomic.AddInt64(&a.unCalc, int64(n)) 55 } 56 57 func (a *exponentMetric) Calculate() { 58 count := atomic.LoadInt64(&a.unCalc) 59 atomic.AddInt64(&a.unCalc, -count) 60 a.subtotal += count 61 out := a.inqueue.Press(count) 62 if out != nil { 63 a.subtotal -= out.(int64) 64 } 65 atomic.StoreInt64(&a.average, a.subtotal / int64(a.inqueue.Size()) ) 66 67 atomic.StoreInt64(&a.loadScore, count + int64(float64(a.loadScore) * a.decayFactor) ) 68 } 69