github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/tsdb/head_read.go (about) 1 // Copyright 2021 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 14 package tsdb 15 16 import ( 17 "math" 18 "sort" 19 20 "github.com/prometheus/prometheus/model/labels" 21 "github.com/prometheus/prometheus/storage" 22 23 "github.com/grafana/loki/pkg/storage/stores/tsdb/index" 24 ) 25 26 // Index returns an IndexReader against the block. 27 func (h *Head) Index() IndexReader { 28 return h.indexRange(math.MinInt64, math.MaxInt64) 29 } 30 31 func (h *Head) indexRange(mint, maxt int64) *headIndexReader { 32 if hmin := h.MinTime(); hmin > mint { 33 mint = hmin 34 } 35 return &headIndexReader{head: h, mint: mint, maxt: maxt} 36 } 37 38 type headIndexReader struct { 39 head *Head 40 mint, maxt int64 41 } 42 43 func (h *headIndexReader) Bounds() (int64, int64) { 44 return h.head.MinTime(), h.head.MaxTime() 45 } 46 47 func (h *headIndexReader) Checksum() uint32 { return 0 } 48 49 func (h *headIndexReader) Close() error { 50 return nil 51 } 52 53 func (h *headIndexReader) Symbols() index.StringIter { 54 return h.head.postings.Symbols() 55 } 56 57 // SortedLabelValues returns label values present in the head for the 58 // specific label name that are within the time range mint to maxt. 59 // If matchers are specified the returned result set is reduced 60 // to label values of metrics matching the matchers. 61 func (h *headIndexReader) SortedLabelValues(name string, matchers ...*labels.Matcher) ([]string, error) { 62 values, err := h.LabelValues(name, matchers...) 63 if err == nil { 64 sort.Strings(values) 65 } 66 return values, err 67 } 68 69 // LabelValues returns label values present in the head for the 70 // specific label name that are within the time range mint to maxt. 71 // If matchers are specified the returned result set is reduced 72 // to label values of metrics matching the matchers. 73 func (h *headIndexReader) LabelValues(name string, matchers ...*labels.Matcher) ([]string, error) { 74 if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() { 75 return []string{}, nil 76 } 77 78 if len(matchers) == 0 { 79 return h.head.postings.LabelValues(name), nil 80 } 81 82 return labelValuesWithMatchers(h, name, matchers...) 83 } 84 85 // LabelNames returns all the unique label names present in the head 86 // that are within the time range mint to maxt. 87 func (h *headIndexReader) LabelNames(matchers ...*labels.Matcher) ([]string, error) { 88 if h.maxt < h.head.MinTime() || h.mint > h.head.MaxTime() { 89 return []string{}, nil 90 } 91 92 if len(matchers) == 0 { 93 labelNames := h.head.postings.LabelNames() 94 sort.Strings(labelNames) 95 return labelNames, nil 96 } 97 98 return labelNamesWithMatchers(h, matchers...) 99 } 100 101 // Postings returns the postings list iterator for the label pairs. 102 func (h *headIndexReader) Postings(name string, shard *index.ShardAnnotation, values ...string) (index.Postings, error) { 103 var p index.Postings 104 switch len(values) { 105 case 0: 106 p = index.EmptyPostings() 107 case 1: 108 p = h.head.postings.Get(name, values[0]) 109 default: 110 res := make([]index.Postings, 0, len(values)) 111 for _, value := range values { 112 res = append(res, h.head.postings.Get(name, value)) 113 } 114 p = index.Merge(res...) 115 } 116 117 if shard != nil { 118 return index.NewShardedPostings(p, *shard, nil), nil 119 } 120 return p, nil 121 } 122 123 // Series returns the series for the given reference. 124 func (h *headIndexReader) Series(ref storage.SeriesRef, lbls *labels.Labels, chks *[]index.ChunkMeta) (uint64, error) { 125 s := h.head.series.getByID(uint64(ref)) 126 127 if s == nil { 128 h.head.metrics.seriesNotFound.Inc() 129 return 0, storage.ErrNotFound 130 } 131 *lbls = append((*lbls)[:0], s.ls...) 132 133 s.Lock() 134 *chks = append((*chks)[:0], s.chks...) 135 s.Unlock() 136 137 return s.fp, nil 138 } 139 140 // LabelValueFor returns label value for the given label name in the series referred to by ID. 141 func (h *headIndexReader) LabelValueFor(id storage.SeriesRef, label string) (string, error) { 142 memSeries := h.head.series.getByID(uint64(id)) 143 if memSeries == nil { 144 return "", storage.ErrNotFound 145 } 146 147 value := memSeries.ls.Get(label) 148 if value == "" { 149 return "", storage.ErrNotFound 150 } 151 152 return value, nil 153 } 154 155 // LabelNamesFor returns all the label names for the series referred to by IDs. 156 // The names returned are sorted. 157 func (h *headIndexReader) LabelNamesFor(ids ...storage.SeriesRef) ([]string, error) { 158 namesMap := make(map[string]struct{}) 159 for _, id := range ids { 160 memSeries := h.head.series.getByID(uint64(id)) 161 if memSeries == nil { 162 return nil, storage.ErrNotFound 163 } 164 for _, lbl := range memSeries.ls { 165 namesMap[lbl.Name] = struct{}{} 166 } 167 } 168 names := make([]string, 0, len(namesMap)) 169 for name := range namesMap { 170 names = append(names, name) 171 } 172 sort.Strings(names) 173 return names, nil 174 }