github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/prometheus/common/model/value.go (about) 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 }