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  }