github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/ingester/index/multi.go (about)

     1  package index
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/pkg/errors"
     7  	"github.com/prometheus/common/model"
     8  	"github.com/prometheus/prometheus/model/labels"
     9  
    10  	"github.com/grafana/loki/pkg/logproto"
    11  	"github.com/grafana/loki/pkg/querier/astmapper"
    12  	"github.com/grafana/loki/pkg/storage/config"
    13  )
    14  
    15  type periodIndex struct {
    16  	time.Time
    17  	idx int // address of the index to use
    18  }
    19  
    20  type Multi struct {
    21  	periods []periodIndex
    22  	indices []Interface
    23  }
    24  
    25  func NewMultiInvertedIndex(periods []config.PeriodConfig, indexShards uint32) (*Multi, error) {
    26  	var (
    27  		err error
    28  
    29  		ii          Interface // always stored in 0th index
    30  		bitPrefixed Interface // always stored in 1st index
    31  
    32  		periodIndices []periodIndex
    33  	)
    34  
    35  	for _, pd := range periods {
    36  		switch pd.IndexType {
    37  		case config.TSDBType:
    38  			if bitPrefixed == nil {
    39  				bitPrefixed, err = NewBitPrefixWithShards(indexShards)
    40  				if err != nil {
    41  					return nil, errors.Wrapf(err, "creating tsdb inverted index for period starting %v", pd.From)
    42  				}
    43  			}
    44  			periodIndices = append(periodIndices, periodIndex{
    45  				Time: pd.From.Time.Time(),
    46  				idx:  1, // tsdb inverted index is always stored in position one
    47  			})
    48  		default:
    49  			if ii == nil {
    50  				ii = NewWithShards(indexShards)
    51  			}
    52  			periodIndices = append(periodIndices, periodIndex{
    53  				Time: pd.From.Time.Time(),
    54  				idx:  0, // regular inverted index is always stored in position zero
    55  			})
    56  		}
    57  	}
    58  
    59  	return &Multi{
    60  		periods: periodIndices,
    61  		indices: []Interface{ii, bitPrefixed},
    62  	}, nil
    63  }
    64  
    65  func (m *Multi) Add(labels []logproto.LabelAdapter, fp model.Fingerprint) (result labels.Labels) {
    66  	for _, i := range m.indices {
    67  		if i != nil {
    68  			result = i.Add(labels, fp)
    69  		}
    70  	}
    71  	return
    72  }
    73  
    74  func (m *Multi) Delete(labels labels.Labels, fp model.Fingerprint) {
    75  	for _, i := range m.indices {
    76  		if i != nil {
    77  			i.Delete(labels, fp)
    78  		}
    79  	}
    80  
    81  }
    82  
    83  func (m *Multi) Lookup(t time.Time, matchers []*labels.Matcher, shard *astmapper.ShardAnnotation) ([]model.Fingerprint, error) {
    84  	return m.indexFor(t).Lookup(matchers, shard)
    85  }
    86  
    87  func (m *Multi) LabelNames(t time.Time, shard *astmapper.ShardAnnotation) ([]string, error) {
    88  	return m.indexFor(t).LabelNames(shard)
    89  }
    90  
    91  func (m *Multi) LabelValues(t time.Time, name string, shard *astmapper.ShardAnnotation) ([]string, error) {
    92  	return m.indexFor(t).LabelValues(name, shard)
    93  }
    94  
    95  // Query planning is responsible for ensuring no query spans more than one inverted index.
    96  // Therefore we don't need to account for both `from` and `through`.
    97  func (m *Multi) indexFor(t time.Time) Interface {
    98  	for i := range m.periods {
    99  		if !m.periods[i].Time.After(t) && (i+1 == len(m.periods) || t.Before(m.periods[i+1].Time)) {
   100  			return m.indices[m.periods[i].idx]
   101  		}
   102  	}
   103  	return noopInvertedIndex{}
   104  }
   105  
   106  type noopInvertedIndex struct{}
   107  
   108  func (noopInvertedIndex) Add(labels []logproto.LabelAdapter, fp model.Fingerprint) labels.Labels {
   109  	return nil
   110  }
   111  
   112  func (noopInvertedIndex) Delete(labels labels.Labels, fp model.Fingerprint) {}
   113  
   114  func (noopInvertedIndex) Lookup(matchers []*labels.Matcher, shard *astmapper.ShardAnnotation) ([]model.Fingerprint, error) {
   115  	return nil, nil
   116  }
   117  
   118  func (noopInvertedIndex) LabelNames(shard *astmapper.ShardAnnotation) ([]string, error) {
   119  	return nil, nil
   120  }
   121  
   122  func (noopInvertedIndex) LabelValues(name string, shard *astmapper.ShardAnnotation) ([]string, error) {
   123  	return nil, nil
   124  }