1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
12 "golang.org/x/tools/internal/event/keys"
13 "golang.org/x/tools/internal/event/label"
16 // Data represents a single point in the time series of a metric.
17 // This provides the common interface to all metrics no matter their data
19 // To get the actual values for the metric you must type assert to a concrete
22 // Handle returns the metric handle this data is for.
23 //TODO: rethink the concept of metric handles
25 // Groups reports the rows that currently exist for this metric.
26 Groups() [][]label.Label
29 // Int64Data is a concrete implementation of Data for int64 scalar metrics.
30 type Int64Data struct {
31 // Info holds the original construction information.
33 // IsGauge is true for metrics that track values, rather than increasing over time.
35 // Rows holds the per group values for the metric.
37 // End is the last time this metric was updated.
40 groups [][]label.Label
44 // Float64Data is a concrete implementation of Data for float64 scalar metrics.
45 type Float64Data struct {
46 // Info holds the original construction information.
48 // IsGauge is true for metrics that track values, rather than increasing over time.
50 // Rows holds the per group values for the metric.
52 // End is the last time this metric was updated.
55 groups [][]label.Label
59 // HistogramInt64Data is a concrete implementation of Data for int64 histogram metrics.
60 type HistogramInt64Data struct {
61 // Info holds the original construction information.
63 // Rows holds the per group values for the metric.
64 Rows []*HistogramInt64Row
65 // End is the last time this metric was updated.
68 groups [][]label.Label
72 // HistogramInt64Row holds the values for a single row of a HistogramInt64Data.
73 type HistogramInt64Row struct {
74 // Values is the counts per bucket.
76 // Count is the total count.
78 // Sum is the sum of all the values recorded.
80 // Min is the smallest recorded value.
82 // Max is the largest recorded value.
86 // HistogramFloat64Data is a concrete implementation of Data for float64 histogram metrics.
87 type HistogramFloat64Data struct {
88 // Info holds the original construction information.
89 Info *HistogramFloat64
90 // Rows holds the per group values for the metric.
91 Rows []*HistogramFloat64Row
92 // End is the last time this metric was updated.
95 groups [][]label.Label
99 // HistogramFloat64Row holds the values for a single row of a HistogramFloat64Data.
100 type HistogramFloat64Row struct {
101 // Values is the counts per bucket.
103 // Count is the total count.
105 // Sum is the sum of all the values recorded.
107 // Min is the smallest recorded value.
109 // Max is the largest recorded value.
113 func labelListEqual(a, b []label.Label) bool {
114 //TODO: make this more efficient
115 return fmt.Sprint(a) == fmt.Sprint(b)
118 func labelListLess(a, b []label.Label) bool {
119 //TODO: make this more efficient
120 return fmt.Sprint(a) < fmt.Sprint(b)
123 func getGroup(lm label.Map, g *[][]label.Label, keys []label.Key) (int, bool) {
124 group := make([]label.Label, len(keys))
125 for i, key := range keys {
132 index := sort.Search(len(old), func(i int) bool {
133 return !labelListLess(old[i], group)
135 if index < len(old) && labelListEqual(group, old[index]) {
139 *g = make([][]label.Label, len(old)+1)
140 copy(*g, old[:index])
141 copy((*g)[index+1:], old[index:])
146 func (data *Int64Data) Handle() string { return data.Info.Name }
147 func (data *Int64Data) Groups() [][]label.Label { return data.groups }
149 func (data *Int64Data) modify(at time.Time, lm label.Map, f func(v int64) int64) Data {
150 index, insert := getGroup(lm, &data.groups, data.Info.Keys)
153 data.Rows = make([]int64, len(old)+1)
154 copy(data.Rows, old[:index])
155 copy(data.Rows[index+1:], old[index:])
157 data.Rows = make([]int64, len(old))
160 data.Rows[index] = f(data.Rows[index])
166 func (data *Int64Data) count(at time.Time, lm label.Map, l label.Label) Data {
167 return data.modify(at, lm, func(v int64) int64 {
172 func (data *Int64Data) sum(at time.Time, lm label.Map, l label.Label) Data {
173 return data.modify(at, lm, func(v int64) int64 {
174 return v + data.key.From(l)
178 func (data *Int64Data) latest(at time.Time, lm label.Map, l label.Label) Data {
179 return data.modify(at, lm, func(v int64) int64 {
180 return data.key.From(l)
184 func (data *Float64Data) Handle() string { return data.Info.Name }
185 func (data *Float64Data) Groups() [][]label.Label { return data.groups }
187 func (data *Float64Data) modify(at time.Time, lm label.Map, f func(v float64) float64) Data {
188 index, insert := getGroup(lm, &data.groups, data.Info.Keys)
191 data.Rows = make([]float64, len(old)+1)
192 copy(data.Rows, old[:index])
193 copy(data.Rows[index+1:], old[index:])
195 data.Rows = make([]float64, len(old))
198 data.Rows[index] = f(data.Rows[index])
204 func (data *Float64Data) sum(at time.Time, lm label.Map, l label.Label) Data {
205 return data.modify(at, lm, func(v float64) float64 {
206 return v + data.key.From(l)
210 func (data *Float64Data) latest(at time.Time, lm label.Map, l label.Label) Data {
211 return data.modify(at, lm, func(v float64) float64 {
212 return data.key.From(l)
216 func (data *HistogramInt64Data) Handle() string { return data.Info.Name }
217 func (data *HistogramInt64Data) Groups() [][]label.Label { return data.groups }
219 func (data *HistogramInt64Data) modify(at time.Time, lm label.Map, f func(v *HistogramInt64Row)) Data {
220 index, insert := getGroup(lm, &data.groups, data.Info.Keys)
222 var v HistogramInt64Row
224 data.Rows = make([]*HistogramInt64Row, len(old)+1)
225 copy(data.Rows, old[:index])
226 copy(data.Rows[index+1:], old[index:])
228 data.Rows = make([]*HistogramInt64Row, len(old))
230 v = *data.Rows[index]
232 oldValues := v.Values
233 v.Values = make([]int64, len(data.Info.Buckets))
234 copy(v.Values, oldValues)
236 data.Rows[index] = &v
242 func (data *HistogramInt64Data) record(at time.Time, lm label.Map, l label.Label) Data {
243 return data.modify(at, lm, func(v *HistogramInt64Row) {
244 value := data.key.From(l)
246 if v.Min > value || v.Count == 0 {
249 if v.Max < value || v.Count == 0 {
253 for i, b := range data.Info.Buckets {
261 func (data *HistogramFloat64Data) Handle() string { return data.Info.Name }
262 func (data *HistogramFloat64Data) Groups() [][]label.Label { return data.groups }
264 func (data *HistogramFloat64Data) modify(at time.Time, lm label.Map, f func(v *HistogramFloat64Row)) Data {
265 index, insert := getGroup(lm, &data.groups, data.Info.Keys)
267 var v HistogramFloat64Row
269 data.Rows = make([]*HistogramFloat64Row, len(old)+1)
270 copy(data.Rows, old[:index])
271 copy(data.Rows[index+1:], old[index:])
273 data.Rows = make([]*HistogramFloat64Row, len(old))
275 v = *data.Rows[index]
277 oldValues := v.Values
278 v.Values = make([]int64, len(data.Info.Buckets))
279 copy(v.Values, oldValues)
281 data.Rows[index] = &v
287 func (data *HistogramFloat64Data) record(at time.Time, lm label.Map, l label.Label) Data {
288 return data.modify(at, lm, func(v *HistogramFloat64Row) {
289 value := data.key.From(l)
291 if v.Min > value || v.Count == 0 {
294 if v.Max < value || v.Count == 0 {
298 for i, b := range data.Info.Buckets {