+++ /dev/null
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package metric
-
-import (
- "fmt"
- "sort"
- "time"
-
- "golang.org/x/tools/internal/event/keys"
- "golang.org/x/tools/internal/event/label"
-)
-
-// Data represents a single point in the time series of a metric.
-// This provides the common interface to all metrics no matter their data
-// format.
-// To get the actual values for the metric you must type assert to a concrete
-// metric type.
-type Data interface {
- // Handle returns the metric handle this data is for.
- //TODO: rethink the concept of metric handles
- Handle() string
- // Groups reports the rows that currently exist for this metric.
- Groups() [][]label.Label
-}
-
-// Int64Data is a concrete implementation of Data for int64 scalar metrics.
-type Int64Data struct {
- // Info holds the original construction information.
- Info *Scalar
- // IsGauge is true for metrics that track values, rather than increasing over time.
- IsGauge bool
- // Rows holds the per group values for the metric.
- Rows []int64
- // End is the last time this metric was updated.
- EndTime time.Time
-
- groups [][]label.Label
- key *keys.Int64
-}
-
-// Float64Data is a concrete implementation of Data for float64 scalar metrics.
-type Float64Data struct {
- // Info holds the original construction information.
- Info *Scalar
- // IsGauge is true for metrics that track values, rather than increasing over time.
- IsGauge bool
- // Rows holds the per group values for the metric.
- Rows []float64
- // End is the last time this metric was updated.
- EndTime time.Time
-
- groups [][]label.Label
- key *keys.Float64
-}
-
-// HistogramInt64Data is a concrete implementation of Data for int64 histogram metrics.
-type HistogramInt64Data struct {
- // Info holds the original construction information.
- Info *HistogramInt64
- // Rows holds the per group values for the metric.
- Rows []*HistogramInt64Row
- // End is the last time this metric was updated.
- EndTime time.Time
-
- groups [][]label.Label
- key *keys.Int64
-}
-
-// HistogramInt64Row holds the values for a single row of a HistogramInt64Data.
-type HistogramInt64Row struct {
- // Values is the counts per bucket.
- Values []int64
- // Count is the total count.
- Count int64
- // Sum is the sum of all the values recorded.
- Sum int64
- // Min is the smallest recorded value.
- Min int64
- // Max is the largest recorded value.
- Max int64
-}
-
-// HistogramFloat64Data is a concrete implementation of Data for float64 histogram metrics.
-type HistogramFloat64Data struct {
- // Info holds the original construction information.
- Info *HistogramFloat64
- // Rows holds the per group values for the metric.
- Rows []*HistogramFloat64Row
- // End is the last time this metric was updated.
- EndTime time.Time
-
- groups [][]label.Label
- key *keys.Float64
-}
-
-// HistogramFloat64Row holds the values for a single row of a HistogramFloat64Data.
-type HistogramFloat64Row struct {
- // Values is the counts per bucket.
- Values []int64
- // Count is the total count.
- Count int64
- // Sum is the sum of all the values recorded.
- Sum float64
- // Min is the smallest recorded value.
- Min float64
- // Max is the largest recorded value.
- Max float64
-}
-
-func labelListEqual(a, b []label.Label) bool {
- //TODO: make this more efficient
- return fmt.Sprint(a) == fmt.Sprint(b)
-}
-
-func labelListLess(a, b []label.Label) bool {
- //TODO: make this more efficient
- return fmt.Sprint(a) < fmt.Sprint(b)
-}
-
-func getGroup(lm label.Map, g *[][]label.Label, keys []label.Key) (int, bool) {
- group := make([]label.Label, len(keys))
- for i, key := range keys {
- l := lm.Find(key)
- if l.Valid() {
- group[i] = l
- }
- }
- old := *g
- index := sort.Search(len(old), func(i int) bool {
- return !labelListLess(old[i], group)
- })
- if index < len(old) && labelListEqual(group, old[index]) {
- // not a new group
- return index, false
- }
- *g = make([][]label.Label, len(old)+1)
- copy(*g, old[:index])
- copy((*g)[index+1:], old[index:])
- (*g)[index] = group
- return index, true
-}
-
-func (data *Int64Data) Handle() string { return data.Info.Name }
-func (data *Int64Data) Groups() [][]label.Label { return data.groups }
-
-func (data *Int64Data) modify(at time.Time, lm label.Map, f func(v int64) int64) Data {
- index, insert := getGroup(lm, &data.groups, data.Info.Keys)
- old := data.Rows
- if insert {
- data.Rows = make([]int64, len(old)+1)
- copy(data.Rows, old[:index])
- copy(data.Rows[index+1:], old[index:])
- } else {
- data.Rows = make([]int64, len(old))
- copy(data.Rows, old)
- }
- data.Rows[index] = f(data.Rows[index])
- data.EndTime = at
- frozen := *data
- return &frozen
-}
-
-func (data *Int64Data) count(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v int64) int64 {
- return v + 1
- })
-}
-
-func (data *Int64Data) sum(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v int64) int64 {
- return v + data.key.From(l)
- })
-}
-
-func (data *Int64Data) latest(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v int64) int64 {
- return data.key.From(l)
- })
-}
-
-func (data *Float64Data) Handle() string { return data.Info.Name }
-func (data *Float64Data) Groups() [][]label.Label { return data.groups }
-
-func (data *Float64Data) modify(at time.Time, lm label.Map, f func(v float64) float64) Data {
- index, insert := getGroup(lm, &data.groups, data.Info.Keys)
- old := data.Rows
- if insert {
- data.Rows = make([]float64, len(old)+1)
- copy(data.Rows, old[:index])
- copy(data.Rows[index+1:], old[index:])
- } else {
- data.Rows = make([]float64, len(old))
- copy(data.Rows, old)
- }
- data.Rows[index] = f(data.Rows[index])
- data.EndTime = at
- frozen := *data
- return &frozen
-}
-
-func (data *Float64Data) sum(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v float64) float64 {
- return v + data.key.From(l)
- })
-}
-
-func (data *Float64Data) latest(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v float64) float64 {
- return data.key.From(l)
- })
-}
-
-func (data *HistogramInt64Data) Handle() string { return data.Info.Name }
-func (data *HistogramInt64Data) Groups() [][]label.Label { return data.groups }
-
-func (data *HistogramInt64Data) modify(at time.Time, lm label.Map, f func(v *HistogramInt64Row)) Data {
- index, insert := getGroup(lm, &data.groups, data.Info.Keys)
- old := data.Rows
- var v HistogramInt64Row
- if insert {
- data.Rows = make([]*HistogramInt64Row, len(old)+1)
- copy(data.Rows, old[:index])
- copy(data.Rows[index+1:], old[index:])
- } else {
- data.Rows = make([]*HistogramInt64Row, len(old))
- copy(data.Rows, old)
- v = *data.Rows[index]
- }
- oldValues := v.Values
- v.Values = make([]int64, len(data.Info.Buckets))
- copy(v.Values, oldValues)
- f(&v)
- data.Rows[index] = &v
- data.EndTime = at
- frozen := *data
- return &frozen
-}
-
-func (data *HistogramInt64Data) record(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v *HistogramInt64Row) {
- value := data.key.From(l)
- v.Sum += value
- if v.Min > value || v.Count == 0 {
- v.Min = value
- }
- if v.Max < value || v.Count == 0 {
- v.Max = value
- }
- v.Count++
- for i, b := range data.Info.Buckets {
- if value <= b {
- v.Values[i]++
- }
- }
- })
-}
-
-func (data *HistogramFloat64Data) Handle() string { return data.Info.Name }
-func (data *HistogramFloat64Data) Groups() [][]label.Label { return data.groups }
-
-func (data *HistogramFloat64Data) modify(at time.Time, lm label.Map, f func(v *HistogramFloat64Row)) Data {
- index, insert := getGroup(lm, &data.groups, data.Info.Keys)
- old := data.Rows
- var v HistogramFloat64Row
- if insert {
- data.Rows = make([]*HistogramFloat64Row, len(old)+1)
- copy(data.Rows, old[:index])
- copy(data.Rows[index+1:], old[index:])
- } else {
- data.Rows = make([]*HistogramFloat64Row, len(old))
- copy(data.Rows, old)
- v = *data.Rows[index]
- }
- oldValues := v.Values
- v.Values = make([]int64, len(data.Info.Buckets))
- copy(v.Values, oldValues)
- f(&v)
- data.Rows[index] = &v
- data.EndTime = at
- frozen := *data
- return &frozen
-}
-
-func (data *HistogramFloat64Data) record(at time.Time, lm label.Map, l label.Label) Data {
- return data.modify(at, lm, func(v *HistogramFloat64Row) {
- value := data.key.From(l)
- v.Sum += value
- if v.Min > value || v.Count == 0 {
- v.Min = value
- }
- if v.Max < value || v.Count == 0 {
- v.Max = value
- }
- v.Count++
- for i, b := range data.Info.Buckets {
- if value <= b {
- v.Values[i]++
- }
- }
- })
-}