cubefs
169 строк · 4.2 Кб
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"sort"20"strings"21)
22
23// A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet
24// may be fully-qualified down to the point where it may resolve to a single
25// Metric in the data store or not. All operations that occur within the realm
26// of a LabelSet can emit a vector of Metric entities to which the LabelSet may
27// match.
28type LabelSet map[LabelName]LabelValue29
30// Validate checks whether all names and values in the label set
31// are valid.
32func (ls LabelSet) Validate() error {33for ln, lv := range ls {34if !ln.IsValid() {35return fmt.Errorf("invalid name %q", ln)36}37if !lv.IsValid() {38return fmt.Errorf("invalid value %q", lv)39}40}41return nil42}
43
44// Equal returns true iff both label sets have exactly the same key/value pairs.
45func (ls LabelSet) Equal(o LabelSet) bool {46if len(ls) != len(o) {47return false48}49for ln, lv := range ls {50olv, ok := o[ln]51if !ok {52return false53}54if olv != lv {55return false56}57}58return true59}
60
61// Before compares the metrics, using the following criteria:
62//
63// If m has fewer labels than o, it is before o. If it has more, it is not.
64//
65// If the number of labels is the same, the superset of all label names is
66// sorted alphanumerically. The first differing label pair found in that order
67// determines the outcome: If the label does not exist at all in m, then m is
68// before o, and vice versa. Otherwise the label value is compared
69// alphanumerically.
70//
71// If m and o are equal, the method returns false.
72func (ls LabelSet) Before(o LabelSet) bool {73if len(ls) < len(o) {74return true75}76if len(ls) > len(o) {77return false78}79
80lns := make(LabelNames, 0, len(ls)+len(o))81for ln := range ls {82lns = append(lns, ln)83}84for ln := range o {85lns = append(lns, ln)86}87// It's probably not worth it to de-dup lns.88sort.Sort(lns)89for _, ln := range lns {90mlv, ok := ls[ln]91if !ok {92return true93}94olv, ok := o[ln]95if !ok {96return false97}98if mlv < olv {99return true100}101if mlv > olv {102return false103}104}105return false106}
107
108// Clone returns a copy of the label set.
109func (ls LabelSet) Clone() LabelSet {110lsn := make(LabelSet, len(ls))111for ln, lv := range ls {112lsn[ln] = lv113}114return lsn115}
116
117// Merge is a helper function to non-destructively merge two label sets.
118func (l LabelSet) Merge(other LabelSet) LabelSet {119result := make(LabelSet, len(l))120
121for k, v := range l {122result[k] = v123}124
125for k, v := range other {126result[k] = v127}128
129return result130}
131
132func (l LabelSet) String() string {133lstrs := make([]string, 0, len(l))134for l, v := range l {135lstrs = append(lstrs, fmt.Sprintf("%s=%q", l, v))136}137
138sort.Strings(lstrs)139return fmt.Sprintf("{%s}", strings.Join(lstrs, ", "))140}
141
142// Fingerprint returns the LabelSet's fingerprint.
143func (ls LabelSet) Fingerprint() Fingerprint {144return labelSetToFingerprint(ls)145}
146
147// FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing
148// algorithm, which is, however, more susceptible to hash collisions.
149func (ls LabelSet) FastFingerprint() Fingerprint {150return labelSetToFastFingerprint(ls)151}
152
153// UnmarshalJSON implements the json.Unmarshaler interface.
154func (l *LabelSet) UnmarshalJSON(b []byte) error {155var m map[LabelName]LabelValue156if err := json.Unmarshal(b, &m); err != nil {157return err158}159// encoding/json only unmarshals maps of the form map[string]T. It treats160// LabelName as a string and does not call its UnmarshalJSON method.161// Thus, we have to replicate the behavior here.162for ln := range m {163if !ln.IsValid() {164return fmt.Errorf("%q is not a valid label name", ln)165}166}167*l = LabelSet(m)168return nil169}
170