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