diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/go/core/metrics/buckets.go | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'library/go/core/metrics/buckets.go')
-rw-r--r-- | library/go/core/metrics/buckets.go | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/library/go/core/metrics/buckets.go b/library/go/core/metrics/buckets.go new file mode 100644 index 0000000000..063c0c4418 --- /dev/null +++ b/library/go/core/metrics/buckets.go @@ -0,0 +1,147 @@ +package metrics + +import ( + "sort" + "time" +) + +var ( + _ DurationBuckets = (*durationBuckets)(nil) + _ Buckets = (*buckets)(nil) +) + +const ( + errBucketsCountNeedsGreaterThanZero = "n needs to be > 0" + errBucketsStartNeedsGreaterThanZero = "start needs to be > 0" + errBucketsFactorNeedsGreaterThanOne = "factor needs to be > 1" +) + +type durationBuckets struct { + buckets []time.Duration +} + +// NewDurationBuckets returns new DurationBuckets implementation. +func NewDurationBuckets(bk ...time.Duration) DurationBuckets { + sort.Slice(bk, func(i, j int) bool { + return bk[i] < bk[j] + }) + return durationBuckets{buckets: bk} +} + +func (d durationBuckets) Size() int { + return len(d.buckets) +} + +func (d durationBuckets) MapDuration(dv time.Duration) (idx int) { + for _, bound := range d.buckets { + if dv < bound { + break + } + idx++ + } + return +} + +func (d durationBuckets) UpperBound(idx int) time.Duration { + if idx > d.Size()-1 { + panic("idx is out of bounds") + } + return d.buckets[idx] +} + +type buckets struct { + buckets []float64 +} + +// NewBuckets returns new Buckets implementation. +func NewBuckets(bk ...float64) Buckets { + sort.Slice(bk, func(i, j int) bool { + return bk[i] < bk[j] + }) + return buckets{buckets: bk} +} + +func (d buckets) Size() int { + return len(d.buckets) +} + +func (d buckets) MapValue(v float64) (idx int) { + for _, bound := range d.buckets { + if v < bound { + break + } + idx++ + } + return +} + +func (d buckets) UpperBound(idx int) float64 { + if idx > d.Size()-1 { + panic("idx is out of bounds") + } + return d.buckets[idx] +} + +// MakeLinearBuckets creates a set of linear value buckets. +func MakeLinearBuckets(start, width float64, n int) Buckets { + if n <= 0 { + panic(errBucketsCountNeedsGreaterThanZero) + } + bounds := make([]float64, n) + for i := range bounds { + bounds[i] = start + (float64(i) * width) + } + return NewBuckets(bounds...) +} + +// MakeLinearDurationBuckets creates a set of linear duration buckets. +func MakeLinearDurationBuckets(start, width time.Duration, n int) DurationBuckets { + if n <= 0 { + panic(errBucketsCountNeedsGreaterThanZero) + } + buckets := make([]time.Duration, n) + for i := range buckets { + buckets[i] = start + (time.Duration(i) * width) + } + return NewDurationBuckets(buckets...) +} + +// MakeExponentialBuckets creates a set of exponential value buckets. +func MakeExponentialBuckets(start, factor float64, n int) Buckets { + if n <= 0 { + panic(errBucketsCountNeedsGreaterThanZero) + } + if start <= 0 { + panic(errBucketsStartNeedsGreaterThanZero) + } + if factor <= 1 { + panic(errBucketsFactorNeedsGreaterThanOne) + } + buckets := make([]float64, n) + curr := start + for i := range buckets { + buckets[i] = curr + curr *= factor + } + return NewBuckets(buckets...) +} + +// MakeExponentialDurationBuckets creates a set of exponential duration buckets. +func MakeExponentialDurationBuckets(start time.Duration, factor float64, n int) DurationBuckets { + if n <= 0 { + panic(errBucketsCountNeedsGreaterThanZero) + } + if start <= 0 { + panic(errBucketsStartNeedsGreaterThanZero) + } + if factor <= 1 { + panic(errBucketsFactorNeedsGreaterThanOne) + } + buckets := make([]time.Duration, n) + curr := start + for i := range buckets { + buckets[i] = curr + curr = time.Duration(float64(curr) * factor) + } + return NewDurationBuckets(buckets...) +} |