github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/metrics/ewma.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 12:09:41</date>
    10  //</624342648152395776>
    11  
    12  package metrics
    13  
    14  import (
    15  	"math"
    16  	"sync"
    17  	"sync/atomic"
    18  )
    19  
    20  //EWMA连续计算指数加权移动平均值
    21  //基于外部时钟信号源。
    22  type EWMA interface {
    23  	Rate() float64
    24  	Snapshot() EWMA
    25  	Tick()
    26  	Update(int64)
    27  }
    28  
    29  //new ewma用给定的alpha构造一个新的ewma。
    30  func NewEWMA(alpha float64) EWMA {
    31  	if !Enabled {
    32  		return NilEWMA{}
    33  	}
    34  	return &StandardEWMA{alpha: alpha}
    35  }
    36  
    37  //newewma1构建一个新的ewma,移动平均值为一分钟。
    38  func NewEWMA1() EWMA {
    39  	return NewEWMA(1 - math.Exp(-5.0/60.0/1))
    40  }
    41  
    42  //newewma5构建一个新的ewma,平均移动5分钟。
    43  func NewEWMA5() EWMA {
    44  	return NewEWMA(1 - math.Exp(-5.0/60.0/5))
    45  }
    46  
    47  //newewma15构建一个新的ewma,平均移动15分钟。
    48  func NewEWMA15() EWMA {
    49  	return NewEWMA(1 - math.Exp(-5.0/60.0/15))
    50  }
    51  
    52  //ewmasnapshot是另一个ewma的只读副本。
    53  type EWMASnapshot float64
    54  
    55  //Rate返回快照时每秒事件的速率
    56  //拿。
    57  func (a EWMASnapshot) Rate() float64 { return float64(a) }
    58  
    59  //快照返回快照。
    60  func (a EWMASnapshot) Snapshot() EWMA { return a }
    61  
    62  //蜱恐慌。
    63  func (EWMASnapshot) Tick() {
    64  	panic("Tick called on an EWMASnapshot")
    65  }
    66  
    67  //更新恐慌。
    68  func (EWMASnapshot) Update(int64) {
    69  	panic("Update called on an EWMASnapshot")
    70  }
    71  
    72  //尼罗河流域是一个绝无仅有的EWMA。
    73  type NilEWMA struct{}
    74  
    75  //价格是不允许的。
    76  func (NilEWMA) Rate() float64 { return 0.0 }
    77  
    78  //快照是不可操作的。
    79  func (NilEWMA) Snapshot() EWMA { return NilEWMA{} }
    80  
    81  //滴答声是禁止的。
    82  func (NilEWMA) Tick() {}
    83  
    84  //更新是不可操作的。
    85  func (NilEWMA) Update(n int64) {}
    86  
    87  //StandardEWMA是EWMA的标准实现并跟踪
    88  //对未计数的事件进行处理。它使用
    89  //同步/原子包以管理未计数的事件。
    90  type StandardEWMA struct {
    91  uncounted int64 //!\这应该是确保64位对齐的第一个成员
    92  	alpha     float64
    93  	rate      float64
    94  	init      bool
    95  	mutex     sync.Mutex
    96  }
    97  
    98  //Rate返回每秒事件的移动平均速率。
    99  func (a *StandardEWMA) Rate() float64 {
   100  	a.mutex.Lock()
   101  	defer a.mutex.Unlock()
   102  	return a.rate * float64(1e9)
   103  }
   104  
   105  //快照返回EWMA的只读副本。
   106  func (a *StandardEWMA) Snapshot() EWMA {
   107  	return EWMASnapshot(a.Rate())
   108  }
   109  
   110  //勾选时钟以更新移动平均值。它假定它被调用
   111  //每五秒钟。
   112  func (a *StandardEWMA) Tick() {
   113  	count := atomic.LoadInt64(&a.uncounted)
   114  	atomic.AddInt64(&a.uncounted, -count)
   115  	instantRate := float64(count) / float64(5e9)
   116  	a.mutex.Lock()
   117  	defer a.mutex.Unlock()
   118  	if a.init {
   119  		a.rate += a.alpha * (instantRate - a.rate)
   120  	} else {
   121  		a.init = true
   122  		a.rate = instantRate
   123  	}
   124  }
   125  
   126  //更新添加了n个未计数的事件。
   127  func (a *StandardEWMA) Update(n int64) {
   128  	atomic.AddInt64(&a.uncounted, n)
   129  }
   130