diff options
Diffstat (limited to 'vendor/github.com/facebookgo/stats/counter.go')
-rw-r--r-- | vendor/github.com/facebookgo/stats/counter.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/vendor/github.com/facebookgo/stats/counter.go b/vendor/github.com/facebookgo/stats/counter.go new file mode 100644 index 00000000..59a0ed1e --- /dev/null +++ b/vendor/github.com/facebookgo/stats/counter.go @@ -0,0 +1,112 @@ +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") +} |