master
go 110 lines 2.2 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package prometheus
4
5 import (
6 "sort"
7
8 "github.com/prometheus/prometheus/model/labels"
9 )
10
11 type (
12 // SeriesSample is a pair of label set and value
13 SeriesSample struct {
14 Labels labels.Labels
15 Value float64
16 }
17
18 // Series is a list of SeriesSample
19 Series []SeriesSample
20 )
21
22 // Name the __name__ label value
23 func (s SeriesSample) Name() string {
24 return s.Labels[0].Value
25 }
26
27 // Add appends a metric.
28 func (s *Series) Add(kv SeriesSample) {
29 *s = append(*s, kv)
30 }
31
32 // Reset resets the buffer to be empty,
33 // but it retains the underlying storage for use by future writes.
34 func (s *Series) Reset() {
35 *s = (*s)[:0]
36 }
37
38 // Sort sorts data.
39 func (s Series) Sort() {
40 sort.Sort(s)
41 }
42
43 // Len returns metric length.
44 func (s Series) Len() int {
45 return len(s)
46 }
47
48 // Less reports whether the element with
49 // index i should sort before the element with index j.
50 func (s Series) Less(i, j int) bool {
51 return s[i].Name() < s[j].Name()
52 }
53
54 // Swap swaps the elements with indexes i and j.
55 func (s Series) Swap(i, j int) {
56 s[i], s[j] = s[j], s[i]
57 }
58
59 // FindByName finds metrics where it's __name__ label matches given name.
60 // It expects the metrics is sorted.
61 // Complexity: O(log(N))
62 func (s Series) FindByName(name string) Series {
63 from := sort.Search(len(s), func(i int) bool {
64 return s[i].Name() >= name
65 })
66 if from == len(s) || s[from].Name() != name { // not found
67 return Series{}
68 }
69 until := from + 1
70 for until < len(s) && s[until].Name() == name {
71 until++
72 }
73 return s[from:until]
74 }
75
76 // FindByNames finds metrics where it's __name__ label matches given any of names.
77 // It expects the metrics is sorted.
78 // Complexity: O(log(N))
79 func (s Series) FindByNames(names ...string) Series {
80 switch len(names) {
81 case 0:
82 return Series{}
83 case 1:
84 return s.FindByName(names[0])
85 }
86 var result Series
87 for _, name := range names {
88 result = append(result, s.FindByName(name)...)
89 }
90 return result
91 }
92
93 // Max returns the max value.
94 // It does NOT expect the metrics is sorted.
95 // Complexity: O(N)
96 func (s Series) Max() float64 {
97 switch len(s) {
98 case 0:
99 return 0
100 case 1:
101 return s[0].Value
102 }
103 maxv := s[0].Value
104 for _, kv := range s[1:] {
105 if maxv < kv.Value {
106 maxv = kv.Value
107 }
108 }
109 return maxv
110 }