lotus/lib/stati/histo.go
Jakub Sztandera 7dd58efb84 Add quantiles and histogram
Signed-off-by: Jakub Sztandera <kubuxu@protocol.ai>
2021-06-18 15:44:36 -07:00

57 lines
1.1 KiB
Go

package stati
import (
"math"
"golang.org/x/xerrors"
)
type Histogram struct {
Buckets []float64
Counts []uint64
}
// NewHistogram creates a histograme with buckets defined as:
// {x > -Inf, x >= buckets[0], x >= buckets[1], ..., x >= buckets[i]}
func NewHistogram(buckets []float64) (*Histogram, error) {
if len(buckets) == 0 {
return nil, xerrors.Errorf("empty buckets")
}
prev := buckets[0]
for i, v := range buckets[1:] {
if v < prev {
return nil, xerrors.Errorf("bucket at index %d is smaller than previous %f < %f", i+1, v, prev)
}
prev = v
}
h := &Histogram{
Buckets: append([]float64{math.Inf(-1)}, buckets...),
Counts: make([]uint64, len(buckets)+1),
}
return h, nil
}
func (h *Histogram) Observe(x float64) {
for i, b := range h.Buckets {
if x >= b {
h.Counts[i]++
} else {
break
}
}
}
func (h *Histogram) Total() uint64 {
return h.Counts[0]
}
func (h *Histogram) Get(i int) uint64 {
if i >= len(h.Counts)-2 {
return h.Counts[i]
}
return h.Counts[i+1] - h.Counts[i+2]
}
func (h *Histogram) GetRatio(i int) float64 {
return float64(h.Get(i)) / float64(h.Total())
}