Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / github.com / prometheus / common / model / value.go
1 // Copyright 2013 The Prometheus Authors
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package model
15
16 import (
17         "encoding/json"
18         "fmt"
19         "math"
20         "sort"
21         "strconv"
22         "strings"
23 )
24
25 var (
26         // ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a
27         // non-existing sample pair. It is a SamplePair with timestamp Earliest and
28         // value 0.0. Note that the natural zero value of SamplePair has a timestamp
29         // of 0, which is possible to appear in a real SamplePair and thus not
30         // suitable to signal a non-existing SamplePair.
31         ZeroSamplePair = SamplePair{Timestamp: Earliest}
32
33         // ZeroSample is the pseudo zero-value of Sample used to signal a
34         // non-existing sample. It is a Sample with timestamp Earliest, value 0.0,
35         // and metric nil. Note that the natural zero value of Sample has a timestamp
36         // of 0, which is possible to appear in a real Sample and thus not suitable
37         // to signal a non-existing Sample.
38         ZeroSample = Sample{Timestamp: Earliest}
39 )
40
41 // A SampleValue is a representation of a value for a given sample at a given
42 // time.
43 type SampleValue float64
44
45 // MarshalJSON implements json.Marshaler.
46 func (v SampleValue) MarshalJSON() ([]byte, error) {
47         return json.Marshal(v.String())
48 }
49
50 // UnmarshalJSON implements json.Unmarshaler.
51 func (v *SampleValue) UnmarshalJSON(b []byte) error {
52         if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
53                 return fmt.Errorf("sample value must be a quoted string")
54         }
55         f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)
56         if err != nil {
57                 return err
58         }
59         *v = SampleValue(f)
60         return nil
61 }
62
63 // Equal returns true if the value of v and o is equal or if both are NaN. Note
64 // that v==o is false if both are NaN. If you want the conventional float
65 // behavior, use == to compare two SampleValues.
66 func (v SampleValue) Equal(o SampleValue) bool {
67         if v == o {
68                 return true
69         }
70         return math.IsNaN(float64(v)) && math.IsNaN(float64(o))
71 }
72
73 func (v SampleValue) String() string {
74         return strconv.FormatFloat(float64(v), 'f', -1, 64)
75 }
76
77 // SamplePair pairs a SampleValue with a Timestamp.
78 type SamplePair struct {
79         Timestamp Time
80         Value     SampleValue
81 }
82
83 // MarshalJSON implements json.Marshaler.
84 func (s SamplePair) MarshalJSON() ([]byte, error) {
85         t, err := json.Marshal(s.Timestamp)
86         if err != nil {
87                 return nil, err
88         }
89         v, err := json.Marshal(s.Value)
90         if err != nil {
91                 return nil, err
92         }
93         return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil
94 }
95
96 // UnmarshalJSON implements json.Unmarshaler.
97 func (s *SamplePair) UnmarshalJSON(b []byte) error {
98         v := [...]json.Unmarshaler{&s.Timestamp, &s.Value}
99         return json.Unmarshal(b, &v)
100 }
101
102 // Equal returns true if this SamplePair and o have equal Values and equal
103 // Timestamps. The semantics of Value equality is defined by SampleValue.Equal.
104 func (s *SamplePair) Equal(o *SamplePair) bool {
105         return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))
106 }
107
108 func (s SamplePair) String() string {
109         return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp)
110 }
111
112 // Sample is a sample pair associated with a metric.
113 type Sample struct {
114         Metric    Metric      `json:"metric"`
115         Value     SampleValue `json:"value"`
116         Timestamp Time        `json:"timestamp"`
117 }
118
119 // Equal compares first the metrics, then the timestamp, then the value. The
120 // semantics of value equality is defined by SampleValue.Equal.
121 func (s *Sample) Equal(o *Sample) bool {
122         if s == o {
123                 return true
124         }
125
126         if !s.Metric.Equal(o.Metric) {
127                 return false
128         }
129         if !s.Timestamp.Equal(o.Timestamp) {
130                 return false
131         }
132
133         return s.Value.Equal(o.Value)
134 }
135
136 func (s Sample) String() string {
137         return fmt.Sprintf("%s => %s", s.Metric, SamplePair{
138                 Timestamp: s.Timestamp,
139                 Value:     s.Value,
140         })
141 }
142
143 // MarshalJSON implements json.Marshaler.
144 func (s Sample) MarshalJSON() ([]byte, error) {
145         v := struct {
146                 Metric Metric     `json:"metric"`
147                 Value  SamplePair `json:"value"`
148         }{
149                 Metric: s.Metric,
150                 Value: SamplePair{
151                         Timestamp: s.Timestamp,
152                         Value:     s.Value,
153                 },
154         }
155
156         return json.Marshal(&v)
157 }
158
159 // UnmarshalJSON implements json.Unmarshaler.
160 func (s *Sample) UnmarshalJSON(b []byte) error {
161         v := struct {
162                 Metric Metric     `json:"metric"`
163                 Value  SamplePair `json:"value"`
164         }{
165                 Metric: s.Metric,
166                 Value: SamplePair{
167                         Timestamp: s.Timestamp,
168                         Value:     s.Value,
169                 },
170         }
171
172         if err := json.Unmarshal(b, &v); err != nil {
173                 return err
174         }
175
176         s.Metric = v.Metric
177         s.Timestamp = v.Value.Timestamp
178         s.Value = v.Value.Value
179
180         return nil
181 }
182
183 // Samples is a sortable Sample slice. It implements sort.Interface.
184 type Samples []*Sample
185
186 func (s Samples) Len() int {
187         return len(s)
188 }
189
190 // Less compares first the metrics, then the timestamp.
191 func (s Samples) Less(i, j int) bool {
192         switch {
193         case s[i].Metric.Before(s[j].Metric):
194                 return true
195         case s[j].Metric.Before(s[i].Metric):
196                 return false
197         case s[i].Timestamp.Before(s[j].Timestamp):
198                 return true
199         default:
200                 return false
201         }
202 }
203
204 func (s Samples) Swap(i, j int) {
205         s[i], s[j] = s[j], s[i]
206 }
207
208 // Equal compares two sets of samples and returns true if they are equal.
209 func (s Samples) Equal(o Samples) bool {
210         if len(s) != len(o) {
211                 return false
212         }
213
214         for i, sample := range s {
215                 if !sample.Equal(o[i]) {
216                         return false
217                 }
218         }
219         return true
220 }
221
222 // SampleStream is a stream of Values belonging to an attached COWMetric.
223 type SampleStream struct {
224         Metric Metric       `json:"metric"`
225         Values []SamplePair `json:"values"`
226 }
227
228 func (ss SampleStream) String() string {
229         vals := make([]string, len(ss.Values))
230         for i, v := range ss.Values {
231                 vals[i] = v.String()
232         }
233         return fmt.Sprintf("%s =>\n%s", ss.Metric, strings.Join(vals, "\n"))
234 }
235
236 // Value is a generic interface for values resulting from a query evaluation.
237 type Value interface {
238         Type() ValueType
239         String() string
240 }
241
242 func (Matrix) Type() ValueType  { return ValMatrix }
243 func (Vector) Type() ValueType  { return ValVector }
244 func (*Scalar) Type() ValueType { return ValScalar }
245 func (*String) Type() ValueType { return ValString }
246
247 type ValueType int
248
249 const (
250         ValNone ValueType = iota
251         ValScalar
252         ValVector
253         ValMatrix
254         ValString
255 )
256
257 // MarshalJSON implements json.Marshaler.
258 func (et ValueType) MarshalJSON() ([]byte, error) {
259         return json.Marshal(et.String())
260 }
261
262 func (et *ValueType) UnmarshalJSON(b []byte) error {
263         var s string
264         if err := json.Unmarshal(b, &s); err != nil {
265                 return err
266         }
267         switch s {
268         case "<ValNone>":
269                 *et = ValNone
270         case "scalar":
271                 *et = ValScalar
272         case "vector":
273                 *et = ValVector
274         case "matrix":
275                 *et = ValMatrix
276         case "string":
277                 *et = ValString
278         default:
279                 return fmt.Errorf("unknown value type %q", s)
280         }
281         return nil
282 }
283
284 func (e ValueType) String() string {
285         switch e {
286         case ValNone:
287                 return "<ValNone>"
288         case ValScalar:
289                 return "scalar"
290         case ValVector:
291                 return "vector"
292         case ValMatrix:
293                 return "matrix"
294         case ValString:
295                 return "string"
296         }
297         panic("ValueType.String: unhandled value type")
298 }
299
300 // Scalar is a scalar value evaluated at the set timestamp.
301 type Scalar struct {
302         Value     SampleValue `json:"value"`
303         Timestamp Time        `json:"timestamp"`
304 }
305
306 func (s Scalar) String() string {
307         return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)
308 }
309
310 // MarshalJSON implements json.Marshaler.
311 func (s Scalar) MarshalJSON() ([]byte, error) {
312         v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)
313         return json.Marshal([...]interface{}{s.Timestamp, string(v)})
314 }
315
316 // UnmarshalJSON implements json.Unmarshaler.
317 func (s *Scalar) UnmarshalJSON(b []byte) error {
318         var f string
319         v := [...]interface{}{&s.Timestamp, &f}
320
321         if err := json.Unmarshal(b, &v); err != nil {
322                 return err
323         }
324
325         value, err := strconv.ParseFloat(f, 64)
326         if err != nil {
327                 return fmt.Errorf("error parsing sample value: %s", err)
328         }
329         s.Value = SampleValue(value)
330         return nil
331 }
332
333 // String is a string value evaluated at the set timestamp.
334 type String struct {
335         Value     string `json:"value"`
336         Timestamp Time   `json:"timestamp"`
337 }
338
339 func (s *String) String() string {
340         return s.Value
341 }
342
343 // MarshalJSON implements json.Marshaler.
344 func (s String) MarshalJSON() ([]byte, error) {
345         return json.Marshal([]interface{}{s.Timestamp, s.Value})
346 }
347
348 // UnmarshalJSON implements json.Unmarshaler.
349 func (s *String) UnmarshalJSON(b []byte) error {
350         v := [...]interface{}{&s.Timestamp, &s.Value}
351         return json.Unmarshal(b, &v)
352 }
353
354 // Vector is basically only an alias for Samples, but the
355 // contract is that in a Vector, all Samples have the same timestamp.
356 type Vector []*Sample
357
358 func (vec Vector) String() string {
359         entries := make([]string, len(vec))
360         for i, s := range vec {
361                 entries[i] = s.String()
362         }
363         return strings.Join(entries, "\n")
364 }
365
366 func (vec Vector) Len() int      { return len(vec) }
367 func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }
368
369 // Less compares first the metrics, then the timestamp.
370 func (vec Vector) Less(i, j int) bool {
371         switch {
372         case vec[i].Metric.Before(vec[j].Metric):
373                 return true
374         case vec[j].Metric.Before(vec[i].Metric):
375                 return false
376         case vec[i].Timestamp.Before(vec[j].Timestamp):
377                 return true
378         default:
379                 return false
380         }
381 }
382
383 // Equal compares two sets of samples and returns true if they are equal.
384 func (vec Vector) Equal(o Vector) bool {
385         if len(vec) != len(o) {
386                 return false
387         }
388
389         for i, sample := range vec {
390                 if !sample.Equal(o[i]) {
391                         return false
392                 }
393         }
394         return true
395 }
396
397 // Matrix is a list of time series.
398 type Matrix []*SampleStream
399
400 func (m Matrix) Len() int           { return len(m) }
401 func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }
402 func (m Matrix) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
403
404 func (mat Matrix) String() string {
405         matCp := make(Matrix, len(mat))
406         copy(matCp, mat)
407         sort.Sort(matCp)
408
409         strs := make([]string, len(matCp))
410
411         for i, ss := range matCp {
412                 strs[i] = ss.String()
413         }
414
415         return strings.Join(strs, "\n")
416 }