1
2
3
4
5
6
7
8
9
10
11
12
13
14 package model
15
16 import (
17 "encoding/json"
18 "fmt"
19 "sort"
20 "strconv"
21 "strings"
22 )
23
24
25
26
27
28
29 var ZeroSample = Sample{Timestamp: Earliest}
30
31
32
33
34 type Sample struct {
35 Metric Metric `json:"metric"`
36 Value SampleValue `json:"value"`
37 Timestamp Time `json:"timestamp"`
38 Histogram *SampleHistogram `json:"histogram"`
39 }
40
41
42
43 func (s *Sample) Equal(o *Sample) bool {
44 if s == o {
45 return true
46 }
47
48 if !s.Metric.Equal(o.Metric) {
49 return false
50 }
51 if !s.Timestamp.Equal(o.Timestamp) {
52 return false
53 }
54 if s.Histogram != nil {
55 return s.Histogram.Equal(o.Histogram)
56 }
57 return s.Value.Equal(o.Value)
58 }
59
60 func (s Sample) String() string {
61 if s.Histogram != nil {
62 return fmt.Sprintf("%s => %s", s.Metric, SampleHistogramPair{
63 Timestamp: s.Timestamp,
64 Histogram: s.Histogram,
65 })
66 }
67 return fmt.Sprintf("%s => %s", s.Metric, SamplePair{
68 Timestamp: s.Timestamp,
69 Value: s.Value,
70 })
71 }
72
73
74 func (s Sample) MarshalJSON() ([]byte, error) {
75 if s.Histogram != nil {
76 v := struct {
77 Metric Metric `json:"metric"`
78 Histogram SampleHistogramPair `json:"histogram"`
79 }{
80 Metric: s.Metric,
81 Histogram: SampleHistogramPair{
82 Timestamp: s.Timestamp,
83 Histogram: s.Histogram,
84 },
85 }
86 return json.Marshal(&v)
87 }
88 v := struct {
89 Metric Metric `json:"metric"`
90 Value SamplePair `json:"value"`
91 }{
92 Metric: s.Metric,
93 Value: SamplePair{
94 Timestamp: s.Timestamp,
95 Value: s.Value,
96 },
97 }
98 return json.Marshal(&v)
99 }
100
101
102 func (s *Sample) UnmarshalJSON(b []byte) error {
103 v := struct {
104 Metric Metric `json:"metric"`
105 Value SamplePair `json:"value"`
106 Histogram SampleHistogramPair `json:"histogram"`
107 }{
108 Metric: s.Metric,
109 Value: SamplePair{
110 Timestamp: s.Timestamp,
111 Value: s.Value,
112 },
113 Histogram: SampleHistogramPair{
114 Timestamp: s.Timestamp,
115 Histogram: s.Histogram,
116 },
117 }
118
119 if err := json.Unmarshal(b, &v); err != nil {
120 return err
121 }
122
123 s.Metric = v.Metric
124 if v.Histogram.Histogram != nil {
125 s.Timestamp = v.Histogram.Timestamp
126 s.Histogram = v.Histogram.Histogram
127 } else {
128 s.Timestamp = v.Value.Timestamp
129 s.Value = v.Value.Value
130 }
131
132 return nil
133 }
134
135
136 type Samples []*Sample
137
138 func (s Samples) Len() int {
139 return len(s)
140 }
141
142
143 func (s Samples) Less(i, j int) bool {
144 switch {
145 case s[i].Metric.Before(s[j].Metric):
146 return true
147 case s[j].Metric.Before(s[i].Metric):
148 return false
149 case s[i].Timestamp.Before(s[j].Timestamp):
150 return true
151 default:
152 return false
153 }
154 }
155
156 func (s Samples) Swap(i, j int) {
157 s[i], s[j] = s[j], s[i]
158 }
159
160
161 func (s Samples) Equal(o Samples) bool {
162 if len(s) != len(o) {
163 return false
164 }
165
166 for i, sample := range s {
167 if !sample.Equal(o[i]) {
168 return false
169 }
170 }
171 return true
172 }
173
174
175 type SampleStream struct {
176 Metric Metric `json:"metric"`
177 Values []SamplePair `json:"values"`
178 Histograms []SampleHistogramPair `json:"histograms"`
179 }
180
181 func (ss SampleStream) String() string {
182 valuesLength := len(ss.Values)
183 vals := make([]string, valuesLength+len(ss.Histograms))
184 for i, v := range ss.Values {
185 vals[i] = v.String()
186 }
187 for i, v := range ss.Histograms {
188 vals[i+valuesLength] = v.String()
189 }
190 return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n"))
191 }
192
193 func (ss SampleStream) MarshalJSON() ([]byte, error) {
194 if len(ss.Histograms) > 0 && len(ss.Values) > 0 {
195 v := struct {
196 Metric Metric `json:"metric"`
197 Values []SamplePair `json:"values"`
198 Histograms []SampleHistogramPair `json:"histograms"`
199 }{
200 Metric: ss.Metric,
201 Values: ss.Values,
202 Histograms: ss.Histograms,
203 }
204 return json.Marshal(&v)
205 } else if len(ss.Histograms) > 0 {
206 v := struct {
207 Metric Metric `json:"metric"`
208 Histograms []SampleHistogramPair `json:"histograms"`
209 }{
210 Metric: ss.Metric,
211 Histograms: ss.Histograms,
212 }
213 return json.Marshal(&v)
214 } else {
215 v := struct {
216 Metric Metric `json:"metric"`
217 Values []SamplePair `json:"values"`
218 }{
219 Metric: ss.Metric,
220 Values: ss.Values,
221 }
222 return json.Marshal(&v)
223 }
224 }
225
226 func (ss *SampleStream) UnmarshalJSON(b []byte) error {
227 v := struct {
228 Metric Metric `json:"metric"`
229 Values []SamplePair `json:"values"`
230 Histograms []SampleHistogramPair `json:"histograms"`
231 }{
232 Metric: ss.Metric,
233 Values: ss.Values,
234 Histograms: ss.Histograms,
235 }
236
237 if err := json.Unmarshal(b, &v); err != nil {
238 return err
239 }
240
241 ss.Metric = v.Metric
242 ss.Values = v.Values
243 ss.Histograms = v.Histograms
244
245 return nil
246 }
247
248
249 type Scalar struct {
250 Value SampleValue `json:"value"`
251 Timestamp Time `json:"timestamp"`
252 }
253
254 func (s Scalar) String() string {
255 return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)
256 }
257
258
259 func (s Scalar) MarshalJSON() ([]byte, error) {
260 v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)
261 return json.Marshal([...]interface{}{s.Timestamp, string(v)})
262 }
263
264
265 func (s *Scalar) UnmarshalJSON(b []byte) error {
266 var f string
267 v := [...]interface{}{&s.Timestamp, &f}
268
269 if err := json.Unmarshal(b, &v); err != nil {
270 return err
271 }
272
273 value, err := strconv.ParseFloat(f, 64)
274 if err != nil {
275 return fmt.Errorf("error parsing sample value: %w", err)
276 }
277 s.Value = SampleValue(value)
278 return nil
279 }
280
281
282 type String struct {
283 Value string `json:"value"`
284 Timestamp Time `json:"timestamp"`
285 }
286
287 func (s *String) String() string {
288 return s.Value
289 }
290
291
292 func (s String) MarshalJSON() ([]byte, error) {
293 return json.Marshal([]interface{}{s.Timestamp, s.Value})
294 }
295
296
297 func (s *String) UnmarshalJSON(b []byte) error {
298 v := [...]interface{}{&s.Timestamp, &s.Value}
299 return json.Unmarshal(b, &v)
300 }
301
302
303
304 type Vector []*Sample
305
306 func (vec Vector) String() string {
307 entries := make([]string, len(vec))
308 for i, s := range vec {
309 entries[i] = s.String()
310 }
311 return strings.Join(entries, "\n")
312 }
313
314 func (vec Vector) Len() int { return len(vec) }
315 func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
316
317
318 func (vec Vector) Less(i, j int) bool {
319 switch {
320 case vec[i].Metric.Before(vec[j].Metric):
321 return true
322 case vec[j].Metric.Before(vec[i].Metric):
323 return false
324 case vec[i].Timestamp.Before(vec[j].Timestamp):
325 return true
326 default:
327 return false
328 }
329 }
330
331
332 func (vec Vector) Equal(o Vector) bool {
333 if len(vec) != len(o) {
334 return false
335 }
336
337 for i, sample := range vec {
338 if !sample.Equal(o[i]) {
339 return false
340 }
341 }
342 return true
343 }
344
345
346 type Matrix []*SampleStream
347
348 func (m Matrix) Len() int { return len(m) }
349 func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }
350 func (m Matrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] }
351
352 func (mat Matrix) String() string {
353 matCp := make(Matrix, len(mat))
354 copy(matCp, mat)
355 sort.Sort(matCp)
356
357 strs := make([]string, len(matCp))
358
359 for i, ss := range matCp {
360 strs[i] = ss.String()
361 }
362
363 return strings.Join(strs, "\n")
364 }
365
View as plain text