github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:39</date>
    10  //</624450098297835520>
    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  	return &StandardEWMA{alpha: alpha}
    32  }
    33  
    34  //newewma1构建一个新的ewma,移动平均值为一分钟。
    35  func NewEWMA1() EWMA {
    36  	return NewEWMA(1 - math.Exp(-5.0/60.0/1))
    37  }
    38  
    39  //newewma5构建一个新的ewma,平均移动5分钟。
    40  func NewEWMA5() EWMA {
    41  	return NewEWMA(1 - math.Exp(-5.0/60.0/5))
    42  }
    43  
    44  //newewma15构建一个新的ewma,平均移动15分钟。
    45  func NewEWMA15() EWMA {
    46  	return NewEWMA(1 - math.Exp(-5.0/60.0/15))
    47  }
    48  
    49  //ewmasnapshot是另一个ewma的只读副本。
    50  type EWMASnapshot float64
    51  
    52  //Rate返回快照时每秒事件的速率
    53  //拿。
    54  func (a EWMASnapshot) Rate() float64 { return float64(a) }
    55  
    56  //快照返回快照。
    57  func (a EWMASnapshot) Snapshot() EWMA { return a }
    58  
    59  //蜱恐慌。
    60  func (EWMASnapshot) Tick() {
    61  	panic("Tick called on an EWMASnapshot")
    62  }
    63  
    64  //更新恐慌。
    65  func (EWMASnapshot) Update(int64) {
    66  	panic("Update called on an EWMASnapshot")
    67  }
    68  
    69  //尼罗河流域是一个绝无仅有的EWMA。
    70  type NilEWMA struct{}
    71  
    72  //价格是不允许的。
    73  func (NilEWMA) Rate() float64 { return 0.0 }
    74  
    75  //快照是不可操作的。
    76  func (NilEWMA) Snapshot() EWMA { return NilEWMA{} }
    77  
    78  //滴答声是禁止的。
    79  func (NilEWMA) Tick() {}
    80  
    81  //更新是不可操作的。
    82  func (NilEWMA) Update(n int64) {}
    83  
    84  //StandardEWMA是EWMA的标准实现并跟踪
    85  //对未计数的事件进行处理。它使用
    86  //同步/原子包以管理未计数的事件。
    87  type StandardEWMA struct {
    88  uncounted int64 //!\这应该是确保64位对齐的第一个成员
    89  	alpha     float64
    90  	rate      float64
    91  	init      bool
    92  	mutex     sync.Mutex
    93  }
    94  
    95  //Rate返回每秒事件的移动平均速率。
    96  func (a *StandardEWMA) Rate() float64 {
    97  	a.mutex.Lock()
    98  	defer a.mutex.Unlock()
    99  	return a.rate * float64(1e9)
   100  }
   101  
   102  //快照返回EWMA的只读副本。
   103  func (a *StandardEWMA) Snapshot() EWMA {
   104  	return EWMASnapshot(a.Rate())
   105  }
   106  
   107  //勾选时钟以更新移动平均值。它假定它被调用
   108  //每五秒钟。
   109  func (a *StandardEWMA) Tick() {
   110  	count := atomic.LoadInt64(&a.uncounted)
   111  	atomic.AddInt64(&a.uncounted, -count)
   112  	instantRate := float64(count) / float64(5e9)
   113  	a.mutex.Lock()
   114  	defer a.mutex.Unlock()
   115  	if a.init {
   116  		a.rate += a.alpha * (instantRate - a.rate)
   117  	} else {
   118  		a.init = true
   119  		a.rate = instantRate
   120  	}
   121  }
   122  
   123  //更新添加了n个未计数的事件。
   124  func (a *StandardEWMA) Update(n int64) {
   125  	atomic.AddInt64(&a.uncounted, n)
   126  }
   127