github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/storage/stores/tsdb/index_shipper_querier.go (about)

     1  package tsdb
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  
     8  	"github.com/prometheus/common/model"
     9  	"github.com/prometheus/prometheus/model/labels"
    10  
    11  	"github.com/grafana/loki/pkg/storage/chunk"
    12  	"github.com/grafana/loki/pkg/storage/config"
    13  	"github.com/grafana/loki/pkg/storage/stores/index/stats"
    14  	"github.com/grafana/loki/pkg/storage/stores/indexshipper"
    15  	shipper_index "github.com/grafana/loki/pkg/storage/stores/indexshipper/index"
    16  	"github.com/grafana/loki/pkg/storage/stores/tsdb/index"
    17  )
    18  
    19  // indexShipperQuerier is used for querying index from the shipper.
    20  type indexShipperQuerier struct {
    21  	shipper     indexshipper.IndexShipper
    22  	chunkFilter chunk.RequestChunkFilterer
    23  	tableRanges config.TableRanges
    24  }
    25  
    26  func newIndexShipperQuerier(shipper indexshipper.IndexShipper, tableRanges config.TableRanges) Index {
    27  	return &indexShipperQuerier{shipper: shipper, tableRanges: tableRanges}
    28  }
    29  
    30  func (i *indexShipperQuerier) indices(ctx context.Context, from, through model.Time, user string) (Index, error) {
    31  	var indices []Index
    32  
    33  	// Ensure we query both per tenant and multitenant TSDBs
    34  	idxBuckets, err := indexBuckets(from, through, i.tableRanges)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	for _, bkt := range idxBuckets {
    39  		if err := i.shipper.ForEach(ctx, bkt, user, func(multitenant bool, idx shipper_index.Index) error {
    40  			impl, ok := idx.(Index)
    41  			if !ok {
    42  				return fmt.Errorf("unexpected shipper index type: %T", idx)
    43  			}
    44  			if multitenant {
    45  				indices = append(indices, NewMultiTenantIndex(impl))
    46  			} else {
    47  				indices = append(indices, impl)
    48  			}
    49  			return nil
    50  		}); err != nil {
    51  			return nil, err
    52  		}
    53  
    54  	}
    55  
    56  	if len(indices) == 0 {
    57  		return NoopIndex{}, nil
    58  	}
    59  	idx, err := NewMultiIndex(indices...)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	if i.chunkFilter != nil {
    65  		idx.SetChunkFilterer(i.chunkFilter)
    66  	}
    67  	return idx, nil
    68  }
    69  
    70  // TODO(owen-d): how to better implement this?
    71  // setting 0->maxint will force the tsdbmanager to always query
    72  // underlying tsdbs, which is safe, but can we optimize this?
    73  func (i *indexShipperQuerier) Bounds() (model.Time, model.Time) {
    74  	return 0, math.MaxInt64
    75  }
    76  
    77  func (i *indexShipperQuerier) SetChunkFilterer(chunkFilter chunk.RequestChunkFilterer) {
    78  	i.chunkFilter = chunkFilter
    79  }
    80  
    81  // Close implements Index.Close, but we offload this responsibility
    82  // to the index shipper
    83  func (i *indexShipperQuerier) Close() error {
    84  	return nil
    85  }
    86  
    87  func (i *indexShipperQuerier) GetChunkRefs(ctx context.Context, userID string, from, through model.Time, res []ChunkRef, shard *index.ShardAnnotation, matchers ...*labels.Matcher) ([]ChunkRef, error) {
    88  	idx, err := i.indices(ctx, from, through, userID)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  	return idx.GetChunkRefs(ctx, userID, from, through, res, shard, matchers...)
    93  }
    94  
    95  func (i *indexShipperQuerier) Series(ctx context.Context, userID string, from, through model.Time, res []Series, shard *index.ShardAnnotation, matchers ...*labels.Matcher) ([]Series, error) {
    96  	idx, err := i.indices(ctx, from, through, userID)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	return idx.Series(ctx, userID, from, through, res, shard, matchers...)
   101  }
   102  
   103  func (i *indexShipperQuerier) LabelNames(ctx context.Context, userID string, from, through model.Time, matchers ...*labels.Matcher) ([]string, error) {
   104  	idx, err := i.indices(ctx, from, through, userID)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  	return idx.LabelNames(ctx, userID, from, through, matchers...)
   109  }
   110  
   111  func (i *indexShipperQuerier) LabelValues(ctx context.Context, userID string, from, through model.Time, name string, matchers ...*labels.Matcher) ([]string, error) {
   112  	idx, err := i.indices(ctx, from, through, userID)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	return idx.LabelValues(ctx, userID, from, through, name, matchers...)
   117  }
   118  
   119  func (i *indexShipperQuerier) Stats(ctx context.Context, userID string, from, through model.Time, blooms *stats.Blooms, shard *index.ShardAnnotation, matchers ...*labels.Matcher) (*stats.Blooms, error) {
   120  	idx, err := i.indices(ctx, from, through, userID)
   121  	if err != nil {
   122  		return blooms, err
   123  	}
   124  
   125  	return idx.Stats(ctx, userID, from, through, blooms, shard, matchers...)
   126  }