summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/facebookgo/stats/counter.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/facebookgo/stats/counter.go')
-rw-r--r--vendor/github.com/facebookgo/stats/counter.go112
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")
+}