github.com/netdata/go.d.plugin@v0.58.1/pkg/prometheus/metric_series.go (about) 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 max := s[0].Value 104 for _, kv := range s[1:] { 105 if max < kv.Value { 106 max = kv.Value 107 } 108 } 109 return max 110 }