Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / internal / event / export / metric / data.go
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.
4
5 package metric
6
7 import (
8         "fmt"
9         "sort"
10         "time"
11
12         "golang.org/x/tools/internal/event/keys"
13         "golang.org/x/tools/internal/event/label"
14 )
15
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
18 // format.
19 // To get the actual values for the metric you must type assert to a concrete
20 // metric type.
21 type Data interface {
22         // Handle returns the metric handle this data is for.
23         //TODO: rethink the concept of metric handles
24         Handle() string
25         // Groups reports the rows that currently exist for this metric.
26         Groups() [][]label.Label
27 }
28
29 // Int64Data is a concrete implementation of Data for int64 scalar metrics.
30 type Int64Data struct {
31         // Info holds the original construction information.
32         Info *Scalar
33         // IsGauge is true for metrics that track values, rather than increasing over time.
34         IsGauge bool
35         // Rows holds the per group values for the metric.
36         Rows []int64
37         // End is the last time this metric was updated.
38         EndTime time.Time
39
40         groups [][]label.Label
41         key    *keys.Int64
42 }
43
44 // Float64Data is a concrete implementation of Data for float64 scalar metrics.
45 type Float64Data struct {
46         // Info holds the original construction information.
47         Info *Scalar
48         // IsGauge is true for metrics that track values, rather than increasing over time.
49         IsGauge bool
50         // Rows holds the per group values for the metric.
51         Rows []float64
52         // End is the last time this metric was updated.
53         EndTime time.Time
54
55         groups [][]label.Label
56         key    *keys.Float64
57 }
58
59 // HistogramInt64Data is a concrete implementation of Data for int64 histogram metrics.
60 type HistogramInt64Data struct {
61         // Info holds the original construction information.
62         Info *HistogramInt64
63         // Rows holds the per group values for the metric.
64         Rows []*HistogramInt64Row
65         // End is the last time this metric was updated.
66         EndTime time.Time
67
68         groups [][]label.Label
69         key    *keys.Int64
70 }
71
72 // HistogramInt64Row holds the values for a single row of a HistogramInt64Data.
73 type HistogramInt64Row struct {
74         // Values is the counts per bucket.
75         Values []int64
76         // Count is the total count.
77         Count int64
78         // Sum is the sum of all the values recorded.
79         Sum int64
80         // Min is the smallest recorded value.
81         Min int64
82         // Max is the largest recorded value.
83         Max int64
84 }
85
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.
93         EndTime time.Time
94
95         groups [][]label.Label
96         key    *keys.Float64
97 }
98
99 // HistogramFloat64Row holds the values for a single row of a HistogramFloat64Data.
100 type HistogramFloat64Row struct {
101         // Values is the counts per bucket.
102         Values []int64
103         // Count is the total count.
104         Count int64
105         // Sum is the sum of all the values recorded.
106         Sum float64
107         // Min is the smallest recorded value.
108         Min float64
109         // Max is the largest recorded value.
110         Max float64
111 }
112
113 func labelListEqual(a, b []label.Label) bool {
114         //TODO: make this more efficient
115         return fmt.Sprint(a) == fmt.Sprint(b)
116 }
117
118 func labelListLess(a, b []label.Label) bool {
119         //TODO: make this more efficient
120         return fmt.Sprint(a) < fmt.Sprint(b)
121 }
122
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 {
126                 l := lm.Find(key)
127                 if l.Valid() {
128                         group[i] = l
129                 }
130         }
131         old := *g
132         index := sort.Search(len(old), func(i int) bool {
133                 return !labelListLess(old[i], group)
134         })
135         if index < len(old) && labelListEqual(group, old[index]) {
136                 // not a new group
137                 return index, false
138         }
139         *g = make([][]label.Label, len(old)+1)
140         copy(*g, old[:index])
141         copy((*g)[index+1:], old[index:])
142         (*g)[index] = group
143         return index, true
144 }
145
146 func (data *Int64Data) Handle() string          { return data.Info.Name }
147 func (data *Int64Data) Groups() [][]label.Label { return data.groups }
148
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)
151         old := data.Rows
152         if insert {
153                 data.Rows = make([]int64, len(old)+1)
154                 copy(data.Rows, old[:index])
155                 copy(data.Rows[index+1:], old[index:])
156         } else {
157                 data.Rows = make([]int64, len(old))
158                 copy(data.Rows, old)
159         }
160         data.Rows[index] = f(data.Rows[index])
161         data.EndTime = at
162         frozen := *data
163         return &frozen
164 }
165
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 {
168                 return v + 1
169         })
170 }
171
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)
175         })
176 }
177
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)
181         })
182 }
183
184 func (data *Float64Data) Handle() string          { return data.Info.Name }
185 func (data *Float64Data) Groups() [][]label.Label { return data.groups }
186
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)
189         old := data.Rows
190         if insert {
191                 data.Rows = make([]float64, len(old)+1)
192                 copy(data.Rows, old[:index])
193                 copy(data.Rows[index+1:], old[index:])
194         } else {
195                 data.Rows = make([]float64, len(old))
196                 copy(data.Rows, old)
197         }
198         data.Rows[index] = f(data.Rows[index])
199         data.EndTime = at
200         frozen := *data
201         return &frozen
202 }
203
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)
207         })
208 }
209
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)
213         })
214 }
215
216 func (data *HistogramInt64Data) Handle() string          { return data.Info.Name }
217 func (data *HistogramInt64Data) Groups() [][]label.Label { return data.groups }
218
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)
221         old := data.Rows
222         var v HistogramInt64Row
223         if insert {
224                 data.Rows = make([]*HistogramInt64Row, len(old)+1)
225                 copy(data.Rows, old[:index])
226                 copy(data.Rows[index+1:], old[index:])
227         } else {
228                 data.Rows = make([]*HistogramInt64Row, len(old))
229                 copy(data.Rows, old)
230                 v = *data.Rows[index]
231         }
232         oldValues := v.Values
233         v.Values = make([]int64, len(data.Info.Buckets))
234         copy(v.Values, oldValues)
235         f(&v)
236         data.Rows[index] = &v
237         data.EndTime = at
238         frozen := *data
239         return &frozen
240 }
241
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)
245                 v.Sum += value
246                 if v.Min > value || v.Count == 0 {
247                         v.Min = value
248                 }
249                 if v.Max < value || v.Count == 0 {
250                         v.Max = value
251                 }
252                 v.Count++
253                 for i, b := range data.Info.Buckets {
254                         if value <= b {
255                                 v.Values[i]++
256                         }
257                 }
258         })
259 }
260
261 func (data *HistogramFloat64Data) Handle() string          { return data.Info.Name }
262 func (data *HistogramFloat64Data) Groups() [][]label.Label { return data.groups }
263
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)
266         old := data.Rows
267         var v HistogramFloat64Row
268         if insert {
269                 data.Rows = make([]*HistogramFloat64Row, len(old)+1)
270                 copy(data.Rows, old[:index])
271                 copy(data.Rows[index+1:], old[index:])
272         } else {
273                 data.Rows = make([]*HistogramFloat64Row, len(old))
274                 copy(data.Rows, old)
275                 v = *data.Rows[index]
276         }
277         oldValues := v.Values
278         v.Values = make([]int64, len(data.Info.Buckets))
279         copy(v.Values, oldValues)
280         f(&v)
281         data.Rows[index] = &v
282         data.EndTime = at
283         frozen := *data
284         return &frozen
285 }
286
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)
290                 v.Sum += value
291                 if v.Min > value || v.Count == 0 {
292                         v.Min = value
293                 }
294                 if v.Max < value || v.Count == 0 {
295                         v.Max = value
296                 }
297                 v.Count++
298                 for i, b := range data.Info.Buckets {
299                         if value <= b {
300                                 v.Values[i]++
301                         }
302                 }
303         })
304 }