gitea/vendor/github.com/facebookgo/stats/counter.go

113 lines
2.7 KiB
Go

package stats
import "fmt"
// Type is the type of aggregation of apply
type Type int
const (
AggregateAvg Type = iota
AggregateSum
AggregateHistogram
)
var (
// HistogramPercentiles is used to determine which percentiles to return for
// SimpleCounter.Aggregate
HistogramPercentiles = map[string]float64{
"p50": 0.5,
"p95": 0.95,
"p99": 0.99,
}
// MinSamplesForPercentiles is used by SimpleCounter.Aggregate to determine
// what the minimum number of samples is required for percentile analysis
MinSamplesForPercentiles = 10
)
// Aggregates can be used to merge counters together. This is not goroutine safe
type Aggregates map[string]Counter
// Add adds the counter for aggregation. This is not goroutine safe
func (a Aggregates) Add(c Counter) error {
key := c.FullKey()
if counter, ok := a[key]; ok {
if counter.GetType() != c.GetType() {
return fmt.Errorf("stats: mismatched aggregation type for: %s", key)
}
counter.AddValues(c.GetValues()...)
} else {
a[key] = c
}
return nil
}
// Counter is the interface used by Aggregates to merge counters together
type Counter interface {
// FullKey is used to uniquely identify the counter
FullKey() string
// AddValues adds values for aggregation
AddValues(...float64)
// GetValues returns the values for aggregation
GetValues() []float64
// GetType returns the type of aggregation to apply
GetType() Type
}
// SimpleCounter is a basic implementation of the Counter interface
type SimpleCounter struct {
Key string
Values []float64
Type Type
}
// FullKey is part of the Counter interace
func (s *SimpleCounter) FullKey() string {
return s.Key
}
// GetValues is part of the Counter interface
func (s *SimpleCounter) GetValues() []float64 {
return s.Values
}
// AddValues is part of the Counter interface
func (s *SimpleCounter) AddValues(vs ...float64) {
s.Values = append(s.Values, vs...)
}
// GetType is part of the Counter interface
func (s *SimpleCounter) GetType() Type {
return s.Type
}
// Aggregate aggregates the provided values appropriately, returning a map
// from key to value. If AggregateHistogram is specified, the map will contain
// the relevant percentiles as specified by HistogramPercentiles
func (s *SimpleCounter) Aggregate() map[string]float64 {
switch s.Type {
case AggregateAvg:
return map[string]float64{
s.Key: Average(s.Values),
}
case AggregateSum:
return map[string]float64{
s.Key: Sum(s.Values),
}
case AggregateHistogram:
histogram := map[string]float64{
s.Key: Average(s.Values),
}
if len(s.Values) > MinSamplesForPercentiles {
for k, v := range Percentiles(s.Values, HistogramPercentiles) {
histogram[fmt.Sprintf("%s.%s", s.Key, k)] = v
}
}
return histogram
}
panic("stats: unsupported aggregation type")
}