github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/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 19:16:40</date>
    10  //</624450099757453312>
    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