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