cubefs
416 строк · 10.0 Кб
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
14package model15
16import (17"encoding/json"18"fmt"19"math"20"sort"21"strconv"22"strings"23)
24
25var (26// ZeroSamplePair is the pseudo zero-value of SamplePair used to signal a27// non-existing sample pair. It is a SamplePair with timestamp Earliest and28// value 0.0. Note that the natural zero value of SamplePair has a timestamp29// of 0, which is possible to appear in a real SamplePair and thus not30// suitable to signal a non-existing SamplePair.31ZeroSamplePair = SamplePair{Timestamp: Earliest}32
33// ZeroSample is the pseudo zero-value of Sample used to signal a34// 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 timestamp36// of 0, which is possible to appear in a real Sample and thus not suitable37// to signal a non-existing Sample.38ZeroSample = Sample{Timestamp: Earliest}39)
40
41// A SampleValue is a representation of a value for a given sample at a given
42// time.
43type SampleValue float6444
45// MarshalJSON implements json.Marshaler.
46func (v SampleValue) MarshalJSON() ([]byte, error) {47return json.Marshal(v.String())48}
49
50// UnmarshalJSON implements json.Unmarshaler.
51func (v *SampleValue) UnmarshalJSON(b []byte) error {52if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {53return fmt.Errorf("sample value must be a quoted string")54}55f, err := strconv.ParseFloat(string(b[1:len(b)-1]), 64)56if err != nil {57return err58}59*v = SampleValue(f)60return nil61}
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.
66func (v SampleValue) Equal(o SampleValue) bool {67if v == o {68return true69}70return math.IsNaN(float64(v)) && math.IsNaN(float64(o))71}
72
73func (v SampleValue) String() string {74return strconv.FormatFloat(float64(v), 'f', -1, 64)75}
76
77// SamplePair pairs a SampleValue with a Timestamp.
78type SamplePair struct {79Timestamp Time
80Value SampleValue
81}
82
83// MarshalJSON implements json.Marshaler.
84func (s SamplePair) MarshalJSON() ([]byte, error) {85t, err := json.Marshal(s.Timestamp)86if err != nil {87return nil, err88}89v, err := json.Marshal(s.Value)90if err != nil {91return nil, err92}93return []byte(fmt.Sprintf("[%s,%s]", t, v)), nil94}
95
96// UnmarshalJSON implements json.Unmarshaler.
97func (s *SamplePair) UnmarshalJSON(b []byte) error {98v := [...]json.Unmarshaler{&s.Timestamp, &s.Value}99return 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.
104func (s *SamplePair) Equal(o *SamplePair) bool {105return s == o || (s.Value.Equal(o.Value) && s.Timestamp.Equal(o.Timestamp))106}
107
108func (s SamplePair) String() string {109return fmt.Sprintf("%s @[%s]", s.Value, s.Timestamp)110}
111
112// Sample is a sample pair associated with a metric.
113type Sample struct {114Metric Metric `json:"metric"`115Value SampleValue `json:"value"`116Timestamp 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.
121func (s *Sample) Equal(o *Sample) bool {122if s == o {123return true124}125
126if !s.Metric.Equal(o.Metric) {127return false128}129if !s.Timestamp.Equal(o.Timestamp) {130return false131}132
133return s.Value.Equal(o.Value)134}
135
136func (s Sample) String() string {137return fmt.Sprintf("%s => %s", s.Metric, SamplePair{138Timestamp: s.Timestamp,139Value: s.Value,140})141}
142
143// MarshalJSON implements json.Marshaler.
144func (s Sample) MarshalJSON() ([]byte, error) {145v := struct {146Metric Metric `json:"metric"`147Value SamplePair `json:"value"`148}{149Metric: s.Metric,150Value: SamplePair{151Timestamp: s.Timestamp,152Value: s.Value,153},154}155
156return json.Marshal(&v)157}
158
159// UnmarshalJSON implements json.Unmarshaler.
160func (s *Sample) UnmarshalJSON(b []byte) error {161v := struct {162Metric Metric `json:"metric"`163Value SamplePair `json:"value"`164}{165Metric: s.Metric,166Value: SamplePair{167Timestamp: s.Timestamp,168Value: s.Value,169},170}171
172if err := json.Unmarshal(b, &v); err != nil {173return err174}175
176s.Metric = v.Metric177s.Timestamp = v.Value.Timestamp178s.Value = v.Value.Value179
180return nil181}
182
183// Samples is a sortable Sample slice. It implements sort.Interface.
184type Samples []*Sample185
186func (s Samples) Len() int {187return len(s)188}
189
190// Less compares first the metrics, then the timestamp.
191func (s Samples) Less(i, j int) bool {192switch {193case s[i].Metric.Before(s[j].Metric):194return true195case s[j].Metric.Before(s[i].Metric):196return false197case s[i].Timestamp.Before(s[j].Timestamp):198return true199default:200return false201}202}
203
204func (s Samples) Swap(i, j int) {205s[i], s[j] = s[j], s[i]206}
207
208// Equal compares two sets of samples and returns true if they are equal.
209func (s Samples) Equal(o Samples) bool {210if len(s) != len(o) {211return false212}213
214for i, sample := range s {215if !sample.Equal(o[i]) {216return false217}218}219return true220}
221
222// SampleStream is a stream of Values belonging to an attached COWMetric.
223type SampleStream struct {224Metric Metric `json:"metric"`225Values []SamplePair `json:"values"`226}
227
228func (ss SampleStream) String() string {229vals := make([]string, len(ss.Values))230for i, v := range ss.Values {231vals[i] = v.String()232}233return 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.
237type Value interface {238Type() ValueType239String() string240}
241
242func (Matrix) Type() ValueType { return ValMatrix }243func (Vector) Type() ValueType { return ValVector }244func (*Scalar) Type() ValueType { return ValScalar }245func (*String) Type() ValueType { return ValString }246
247type ValueType int248
249const (250ValNone ValueType = iota251ValScalar
252ValVector
253ValMatrix
254ValString
255)
256
257// MarshalJSON implements json.Marshaler.
258func (et ValueType) MarshalJSON() ([]byte, error) {259return json.Marshal(et.String())260}
261
262func (et *ValueType) UnmarshalJSON(b []byte) error {263var s string264if err := json.Unmarshal(b, &s); err != nil {265return err266}267switch s {268case "<ValNone>":269*et = ValNone270case "scalar":271*et = ValScalar272case "vector":273*et = ValVector274case "matrix":275*et = ValMatrix276case "string":277*et = ValString278default:279return fmt.Errorf("unknown value type %q", s)280}281return nil282}
283
284func (e ValueType) String() string {285switch e {286case ValNone:287return "<ValNone>"288case ValScalar:289return "scalar"290case ValVector:291return "vector"292case ValMatrix:293return "matrix"294case ValString:295return "string"296}297panic("ValueType.String: unhandled value type")298}
299
300// Scalar is a scalar value evaluated at the set timestamp.
301type Scalar struct {302Value SampleValue `json:"value"`303Timestamp Time `json:"timestamp"`304}
305
306func (s Scalar) String() string {307return fmt.Sprintf("scalar: %v @[%v]", s.Value, s.Timestamp)308}
309
310// MarshalJSON implements json.Marshaler.
311func (s Scalar) MarshalJSON() ([]byte, error) {312v := strconv.FormatFloat(float64(s.Value), 'f', -1, 64)313return json.Marshal([...]interface{}{s.Timestamp, string(v)})314}
315
316// UnmarshalJSON implements json.Unmarshaler.
317func (s *Scalar) UnmarshalJSON(b []byte) error {318var f string319v := [...]interface{}{&s.Timestamp, &f}320
321if err := json.Unmarshal(b, &v); err != nil {322return err323}324
325value, err := strconv.ParseFloat(f, 64)326if err != nil {327return fmt.Errorf("error parsing sample value: %s", err)328}329s.Value = SampleValue(value)330return nil331}
332
333// String is a string value evaluated at the set timestamp.
334type String struct {335Value string `json:"value"`336Timestamp Time `json:"timestamp"`337}
338
339func (s *String) String() string {340return s.Value341}
342
343// MarshalJSON implements json.Marshaler.
344func (s String) MarshalJSON() ([]byte, error) {345return json.Marshal([]interface{}{s.Timestamp, s.Value})346}
347
348// UnmarshalJSON implements json.Unmarshaler.
349func (s *String) UnmarshalJSON(b []byte) error {350v := [...]interface{}{&s.Timestamp, &s.Value}351return 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.
356type Vector []*Sample357
358func (vec Vector) String() string {359entries := make([]string, len(vec))360for i, s := range vec {361entries[i] = s.String()362}363return strings.Join(entries, "\n")364}
365
366func (vec Vector) Len() int { return len(vec) }367func (vec Vector) Swap(i, j int) { vec[i], vec[j] = vec[j], vec[i] }368
369// Less compares first the metrics, then the timestamp.
370func (vec Vector) Less(i, j int) bool {371switch {372case vec[i].Metric.Before(vec[j].Metric):373return true374case vec[j].Metric.Before(vec[i].Metric):375return false376case vec[i].Timestamp.Before(vec[j].Timestamp):377return true378default:379return false380}381}
382
383// Equal compares two sets of samples and returns true if they are equal.
384func (vec Vector) Equal(o Vector) bool {385if len(vec) != len(o) {386return false387}388
389for i, sample := range vec {390if !sample.Equal(o[i]) {391return false392}393}394return true395}
396
397// Matrix is a list of time series.
398type Matrix []*SampleStream399
400func (m Matrix) Len() int { return len(m) }401func (m Matrix) Less(i, j int) bool { return m[i].Metric.Before(m[j].Metric) }402func (m Matrix) Swap(i, j int) { m[i], m[j] = m[j], m[i] }403
404func (mat Matrix) String() string {405matCp := make(Matrix, len(mat))406copy(matCp, mat)407sort.Sort(matCp)408
409strs := make([]string, len(matCp))410
411for i, ss := range matCp {412strs[i] = ss.String()413}414
415return strings.Join(strs, "\n")416}
417