github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/metrics/sample.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  package metrics
    10  
    11  import (
    12  	"math"
    13  	"math/rand"
    14  	"sort"
    15  	"sync"
    16  	"time"
    17  )
    18  
    19  const rescaleThreshold = time.Hour
    20  
    21  //样本保持统计意义上的值选择
    22  //小溪
    23  type Sample interface {
    24  	Clear()
    25  	Count() int64
    26  	Max() int64
    27  	Mean() float64
    28  	Min() int64
    29  	Percentile(float64) float64
    30  	Percentiles([]float64) []float64
    31  	Size() int
    32  	Snapshot() Sample
    33  	StdDev() float64
    34  	Sum() int64
    35  	Update(int64)
    36  	Values() []int64
    37  	Variance() float64
    38  }
    39  
    40  //expdecaysample是使用正向衰减的指数衰减采样
    41  //优先水库。参见Cormode等人的“前向衰减:一个实际时间”
    42  //流媒体系统的衰减模型”。
    43  //
    44  //<http://dimacs.rutgers.edu/~graham/pubs/papers/fwdecay.pdf>
    45  type ExpDecaySample struct {
    46  	alpha         float64
    47  	count         int64
    48  	mutex         sync.Mutex
    49  	reservoirSize int
    50  	t0, t1        time.Time
    51  	values        *expDecaySampleHeap
    52  }
    53  
    54  //newexpdecaysample使用
    55  //给定储层大小和α。
    56  func NewExpDecaySample(reservoirSize int, alpha float64) Sample {
    57  	if !Enabled {
    58  		return NilSample{}
    59  	}
    60  	s := &ExpDecaySample{
    61  		alpha:         alpha,
    62  		reservoirSize: reservoirSize,
    63  		t0:            time.Now(),
    64  		values:        newExpDecaySampleHeap(reservoirSize),
    65  	}
    66  	s.t1 = s.t0.Add(rescaleThreshold)
    67  	return s
    68  }
    69  
    70  //清除清除所有样本。
    71  func (s *ExpDecaySample) Clear() {
    72  	s.mutex.Lock()
    73  	defer s.mutex.Unlock()
    74  	s.count = 0
    75  	s.t0 = time.Now()
    76  	s.t1 = s.t0.Add(rescaleThreshold)
    77  	s.values.Clear()
    78  }
    79  
    80  //count返回记录的样本数,可能超过
    81  //油藏规模
    82  func (s *ExpDecaySample) Count() int64 {
    83  	s.mutex.Lock()
    84  	defer s.mutex.Unlock()
    85  	return s.count
    86  }
    87  
    88  //max返回样本中的最大值,该值可能不是最大值。
    89  //值永远是样本的一部分。
    90  func (s *ExpDecaySample) Max() int64 {
    91  	return SampleMax(s.Values())
    92  }
    93  
    94  //mean返回样本值的平均值。
    95  func (s *ExpDecaySample) Mean() float64 {
    96  	return SampleMean(s.Values())
    97  }
    98  
    99  //Min返回样本中的最小值,该值可能不是最小值
   100  //值永远是样本的一部分。
   101  func (s *ExpDecaySample) Min() int64 {
   102  	return SampleMin(s.Values())
   103  }
   104  
   105  //Percentile返回样本中任意百分位数的值。
   106  func (s *ExpDecaySample) Percentile(p float64) float64 {
   107  	return SamplePercentile(s.Values(), p)
   108  }
   109  
   110  //Percentiles返回
   111  //样品。
   112  func (s *ExpDecaySample) Percentiles(ps []float64) []float64 {
   113  	return SamplePercentiles(s.Values(), ps)
   114  }
   115  
   116  //SIZE返回样本的大小,最多是储层大小。
   117  func (s *ExpDecaySample) Size() int {
   118  	s.mutex.Lock()
   119  	defer s.mutex.Unlock()
   120  	return s.values.Size()
   121  }
   122  
   123  //快照返回示例的只读副本。
   124  func (s *ExpDecaySample) Snapshot() Sample {
   125  	s.mutex.Lock()
   126  	defer s.mutex.Unlock()
   127  	vals := s.values.Values()
   128  	values := make([]int64, len(vals))
   129  	for i, v := range vals {
   130  		values[i] = v.v
   131  	}
   132  	return &SampleSnapshot{
   133  		count:  s.count,
   134  		values: values,
   135  	}
   136  }
   137  
   138  //stdev返回样本值的标准偏差。
   139  func (s *ExpDecaySample) StdDev() float64 {
   140  	return SampleStdDev(s.Values())
   141  }
   142  
   143  //sum返回样本中值的总和。
   144  func (s *ExpDecaySample) Sum() int64 {
   145  	return SampleSum(s.Values())
   146  }
   147  
   148  //更新示例新值。
   149  func (s *ExpDecaySample) Update(v int64) {
   150  	s.update(time.Now(), v)
   151  }
   152  
   153  //值返回示例中值的副本。
   154  func (s *ExpDecaySample) Values() []int64 {
   155  	s.mutex.Lock()
   156  	defer s.mutex.Unlock()
   157  	vals := s.values.Values()
   158  	values := make([]int64, len(vals))
   159  	for i, v := range vals {
   160  		values[i] = v.v
   161  	}
   162  	return values
   163  }
   164  
   165  //方差返回样本中值的方差。
   166  func (s *ExpDecaySample) Variance() float64 {
   167  	return SampleVariance(s.Values())
   168  }
   169  
   170  //更新在特定时间戳处对新值进行采样。这是一个方法
   171  //它本身有助于测试。
   172  func (s *ExpDecaySample) update(t time.Time, v int64) {
   173  	s.mutex.Lock()
   174  	defer s.mutex.Unlock()
   175  	s.count++
   176  	if s.values.Size() == s.reservoirSize {
   177  		s.values.Pop()
   178  	}
   179  	s.values.Push(expDecaySample{
   180  		k: math.Exp(t.Sub(s.t0).Seconds()*s.alpha) / rand.Float64(),
   181  		v: v,
   182  	})
   183  	if t.After(s.t1) {
   184  		values := s.values.Values()
   185  		t0 := s.t0
   186  		s.values.Clear()
   187  		s.t0 = t
   188  		s.t1 = s.t0.Add(rescaleThreshold)
   189  		for _, v := range values {
   190  			v.k = v.k * math.Exp(-s.alpha*s.t0.Sub(t0).Seconds())
   191  			s.values.Push(v)
   192  		}
   193  	}
   194  }
   195  
   196  //nilsample是一个no op示例。
   197  type NilSample struct{}
   198  
   199  //清除是不可操作的。
   200  func (NilSample) Clear() {}
   201  
   202  //计数是不允许的。
   203  func (NilSample) Count() int64 { return 0 }
   204  
   205  //马克斯不是一个OP。
   206  func (NilSample) Max() int64 { return 0 }
   207  
   208  //平均值是不允许的。
   209  func (NilSample) Mean() float64 { return 0.0 }
   210  
   211  //min是NO-OP。
   212  func (NilSample) Min() int64 { return 0 }
   213  
   214  //百分位数是不允许的。
   215  func (NilSample) Percentile(p float64) float64 { return 0.0 }
   216  
   217  //百分位数是不允许的。
   218  func (NilSample) Percentiles(ps []float64) []float64 {
   219  	return make([]float64, len(ps))
   220  }
   221  
   222  //尺寸是不允许的。
   223  func (NilSample) Size() int { return 0 }
   224  
   225  //样本是不可操作的。
   226  func (NilSample) Snapshot() Sample { return NilSample{} }
   227  
   228  //stdev是一个no-op。
   229  func (NilSample) StdDev() float64 { return 0.0 }
   230  
   231  //和是一个NO-op.
   232  func (NilSample) Sum() int64 { return 0 }
   233  
   234  //更新是不可操作的。
   235  func (NilSample) Update(v int64) {}
   236  
   237  //值是不可操作的。
   238  func (NilSample) Values() []int64 { return []int64{} }
   239  
   240  //方差是不可操作的。
   241  func (NilSample) Variance() float64 { return 0.0 }
   242  
   243  //sampleMax返回Int64切片的最大值。
   244  func SampleMax(values []int64) int64 {
   245  	if 0 == len(values) {
   246  		return 0
   247  	}
   248  	var max int64 = math.MinInt64
   249  	for _, v := range values {
   250  		if max < v {
   251  			max = v
   252  		}
   253  	}
   254  	return max
   255  }
   256  
   257  //samplemean返回Int64切片的平均值。
   258  func SampleMean(values []int64) float64 {
   259  	if 0 == len(values) {
   260  		return 0.0
   261  	}
   262  	return float64(SampleSum(values)) / float64(len(values))
   263  }
   264  
   265  //samplemin返回int64切片的最小值。
   266  func SampleMin(values []int64) int64 {
   267  	if 0 == len(values) {
   268  		return 0
   269  	}
   270  	var min int64 = math.MaxInt64
   271  	for _, v := range values {
   272  		if min > v {
   273  			min = v
   274  		}
   275  	}
   276  	return min
   277  }
   278  
   279  //samplePercentles返回Int64切片的任意百分比。
   280  func SamplePercentile(values int64Slice, p float64) float64 {
   281  	return SamplePercentiles(values, []float64{p})[0]
   282  }
   283  
   284  //samplePercenties返回切片的任意百分比切片
   285  //英特64
   286  func SamplePercentiles(values int64Slice, ps []float64) []float64 {
   287  	scores := make([]float64, len(ps))
   288  	size := len(values)
   289  	if size > 0 {
   290  		sort.Sort(values)
   291  		for i, p := range ps {
   292  			pos := p * float64(size+1)
   293  			if pos < 1.0 {
   294  				scores[i] = float64(values[0])
   295  			} else if pos >= float64(size) {
   296  				scores[i] = float64(values[size-1])
   297  			} else {
   298  				lower := float64(values[int(pos)-1])
   299  				upper := float64(values[int(pos)])
   300  				scores[i] = lower + (pos-math.Floor(pos))*(upper-lower)
   301  			}
   302  		}
   303  	}
   304  	return scores
   305  }
   306  
   307  //samplesnapshot是另一个示例的只读副本。
   308  type SampleSnapshot struct {
   309  	count  int64
   310  	values []int64
   311  }
   312  
   313  func NewSampleSnapshot(count int64, values []int64) *SampleSnapshot {
   314  	return &SampleSnapshot{
   315  		count:  count,
   316  		values: values,
   317  	}
   318  }
   319  
   320  //清晰的恐慌。
   321  func (*SampleSnapshot) Clear() {
   322  	panic("Clear called on a SampleSnapshot")
   323  }
   324  
   325  //Count返回拍摄快照时的输入计数。
   326  func (s *SampleSnapshot) Count() int64 { return s.count }
   327  
   328  //max返回快照拍摄时的最大值。
   329  func (s *SampleSnapshot) Max() int64 { return SampleMax(s.values) }
   330  
   331  //mean返回拍摄快照时的平均值。
   332  func (s *SampleSnapshot) Mean() float64 { return SampleMean(s.values) }
   333  
   334  //Min返回拍摄快照时的最小值。
   335  func (s *SampleSnapshot) Min() int64 { return SampleMin(s.values) }
   336  
   337  //percentile返回在
   338  //已拍摄快照。
   339  func (s *SampleSnapshot) Percentile(p float64) float64 {
   340  	return SamplePercentile(s.values, p)
   341  }
   342  
   343  //Percentiles返回当时任意百分位值的切片
   344  //快照已拍摄。
   345  func (s *SampleSnapshot) Percentiles(ps []float64) []float64 {
   346  	return SamplePercentiles(s.values, ps)
   347  }
   348  
   349  //SIZE返回拍摄快照时样本的大小。
   350  func (s *SampleSnapshot) Size() int { return len(s.values) }
   351  
   352  //快照返回快照。
   353  func (s *SampleSnapshot) Snapshot() Sample { return s }
   354  
   355  //stdev返回快照时值的标准偏差
   356  //拿。
   357  func (s *SampleSnapshot) StdDev() float64 { return SampleStdDev(s.values) }
   358  
   359  //SUM返回拍摄快照时的值总和。
   360  func (s *SampleSnapshot) Sum() int64 { return SampleSum(s.values) }
   361  
   362  //更新恐慌。
   363  func (*SampleSnapshot) Update(int64) {
   364  	panic("Update called on a SampleSnapshot")
   365  }
   366  
   367  //值返回示例中值的副本。
   368  func (s *SampleSnapshot) Values() []int64 {
   369  	values := make([]int64, len(s.values))
   370  	copy(values, s.values)
   371  	return values
   372  }
   373  
   374  //variance返回拍摄快照时值的方差。
   375  func (s *SampleSnapshot) Variance() float64 { return SampleVariance(s.values) }
   376  
   377  //samplestdev返回int64切片的标准偏差。
   378  func SampleStdDev(values []int64) float64 {
   379  	return math.Sqrt(SampleVariance(values))
   380  }
   381  
   382  //samplesum返回Int64切片的和。
   383  func SampleSum(values []int64) int64 {
   384  	var sum int64
   385  	for _, v := range values {
   386  		sum += v
   387  	}
   388  	return sum
   389  }
   390  
   391  //samplevariance返回Int64切片的方差。
   392  func SampleVariance(values []int64) float64 {
   393  	if 0 == len(values) {
   394  		return 0.0
   395  	}
   396  	m := SampleMean(values)
   397  	var sum float64
   398  	for _, v := range values {
   399  		d := float64(v) - m
   400  		sum += d * d
   401  	}
   402  	return sum / float64(len(values))
   403  }
   404  
   405  //使用维特算法R的均匀样本。
   406  //
   407  //<http://www.cs.umd.edu/~samir/498/vitter.pdf>
   408  type UniformSample struct {
   409  	count         int64
   410  	mutex         sync.Mutex
   411  	reservoirSize int
   412  	values        []int64
   413  }
   414  
   415  //NewUniformSample构造一个新的具有给定储层的均匀样品
   416  //尺寸。
   417  func NewUniformSample(reservoirSize int) Sample {
   418  	if !Enabled {
   419  		return NilSample{}
   420  	}
   421  	return &UniformSample{
   422  		reservoirSize: reservoirSize,
   423  		values:        make([]int64, 0, reservoirSize),
   424  	}
   425  }
   426  
   427  //清除清除所有样本。
   428  func (s *UniformSample) Clear() {
   429  	s.mutex.Lock()
   430  	defer s.mutex.Unlock()
   431  	s.count = 0
   432  	s.values = make([]int64, 0, s.reservoirSize)
   433  }
   434  
   435  //count返回记录的样本数,可能超过
   436  //油藏规模
   437  func (s *UniformSample) Count() int64 {
   438  	s.mutex.Lock()
   439  	defer s.mutex.Unlock()
   440  	return s.count
   441  }
   442  
   443  //max返回样本中的最大值,该值可能不是最大值。
   444  //值永远是样本的一部分。
   445  func (s *UniformSample) Max() int64 {
   446  	s.mutex.Lock()
   447  	defer s.mutex.Unlock()
   448  	return SampleMax(s.values)
   449  }
   450  
   451  //mean返回样本值的平均值。
   452  func (s *UniformSample) Mean() float64 {
   453  	s.mutex.Lock()
   454  	defer s.mutex.Unlock()
   455  	return SampleMean(s.values)
   456  }
   457  
   458  //Min返回样本中的最小值,该值可能不是最小值
   459  //值永远是样本的一部分。
   460  func (s *UniformSample) Min() int64 {
   461  	s.mutex.Lock()
   462  	defer s.mutex.Unlock()
   463  	return SampleMin(s.values)
   464  }
   465  
   466  //Percentile返回样本中任意百分位数的值。
   467  func (s *UniformSample) Percentile(p float64) float64 {
   468  	s.mutex.Lock()
   469  	defer s.mutex.Unlock()
   470  	return SamplePercentile(s.values, p)
   471  }
   472  
   473  //Percentiles返回
   474  //样品。
   475  func (s *UniformSample) Percentiles(ps []float64) []float64 {
   476  	s.mutex.Lock()
   477  	defer s.mutex.Unlock()
   478  	return SamplePercentiles(s.values, ps)
   479  }
   480  
   481  //SIZE返回样本的大小,最多是储层大小。
   482  func (s *UniformSample) Size() int {
   483  	s.mutex.Lock()
   484  	defer s.mutex.Unlock()
   485  	return len(s.values)
   486  }
   487  
   488  //快照返回示例的只读副本。
   489  func (s *UniformSample) Snapshot() Sample {
   490  	s.mutex.Lock()
   491  	defer s.mutex.Unlock()
   492  	values := make([]int64, len(s.values))
   493  	copy(values, s.values)
   494  	return &SampleSnapshot{
   495  		count:  s.count,
   496  		values: values,
   497  	}
   498  }
   499  
   500  //stdev返回样本值的标准偏差。
   501  func (s *UniformSample) StdDev() float64 {
   502  	s.mutex.Lock()
   503  	defer s.mutex.Unlock()
   504  	return SampleStdDev(s.values)
   505  }
   506  
   507  //sum返回样本中值的总和。
   508  func (s *UniformSample) Sum() int64 {
   509  	s.mutex.Lock()
   510  	defer s.mutex.Unlock()
   511  	return SampleSum(s.values)
   512  }
   513  
   514  //更新示例新值。
   515  func (s *UniformSample) Update(v int64) {
   516  	s.mutex.Lock()
   517  	defer s.mutex.Unlock()
   518  	s.count++
   519  	if len(s.values) < s.reservoirSize {
   520  		s.values = append(s.values, v)
   521  	} else {
   522  		r := rand.Int63n(s.count)
   523  		if r < int64(len(s.values)) {
   524  			s.values[int(r)] = v
   525  		}
   526  	}
   527  }
   528  
   529  //值返回示例中值的副本。
   530  func (s *UniformSample) Values() []int64 {
   531  	s.mutex.Lock()
   532  	defer s.mutex.Unlock()
   533  	values := make([]int64, len(s.values))
   534  	copy(values, s.values)
   535  	return values
   536  }
   537  
   538  //方差返回样本中值的方差。
   539  func (s *UniformSample) Variance() float64 {
   540  	s.mutex.Lock()
   541  	defer s.mutex.Unlock()
   542  	return SampleVariance(s.values)
   543  }
   544  
   545  //expdecaysample表示堆中的单个样本。
   546  type expDecaySample struct {
   547  	k float64
   548  	v int64
   549  }
   550  
   551  func newExpDecaySampleHeap(reservoirSize int) *expDecaySampleHeap {
   552  	return &expDecaySampleHeap{make([]expDecaySample, 0, reservoirSize)}
   553  }
   554  
   555  //expdecaysampleheap是expdecaysamples的最小堆。
   556  //从标准库的容器/堆复制内部实现
   557  type expDecaySampleHeap struct {
   558  	s []expDecaySample
   559  }
   560  
   561  func (h *expDecaySampleHeap) Clear() {
   562  	h.s = h.s[:0]
   563  }
   564  
   565  func (h *expDecaySampleHeap) Push(s expDecaySample) {
   566  	n := len(h.s)
   567  	h.s = h.s[0 : n+1]
   568  	h.s[n] = s
   569  	h.up(n)
   570  }
   571  
   572  func (h *expDecaySampleHeap) Pop() expDecaySample {
   573  	n := len(h.s) - 1
   574  	h.s[0], h.s[n] = h.s[n], h.s[0]
   575  	h.down(0, n)
   576  
   577  	n = len(h.s)
   578  	s := h.s[n-1]
   579  	h.s = h.s[0 : n-1]
   580  	return s
   581  }
   582  
   583  func (h *expDecaySampleHeap) Size() int {
   584  	return len(h.s)
   585  }
   586  
   587  func (h *expDecaySampleHeap) Values() []expDecaySample {
   588  	return h.s
   589  }
   590  
   591  func (h *expDecaySampleHeap) up(j int) {
   592  	for {
   593  i := (j - 1) / 2 //起源
   594  		if i == j || !(h.s[j].k < h.s[i].k) {
   595  			break
   596  		}
   597  		h.s[i], h.s[j] = h.s[j], h.s[i]
   598  		j = i
   599  	}
   600  }
   601  
   602  func (h *expDecaySampleHeap) down(i, n int) {
   603  	for {
   604  		j1 := 2*i + 1
   605  if j1 >= n || j1 < 0 { //int溢出后j1<0
   606  			break
   607  		}
   608  j := j1 //留守儿童
   609  		if j2 := j1 + 1; j2 < n && !(h.s[j1].k < h.s[j2].k) {
   610  j = j2 //=2*i+2//右儿童
   611  		}
   612  		if !(h.s[j].k < h.s[i].k) {
   613  			break
   614  		}
   615  		h.s[i], h.s[j] = h.s[j], h.s[i]
   616  		i = j
   617  	}
   618  }
   619  
   620  type int64Slice []int64
   621  
   622  func (p int64Slice) Len() int           { return len(p) }
   623  func (p int64Slice) Less(i, j int) bool { return p[i] < p[j] }
   624  func (p int64Slice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }