moira

Форк
0
/
sample.go 
144 строки · 3.6 Кб
1
package metrics
2

3
import (
4
	"sync"
5

6
	"github.com/rcrowley/go-metrics"
7
)
8

9
const (
10
	movingWindowSize = 1028
11
)
12

13
// movingWindowSample is sample using moving window reservoir to keep selection of stream values.
14
type movingWindowSample struct {
15
	buffer      []int64
16
	count       int64
17
	index, size int
18
	overflow    bool
19
	lock        sync.RWMutex
20
}
21

22
func newMovingWindowSample() metrics.Sample {
23
	if metrics.UseNilMetrics {
24
		return metrics.NilSample{}
25
	}
26

27
	return &movingWindowSample{
28
		buffer: make([]int64, movingWindowSize),
29
		size:   movingWindowSize,
30
	}
31
}
32

33
// Clear clears all sample
34
func (mw *movingWindowSample) Clear() {
35
	mw.lock.Lock()
36
	defer mw.lock.Unlock()
37

38
	mw.count = 0
39
	mw.index = 0
40
	mw.overflow = false
41
}
42

43
// Count returns the number of samples recorded, which may exceed the reservoir size.
44
func (mw *movingWindowSample) Count() int64 {
45
	mw.lock.RLock()
46
	defer mw.lock.RUnlock()
47
	return mw.count
48
}
49

50
// Max returns the maximum value in the sample.
51
func (mw *movingWindowSample) Max() int64 {
52
	return metrics.SampleMax(mw.Values())
53
}
54

55
// Mean returns the mean of the values in the sample.
56
func (mw *movingWindowSample) Mean() float64 {
57
	return metrics.SampleMean(mw.Values())
58
}
59

60
// Min returns the minimum value in the sample
61
func (mw *movingWindowSample) Min() int64 {
62
	return metrics.SampleMin(mw.Values())
63
}
64

65
// Percentile returns an arbitrary percentile of values in the sample.
66
func (mw *movingWindowSample) Percentile(p float64) float64 {
67
	return metrics.SamplePercentile(mw.Values(), p)
68
}
69

70
// Percentiles returns a slice of arbitrary percentiles of values in the sample.
71
func (mw *movingWindowSample) Percentiles(ps []float64) []float64 {
72
	return metrics.SamplePercentiles(mw.Values(), ps)
73
}
74

75
// Size returns the size of the sample, which is at most the reservoir size.
76
func (mw *movingWindowSample) Size() int {
77
	mw.lock.RLock()
78
	defer mw.lock.RUnlock()
79

80
	if mw.overflow {
81
		return mw.size
82
	} else {
83
		return mw.index
84
	}
85
}
86

87
// Snapshot returns a read-only copy of the sample.
88
func (mw *movingWindowSample) Snapshot() metrics.Sample {
89
	mw.lock.RLock()
90
	defer mw.lock.RUnlock()
91

92
	return metrics.NewSampleSnapshot(mw.count, mw.Values())
93
}
94

95
// StdDev returns the standard deviation of the values in the sample.
96
func (mw *movingWindowSample) StdDev() float64 {
97
	return metrics.SampleStdDev(mw.Values())
98
}
99

100
// Sum returns the sum of the values in the sample.
101
func (mw *movingWindowSample) Sum() int64 {
102
	return metrics.SampleSum(mw.Values())
103
}
104

105
// Update samples a new value.
106
func (mw *movingWindowSample) Update(v int64) {
107
	mw.lock.Lock()
108
	defer mw.lock.Unlock()
109

110
	mw.buffer[mw.index] = v
111
	mw.count++
112
	mw.index++
113
	if mw.index == mw.size {
114
		mw.index = 0
115
		mw.overflow = true
116
	}
117
}
118

119
// Values returns a copy of the values in the sample.
120
func (mw *movingWindowSample) Values() []int64 {
121
	mw.lock.RLock()
122
	defer mw.lock.RUnlock()
123

124
	values := make([]int64, mw.size)
125
	if mw.overflow {
126
		// buffer has been overflow, so window's values consist of 2 parts:
127
		// from current position (included) to the end of buffer and from the beginning of buffer to current position (excluded)
128
		// e.g.: [7, 8, 3, 4, 5, 6], current position = 3, values are [3, 4, 5, 6, 7, 8]
129
		copied := copy(values, mw.buffer[mw.index:])
130
		if copied < mw.size {
131
			copy(values[copied:], mw.buffer[:mw.index])
132
		}
133
	} else {
134
		// buffer hasn't been overflown, so window's values is slice from beginning of buffer to current position (latter is excluded)
135
		// e.g.: [1, 2, 3, 4, 0, 0], current position = 4, values are [1, 2, 3, 4, 0, 0]
136
		copy(values, mw.buffer[0:mw.index])
137
	}
138
	return values
139
}
140

141
// Variance returns the variance of the values in the sample.
142
func (mw *movingWindowSample) Variance() float64 {
143
	return metrics.SampleVariance(mw.Values())
144
}
145

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.