github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/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/pkg/labels" 24 "github.com/prometheus/prometheus/storage" 25 "github.com/prometheus/prometheus/tsdb/chunkenc" 26 27 "github.com/cortexproject/cortex/pkg/chunk/purger" 28 "github.com/cortexproject/cortex/pkg/prom1/storage/metric" 29 ) 30 31 // ConcreteSeriesSet implements storage.SeriesSet. 32 type ConcreteSeriesSet struct { 33 cur int 34 series []storage.Series 35 } 36 37 // NewConcreteSeriesSet instantiates an in-memory series set from a series 38 // Series will be sorted by labels. 39 func NewConcreteSeriesSet(series []storage.Series) storage.SeriesSet { 40 sort.Sort(byLabels(series)) 41 return &ConcreteSeriesSet{ 42 cur: -1, 43 series: series, 44 } 45 } 46 47 // Next iterates through a series set and implements storage.SeriesSet. 48 func (c *ConcreteSeriesSet) Next() bool { 49 c.cur++ 50 return c.cur < len(c.series) 51 } 52 53 // At returns the current series and implements storage.SeriesSet. 54 func (c *ConcreteSeriesSet) At() storage.Series { 55 return c.series[c.cur] 56 } 57 58 // Err implements storage.SeriesSet. 59 func (c *ConcreteSeriesSet) Err() error { 60 return nil 61 } 62 63 // Warnings implements storage.SeriesSet. 64 func (c *ConcreteSeriesSet) Warnings() storage.Warnings { 65 return nil 66 } 67 68 // ConcreteSeries implements storage.Series. 69 type ConcreteSeries struct { 70 labels labels.Labels 71 samples []model.SamplePair 72 } 73 74 // NewConcreteSeries instantiates an in memory series from a list of samples & labels 75 func NewConcreteSeries(ls labels.Labels, samples []model.SamplePair) *ConcreteSeries { 76 return &ConcreteSeries{ 77 labels: ls, 78 samples: samples, 79 } 80 } 81 82 // Labels implements storage.Series 83 func (c *ConcreteSeries) Labels() labels.Labels { 84 return c.labels 85 } 86 87 // Iterator implements storage.Series 88 func (c *ConcreteSeries) Iterator() chunkenc.Iterator { 89 return NewConcreteSeriesIterator(c) 90 } 91 92 // concreteSeriesIterator implements chunkenc.Iterator. 93 type concreteSeriesIterator struct { 94 cur int 95 series *ConcreteSeries 96 } 97 98 // NewConcreteSeriesIterator instaniates an in memory chunkenc.Iterator 99 func NewConcreteSeriesIterator(series *ConcreteSeries) chunkenc.Iterator { 100 return &concreteSeriesIterator{ 101 cur: -1, 102 series: series, 103 } 104 } 105 106 func (c *concreteSeriesIterator) Seek(t int64) bool { 107 c.cur = sort.Search(len(c.series.samples), func(n int) bool { 108 return c.series.samples[n].Timestamp >= model.Time(t) 109 }) 110 return c.cur < len(c.series.samples) 111 } 112 113 func (c *concreteSeriesIterator) At() (t int64, v float64) { 114 s := c.series.samples[c.cur] 115 return int64(s.Timestamp), float64(s.Value) 116 } 117 118 func (c *concreteSeriesIterator) Next() bool { 119 c.cur++ 120 return c.cur < len(c.series.samples) 121 } 122 123 func (c *concreteSeriesIterator) Err() error { 124 return nil 125 } 126 127 // NewErrIterator instantiates an errIterator 128 func NewErrIterator(err error) chunkenc.Iterator { 129 return errIterator{err} 130 } 131 132 // errIterator implements chunkenc.Iterator, just returning an error. 133 type errIterator struct { 134 err error 135 } 136 137 func (errIterator) Seek(int64) bool { 138 return false 139 } 140 141 func (errIterator) Next() bool { 142 return false 143 } 144 145 func (errIterator) At() (t int64, v float64) { 146 return 0, 0 147 } 148 149 func (e errIterator) Err() error { 150 return e.err 151 } 152 153 // MatrixToSeriesSet creates a storage.SeriesSet from a model.Matrix 154 // Series will be sorted by labels. 155 func MatrixToSeriesSet(m model.Matrix) storage.SeriesSet { 156 series := make([]storage.Series, 0, len(m)) 157 for _, ss := range m { 158 series = append(series, &ConcreteSeries{ 159 labels: metricToLabels(ss.Metric), 160 samples: ss.Values, 161 }) 162 } 163 return NewConcreteSeriesSet(series) 164 } 165 166 // MetricsToSeriesSet creates a storage.SeriesSet from a []metric.Metric 167 func MetricsToSeriesSet(ms []metric.Metric) storage.SeriesSet { 168 series := make([]storage.Series, 0, len(ms)) 169 for _, m := range ms { 170 series = append(series, &ConcreteSeries{ 171 labels: metricToLabels(m.Metric), 172 samples: nil, 173 }) 174 } 175 return NewConcreteSeriesSet(series) 176 } 177 178 func metricToLabels(m model.Metric) labels.Labels { 179 ls := make(labels.Labels, 0, len(m)) 180 for k, v := range m { 181 ls = append(ls, labels.Label{ 182 Name: string(k), 183 Value: string(v), 184 }) 185 } 186 // PromQL expects all labels to be sorted! In general, anyone constructing 187 // a labels.Labels list is responsible for sorting it during construction time. 188 sort.Sort(ls) 189 return ls 190 } 191 192 type byLabels []storage.Series 193 194 func (b byLabels) Len() int { return len(b) } 195 func (b byLabels) Swap(i, j int) { b[i], b[j] = b[j], b[i] } 196 func (b byLabels) Less(i, j int) bool { return labels.Compare(b[i].Labels(), b[j].Labels()) < 0 } 197 198 type DeletedSeriesSet struct { 199 seriesSet storage.SeriesSet 200 tombstones *purger.TombstonesSet 201 queryInterval model.Interval 202 } 203 204 func NewDeletedSeriesSet(seriesSet storage.SeriesSet, tombstones *purger.TombstonesSet, queryInterval model.Interval) storage.SeriesSet { 205 return &DeletedSeriesSet{ 206 seriesSet: seriesSet, 207 tombstones: tombstones, 208 queryInterval: queryInterval, 209 } 210 } 211 212 func (d DeletedSeriesSet) Next() bool { 213 return d.seriesSet.Next() 214 } 215 216 func (d DeletedSeriesSet) At() storage.Series { 217 series := d.seriesSet.At() 218 deletedIntervals := d.tombstones.GetDeletedIntervals(series.Labels(), d.queryInterval.Start, d.queryInterval.End) 219 220 // series is deleted for whole query range so return empty series 221 if len(deletedIntervals) == 1 && deletedIntervals[0] == d.queryInterval { 222 return NewEmptySeries(series.Labels()) 223 } 224 225 return NewDeletedSeries(series, deletedIntervals) 226 } 227 228 func (d DeletedSeriesSet) Err() error { 229 return d.seriesSet.Err() 230 } 231 232 func (d DeletedSeriesSet) Warnings() storage.Warnings { 233 return nil 234 } 235 236 type DeletedSeries struct { 237 series storage.Series 238 deletedIntervals []model.Interval 239 } 240 241 func NewDeletedSeries(series storage.Series, deletedIntervals []model.Interval) storage.Series { 242 return &DeletedSeries{ 243 series: series, 244 deletedIntervals: deletedIntervals, 245 } 246 } 247 248 func (d DeletedSeries) Labels() labels.Labels { 249 return d.series.Labels() 250 } 251 252 func (d DeletedSeries) Iterator() chunkenc.Iterator { 253 return NewDeletedSeriesIterator(d.series.Iterator(), d.deletedIntervals) 254 } 255 256 type DeletedSeriesIterator struct { 257 itr chunkenc.Iterator 258 deletedIntervals []model.Interval 259 } 260 261 func NewDeletedSeriesIterator(itr chunkenc.Iterator, deletedIntervals []model.Interval) chunkenc.Iterator { 262 return &DeletedSeriesIterator{ 263 itr: itr, 264 deletedIntervals: deletedIntervals, 265 } 266 } 267 268 func (d DeletedSeriesIterator) Seek(t int64) bool { 269 if found := d.itr.Seek(t); !found { 270 return false 271 } 272 273 seekedTs, _ := d.itr.At() 274 if d.isDeleted(seekedTs) { 275 // point we have seeked into is deleted, Next() should find a new non-deleted sample which is after t and seekedTs 276 return d.Next() 277 } 278 279 return true 280 } 281 282 func (d DeletedSeriesIterator) At() (t int64, v float64) { 283 return d.itr.At() 284 } 285 286 func (d DeletedSeriesIterator) Next() bool { 287 for d.itr.Next() { 288 ts, _ := d.itr.At() 289 290 if d.isDeleted(ts) { 291 continue 292 } 293 return true 294 } 295 return false 296 } 297 298 func (d DeletedSeriesIterator) Err() error { 299 return d.itr.Err() 300 } 301 302 // isDeleted removes intervals which are past ts while checking for whether ts happens to be in one of the deleted intervals 303 func (d *DeletedSeriesIterator) isDeleted(ts int64) bool { 304 mts := model.Time(ts) 305 306 for _, interval := range d.deletedIntervals { 307 if mts > interval.End { 308 d.deletedIntervals = d.deletedIntervals[1:] 309 continue 310 } else if mts < interval.Start { 311 return false 312 } 313 314 return true 315 } 316 317 return false 318 } 319 320 type emptySeries struct { 321 labels labels.Labels 322 } 323 324 func NewEmptySeries(labels labels.Labels) storage.Series { 325 return emptySeries{labels} 326 } 327 328 func (e emptySeries) Labels() labels.Labels { 329 return e.labels 330 } 331 332 func (emptySeries) Iterator() chunkenc.Iterator { 333 return NewEmptySeriesIterator() 334 } 335 336 type emptySeriesIterator struct { 337 } 338 339 func NewEmptySeriesIterator() chunkenc.Iterator { 340 return emptySeriesIterator{} 341 } 342 343 func (emptySeriesIterator) Seek(t int64) bool { 344 return false 345 } 346 347 func (emptySeriesIterator) At() (t int64, v float64) { 348 return 0, 0 349 } 350 351 func (emptySeriesIterator) Next() bool { 352 return false 353 } 354 355 func (emptySeriesIterator) Err() error { 356 return nil 357 } 358 359 type seriesSetWithWarnings struct { 360 wrapped storage.SeriesSet 361 warnings storage.Warnings 362 } 363 364 func NewSeriesSetWithWarnings(wrapped storage.SeriesSet, warnings storage.Warnings) storage.SeriesSet { 365 return seriesSetWithWarnings{ 366 wrapped: wrapped, 367 warnings: warnings, 368 } 369 } 370 371 func (s seriesSetWithWarnings) Next() bool { 372 return s.wrapped.Next() 373 } 374 375 func (s seriesSetWithWarnings) At() storage.Series { 376 return s.wrapped.At() 377 } 378 379 func (s seriesSetWithWarnings) Err() error { 380 return s.wrapped.Err() 381 } 382 383 func (s seriesSetWithWarnings) Warnings() storage.Warnings { 384 return append(s.wrapped.Warnings(), s.warnings...) 385 }