github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/metrics/resetting_timer.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:42</date> 10 //</624342650799001600> 11 12 package metrics 13 14 import ( 15 "math" 16 "sort" 17 "sync" 18 "time" 19 ) 20 21 //存储在重置计时器中的值的初始切片容量 22 const InitialResettingTimerSliceCap = 10 23 24 //ResettingTimer用于存储计时器的聚合值,这些值在每个刷新间隔都会重置。 25 type ResettingTimer interface { 26 Values() []int64 27 Snapshot() ResettingTimer 28 Percentiles([]float64) []int64 29 Mean() float64 30 Time(func()) 31 Update(time.Duration) 32 UpdateSince(time.Time) 33 } 34 35 //GetOrRegisterResettingTimer返回现有的ResettingTimer或构造并注册 36 //新标准重置计时器。 37 func GetOrRegisterResettingTimer(name string, r Registry) ResettingTimer { 38 if nil == r { 39 r = DefaultRegistry 40 } 41 return r.GetOrRegister(name, NewResettingTimer).(ResettingTimer) 42 } 43 44 //NewRegisteredResettingTimer构造并注册新的StandardResettingTimer。 45 func NewRegisteredResettingTimer(name string, r Registry) ResettingTimer { 46 c := NewResettingTimer() 47 if nil == r { 48 r = DefaultRegistry 49 } 50 r.Register(name, c) 51 return c 52 } 53 54 //NewResettingTimer构造新的标准ResettingTimer 55 func NewResettingTimer() ResettingTimer { 56 if !Enabled { 57 return NilResettingTimer{} 58 } 59 return &StandardResettingTimer{ 60 values: make([]int64, 0, InitialResettingTimerSliceCap), 61 } 62 } 63 64 //NilResettingTimer是一个不允许的ResettingTimer。 65 type NilResettingTimer struct { 66 } 67 68 //值是不可操作的。 69 func (NilResettingTimer) Values() []int64 { return nil } 70 71 //快照是不可操作的。 72 func (NilResettingTimer) Snapshot() ResettingTimer { 73 return &ResettingTimerSnapshot{ 74 values: []int64{}, 75 } 76 } 77 78 //时间是不允许的。 79 func (NilResettingTimer) Time(func()) {} 80 81 //更新是不可操作的。 82 func (NilResettingTimer) Update(time.Duration) {} 83 84 //百分位数恐慌。 85 func (NilResettingTimer) Percentiles([]float64) []int64 { 86 panic("Percentiles called on a NilResettingTimer") 87 } 88 89 //平均恐慌。 90 func (NilResettingTimer) Mean() float64 { 91 panic("Mean called on a NilResettingTimer") 92 } 93 94 //updateSince是一个no-op。 95 func (NilResettingTimer) UpdateSince(time.Time) {} 96 97 //StandardResettingTimer是ResettingTimer的标准实现。 98 //和米。 99 type StandardResettingTimer struct { 100 values []int64 101 mutex sync.Mutex 102 } 103 104 //值返回包含所有测量值的切片。 105 func (t *StandardResettingTimer) Values() []int64 { 106 return t.values 107 } 108 109 //快照重置计时器并返回其内容的只读副本。 110 func (t *StandardResettingTimer) Snapshot() ResettingTimer { 111 t.mutex.Lock() 112 defer t.mutex.Unlock() 113 currentValues := t.values 114 t.values = make([]int64, 0, InitialResettingTimerSliceCap) 115 116 return &ResettingTimerSnapshot{ 117 values: currentValues, 118 } 119 } 120 121 //百分位数恐慌。 122 func (t *StandardResettingTimer) Percentiles([]float64) []int64 { 123 panic("Percentiles called on a StandardResettingTimer") 124 } 125 126 //平均恐慌。 127 func (t *StandardResettingTimer) Mean() float64 { 128 panic("Mean called on a StandardResettingTimer") 129 } 130 131 //记录给定函数执行的持续时间。 132 func (t *StandardResettingTimer) Time(f func()) { 133 ts := time.Now() 134 f() 135 t.Update(time.Since(ts)) 136 } 137 138 //记录事件的持续时间。 139 func (t *StandardResettingTimer) Update(d time.Duration) { 140 t.mutex.Lock() 141 defer t.mutex.Unlock() 142 t.values = append(t.values, int64(d)) 143 } 144 145 //记录一次开始到现在结束的事件的持续时间。 146 func (t *StandardResettingTimer) UpdateSince(ts time.Time) { 147 t.mutex.Lock() 148 defer t.mutex.Unlock() 149 t.values = append(t.values, int64(time.Since(ts))) 150 } 151 152 //ResettingTimersSnapshot是另一个ResettingTimer的时间点副本。 153 type ResettingTimerSnapshot struct { 154 values []int64 155 mean float64 156 thresholdBoundaries []int64 157 calculated bool 158 } 159 160 //快照返回快照。 161 func (t *ResettingTimerSnapshot) Snapshot() ResettingTimer { return t } 162 163 //时间恐慌。 164 func (*ResettingTimerSnapshot) Time(func()) { 165 panic("Time called on a ResettingTimerSnapshot") 166 } 167 168 //更新恐慌。 169 func (*ResettingTimerSnapshot) Update(time.Duration) { 170 panic("Update called on a ResettingTimerSnapshot") 171 } 172 173 //更新自恐慌。 174 func (*ResettingTimerSnapshot) UpdateSince(time.Time) { 175 panic("UpdateSince called on a ResettingTimerSnapshot") 176 } 177 178 //值返回快照中的所有值。 179 func (t *ResettingTimerSnapshot) Values() []int64 { 180 return t.values 181 } 182 183 //Percentiles返回输入百分位数的边界。 184 func (t *ResettingTimerSnapshot) Percentiles(percentiles []float64) []int64 { 185 t.calc(percentiles) 186 187 return t.thresholdBoundaries 188 } 189 190 //mean返回快照值的平均值 191 func (t *ResettingTimerSnapshot) Mean() float64 { 192 if !t.calculated { 193 t.calc([]float64{}) 194 } 195 196 return t.mean 197 } 198 199 func (t *ResettingTimerSnapshot) calc(percentiles []float64) { 200 sort.Sort(Int64Slice(t.values)) 201 202 count := len(t.values) 203 if count > 0 { 204 min := t.values[0] 205 max := t.values[count-1] 206 207 cumulativeValues := make([]int64, count) 208 cumulativeValues[0] = min 209 for i := 1; i < count; i++ { 210 cumulativeValues[i] = t.values[i] + cumulativeValues[i-1] 211 } 212 213 t.thresholdBoundaries = make([]int64, len(percentiles)) 214 215 thresholdBoundary := max 216 217 for i, pct := range percentiles { 218 if count > 1 { 219 var abs float64 220 if pct >= 0 { 221 abs = pct 222 } else { 223 abs = 100 + pct 224 } 225 //可怜人的数学。圆(X): 226 //数学楼层(x+0.5) 227 indexOfPerc := int(math.Floor(((abs / 100.0) * float64(count)) + 0.5)) 228 if pct >= 0 && indexOfPerc > 0 { 229 indexOfPerc -= 1 //索引偏移=0 230 } 231 thresholdBoundary = t.values[indexOfPerc] 232 } 233 234 t.thresholdBoundaries[i] = thresholdBoundary 235 } 236 237 sum := cumulativeValues[count-1] 238 t.mean = float64(sum) / float64(count) 239 } else { 240 t.thresholdBoundaries = make([]int64, len(percentiles)) 241 t.mean = 0 242 } 243 244 t.calculated = true 245 } 246 247 //Int64Slice将sort.interface方法附加到[]Int64,按递增顺序排序。 248 type Int64Slice []int64 249 250 func (s Int64Slice) Len() int { return len(s) } 251 func (s Int64Slice) Less(i, j int) bool { return s[i] < s[j] } 252 func (s Int64Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 253