github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/querier/series/series_set.go (about) 1 // Some of the code in this file was adapted from Prometheus (https://github.com/prometheus/prometheus). 2 // The original license header is included below: 3 // 4 // Copyright 2017 The Prometheus Authors 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package series 18 19 import ( 20 "sort" 21 22 "github.com/prometheus/common/model" 23 "github.com/prometheus/prometheus/model/labels" 24 "github.com/prometheus/prometheus/storage" 25 "github.com/prometheus/prometheus/tsdb/chunkenc" 26 27 "github.com/grafana/loki/pkg/prom1/storage/metric" 28 ) 29 30 // ConcreteSeriesSet implements storage.SeriesSet. 31 type ConcreteSeriesSet struct { 32 cur int 33 series []storage.Series 34 } 35 36 // NewConcreteSeriesSet instantiates an in-memory series set from a series 37 // Series will be sorted by labels. 38 func NewConcreteSeriesSet(series []storage.Series) storage.SeriesSet { 39 sort.Sort(byLabels(series)) 40 return &ConcreteSeriesSet{ 41 cur: -1, 42 series: series, 43 } 44 } 45 46 // Next iterates through a series set and implements storage.SeriesSet. 47 func (c *ConcreteSeriesSet) Next() bool { 48 c.cur++ 49 return c.cur < len(c.series) 50 } 51 52 // At returns the current series and implements storage.SeriesSet. 53 func (c *ConcreteSeriesSet) At() storage.Series { 54 return c.series[c.cur] 55 } 56 57 // Err implements storage.SeriesSet. 58 func (c *ConcreteSeriesSet) Err() error { 59 return nil 60 } 61 62 // Warnings implements storage.SeriesSet. 63 func (c *ConcreteSeriesSet) Warnings() storage.Warnings { 64 return nil 65 } 66 67 // ConcreteSeries implements storage.Series. 68 type ConcreteSeries struct { 69 labels labels.Labels 70 samples []model.SamplePair 71 } 72 73 // NewConcreteSeries instantiates an in memory series from a list of samples & labels 74 func NewConcreteSeries(ls labels.Labels, samples []model.SamplePair) *ConcreteSeries { 75 return &ConcreteSeries{ 76 labels: ls, 77 samples: samples, 78 } 79 } 80 81 // Labels implements storage.Series 82 func (c *ConcreteSeries) Labels() labels.Labels { 83 return c.labels 84 } 85 86 // Iterator implements storage.Series 87 func (c *ConcreteSeries) Iterator() chunkenc.Iterator { 88 return NewConcreteSeriesIterator(c) 89 } 90 91 // concreteSeriesIterator implements chunkenc.Iterator. 92 type concreteSeriesIterator struct { 93 cur int 94 series *ConcreteSeries 95 } 96 97 // NewConcreteSeriesIterator instaniates an in memory chunkenc.Iterator 98 func NewConcreteSeriesIterator(series *ConcreteSeries) chunkenc.Iterator { 99 return &concreteSeriesIterator{ 100 cur: -1, 101 series: series, 102 } 103 } 104 105 func (c *concreteSeriesIterator) Seek(t int64) bool { 106 c.cur = sort.Search(len(c.series.samples), func(n int) bool { 107 return c.series.samples[n].Timestamp >= model.Time(t) 108 }) 109 return c.cur < len(c.series.samples) 110 } 111 112 func (c *concreteSeriesIterator) At() (t int64, v float64) { 113 s := c.series.samples[c.cur] 114 return int64(s.Timestamp), float64(s.Value) 115 } 116 117 func (c *concreteSeriesIterator) Next() bool { 118 c.cur++ 119 return c.cur < len(c.series.samples) 120 } 121 122 func (c *concreteSeriesIterator) Err() error { 123 return nil 124 } 125 126 // NewErrIterator instantiates an errIterator 127 func NewErrIterator(err error) chunkenc.Iterator { 128 return errIterator{err} 129 } 130 131 // errIterator implements chunkenc.Iterator, just returning an error. 132 type errIterator struct { 133 err error 134 } 135 136 func (errIterator) Seek(int64) bool { 137 return false 138 } 139 140 func (errIterator) Next() bool { 141 return false 142 } 143 144 func (errIterator) At() (t int64, v float64) { 145 return 0, 0 146 } 147 148 func (e errIterator) Err() error { 149 return e.err 150 } 151 152 // MatrixToSeriesSet creates a storage.SeriesSet from a model.Matrix 153 // Series will be sorted by labels. 154 func MatrixToSeriesSet(m model.Matrix) storage.SeriesSet { 155 series := make([]storage.Series, 0, len(m)) 156 for _, ss := range m { 157 series = append(series, &ConcreteSeries{ 158 labels: metricToLabels(ss.Metric), 159 samples: ss.Values, 160 }) 161 } 162 return NewConcreteSeriesSet(series) 163 } 164 165 // MetricsToSeriesSet creates a storage.SeriesSet from a []metric.Metric 166 func MetricsToSeriesSet(ms []metric.Metric) storage.SeriesSet { 167 series := make([]storage.Series, 0, len(ms)) 168 for _, m := range ms { 169 series = append(series, &ConcreteSeries{ 170 labels: metricToLabels(m.Metric), 171 samples: nil, 172 }) 173 } 174 return NewConcreteSeriesSet(series) 175 } 176 177 func metricToLabels(m model.Metric) labels.Labels { 178 ls := make(labels.Labels, 0, len(m)) 179 for k, v := range m { 180 ls = append(ls, labels.Label{ 181 Name: string(k), 182 Value: string(v), 183 }) 184 } 185 // PromQL expects all labels to be sorted! In general, anyone constructing 186 // a labels.Labels list is responsible for sorting it during construction time. 187 sort.Sort(ls) 188 return ls 189 } 190 191 type byLabels []storage.Series 192 193 func (b byLabels) Len() int { return len(b) } 194 func (b byLabels) Swap(i, j int) { b[i], b[j] = b[j], b[i] } 195 func (b byLabels) Less(i, j int) bool { return labels.Compare(b[i].Labels(), b[j].Labels()) < 0 } 196 197 type DeletedSeries struct { 198 series storage.Series 199 deletedIntervals []model.Interval 200 } 201 202 func NewDeletedSeries(series storage.Series, deletedIntervals []model.Interval) storage.Series { 203 return &DeletedSeries{ 204 series: series, 205 deletedIntervals: deletedIntervals, 206 } 207 } 208 209 func (d DeletedSeries) Labels() labels.Labels { 210 return d.series.Labels() 211 } 212 213 func (d DeletedSeries) Iterator() chunkenc.Iterator { 214 return NewDeletedSeriesIterator(d.series.Iterator(), d.deletedIntervals) 215 } 216 217 type DeletedSeriesIterator struct { 218 itr chunkenc.Iterator 219 deletedIntervals []model.Interval 220 } 221 222 func NewDeletedSeriesIterator(itr chunkenc.Iterator, deletedIntervals []model.Interval) chunkenc.Iterator { 223 return &DeletedSeriesIterator{ 224 itr: itr, 225 deletedIntervals: deletedIntervals, 226 } 227 } 228 229 func (d DeletedSeriesIterator) Seek(t int64) bool { 230 if found := d.itr.Seek(t); !found { 231 return false 232 } 233 234 seekedTs, _ := d.itr.At() 235 if d.isDeleted(seekedTs) { 236 // point we have seeked into is deleted, Next() should find a new non-deleted sample which is after t and seekedTs 237 return d.Next() 238 } 239 240 return true 241 } 242 243 func (d DeletedSeriesIterator) At() (t int64, v float64) { 244 return d.itr.At() 245 } 246 247 func (d DeletedSeriesIterator) Next() bool { 248 for d.itr.Next() { 249 ts, _ := d.itr.At() 250 251 if d.isDeleted(ts) { 252 continue 253 } 254 return true 255 } 256 return false 257 } 258 259 func (d DeletedSeriesIterator) Err() error { 260 return d.itr.Err() 261 } 262 263 // isDeleted removes intervals which are past ts while checking for whether ts happens to be in one of the deleted intervals 264 func (d *DeletedSeriesIterator) isDeleted(ts int64) bool { 265 mts := model.Time(ts) 266 267 for _, interval := range d.deletedIntervals { 268 if mts > interval.End { 269 d.deletedIntervals = d.deletedIntervals[1:] 270 continue 271 } else if mts < interval.Start { 272 return false 273 } 274 275 return true 276 } 277 278 return false 279 } 280 281 type emptySeries struct { 282 labels labels.Labels 283 } 284 285 func NewEmptySeries(labels labels.Labels) storage.Series { 286 return emptySeries{labels} 287 } 288 289 func (e emptySeries) Labels() labels.Labels { 290 return e.labels 291 } 292 293 func (emptySeries) Iterator() chunkenc.Iterator { 294 return NewEmptySeriesIterator() 295 } 296 297 type emptySeriesIterator struct { 298 } 299 300 func NewEmptySeriesIterator() chunkenc.Iterator { 301 return emptySeriesIterator{} 302 } 303 304 func (emptySeriesIterator) Seek(t int64) bool { 305 return false 306 } 307 308 func (emptySeriesIterator) At() (t int64, v float64) { 309 return 0, 0 310 } 311 312 func (emptySeriesIterator) Next() bool { 313 return false 314 } 315 316 func (emptySeriesIterator) Err() error { 317 return nil 318 } 319 320 type seriesSetWithWarnings struct { 321 wrapped storage.SeriesSet 322 warnings storage.Warnings 323 } 324 325 func NewSeriesSetWithWarnings(wrapped storage.SeriesSet, warnings storage.Warnings) storage.SeriesSet { 326 return seriesSetWithWarnings{ 327 wrapped: wrapped, 328 warnings: warnings, 329 } 330 } 331 332 func (s seriesSetWithWarnings) Next() bool { 333 return s.wrapped.Next() 334 } 335 336 func (s seriesSetWithWarnings) At() storage.Series { 337 return s.wrapped.At() 338 } 339 340 func (s seriesSetWithWarnings) Err() error { 341 return s.wrapped.Err() 342 } 343 344 func (s seriesSetWithWarnings) Warnings() storage.Warnings { 345 return append(s.wrapped.Warnings(), s.warnings...) 346 }