labelset.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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. package model
  14. import (
  15. "encoding/json"
  16. "fmt"
  17. "sort"
  18. )
  19. // A LabelSet is a collection of LabelName and LabelValue pairs. The LabelSet
  20. // may be fully-qualified down to the point where it may resolve to a single
  21. // Metric in the data store or not. All operations that occur within the realm
  22. // of a LabelSet can emit a vector of Metric entities to which the LabelSet may
  23. // match.
  24. type LabelSet map[LabelName]LabelValue
  25. // Validate checks whether all names and values in the label set
  26. // are valid.
  27. func (ls LabelSet) Validate() error {
  28. for ln, lv := range ls {
  29. if !ln.IsValid() {
  30. return fmt.Errorf("invalid name %q", ln)
  31. }
  32. if !lv.IsValid() {
  33. return fmt.Errorf("invalid value %q", lv)
  34. }
  35. }
  36. return nil
  37. }
  38. // Equal returns true iff both label sets have exactly the same key/value pairs.
  39. func (ls LabelSet) Equal(o LabelSet) bool {
  40. if len(ls) != len(o) {
  41. return false
  42. }
  43. for ln, lv := range ls {
  44. olv, ok := o[ln]
  45. if !ok {
  46. return false
  47. }
  48. if olv != lv {
  49. return false
  50. }
  51. }
  52. return true
  53. }
  54. // Before compares the metrics, using the following criteria:
  55. //
  56. // If m has fewer labels than o, it is before o. If it has more, it is not.
  57. //
  58. // If the number of labels is the same, the superset of all label names is
  59. // sorted alphanumerically. The first differing label pair found in that order
  60. // determines the outcome: If the label does not exist at all in m, then m is
  61. // before o, and vice versa. Otherwise the label value is compared
  62. // alphanumerically.
  63. //
  64. // If m and o are equal, the method returns false.
  65. func (ls LabelSet) Before(o LabelSet) bool {
  66. if len(ls) < len(o) {
  67. return true
  68. }
  69. if len(ls) > len(o) {
  70. return false
  71. }
  72. lns := make(LabelNames, 0, len(ls)+len(o))
  73. for ln := range ls {
  74. lns = append(lns, ln)
  75. }
  76. for ln := range o {
  77. lns = append(lns, ln)
  78. }
  79. // It's probably not worth it to de-dup lns.
  80. sort.Sort(lns)
  81. for _, ln := range lns {
  82. mlv, ok := ls[ln]
  83. if !ok {
  84. return true
  85. }
  86. olv, ok := o[ln]
  87. if !ok {
  88. return false
  89. }
  90. if mlv < olv {
  91. return true
  92. }
  93. if mlv > olv {
  94. return false
  95. }
  96. }
  97. return false
  98. }
  99. // Clone returns a copy of the label set.
  100. func (ls LabelSet) Clone() LabelSet {
  101. lsn := make(LabelSet, len(ls))
  102. for ln, lv := range ls {
  103. lsn[ln] = lv
  104. }
  105. return lsn
  106. }
  107. // Merge is a helper function to non-destructively merge two label sets.
  108. func (l LabelSet) Merge(other LabelSet) LabelSet {
  109. result := make(LabelSet, len(l))
  110. for k, v := range l {
  111. result[k] = v
  112. }
  113. for k, v := range other {
  114. result[k] = v
  115. }
  116. return result
  117. }
  118. // Fingerprint returns the LabelSet's fingerprint.
  119. func (ls LabelSet) Fingerprint() Fingerprint {
  120. return labelSetToFingerprint(ls)
  121. }
  122. // FastFingerprint returns the LabelSet's Fingerprint calculated by a faster hashing
  123. // algorithm, which is, however, more susceptible to hash collisions.
  124. func (ls LabelSet) FastFingerprint() Fingerprint {
  125. return labelSetToFastFingerprint(ls)
  126. }
  127. // UnmarshalJSON implements the json.Unmarshaler interface.
  128. func (l *LabelSet) UnmarshalJSON(b []byte) error {
  129. var m map[LabelName]LabelValue
  130. if err := json.Unmarshal(b, &m); err != nil {
  131. return err
  132. }
  133. // encoding/json only unmarshals maps of the form map[string]T. It treats
  134. // LabelName as a string and does not call its UnmarshalJSON method.
  135. // Thus, we have to replicate the behavior here.
  136. for ln := range m {
  137. if !ln.IsValid() {
  138. return fmt.Errorf("%q is not a valid label name", ln)
  139. }
  140. }
  141. *l = LabelSet(m)
  142. return nil
  143. }