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  }