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

     1  package index
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/prometheus/common/model"
     7  	"github.com/weaveworks/common/mtime"
     8  )
     9  
    10  type schemaCaching struct {
    11  	SeriesStoreSchema
    12  
    13  	cacheOlderThan time.Duration
    14  }
    15  
    16  func NewSchemaCaching(schema SeriesStoreSchema, cacheOlderThan time.Duration) SeriesStoreSchema {
    17  	return &schemaCaching{
    18  		SeriesStoreSchema: schema,
    19  		cacheOlderThan:    cacheOlderThan,
    20  	}
    21  }
    22  
    23  func (s *schemaCaching) GetReadQueriesForMetric(from, through model.Time, userID string, metricName string) ([]Query, error) {
    24  	queries, err := s.SeriesStoreSchema.GetReadQueriesForMetric(from, through, userID, metricName)
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	return s.setImmutability(from, through, queries), nil
    29  }
    30  
    31  func (s *schemaCaching) GetReadQueriesForMetricLabel(from, through model.Time, userID string, metricName string, labelName string) ([]Query, error) {
    32  	queries, err := s.SeriesStoreSchema.GetReadQueriesForMetricLabel(from, through, userID, metricName, labelName)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  	return s.setImmutability(from, through, queries), nil
    37  }
    38  
    39  func (s *schemaCaching) GetReadQueriesForMetricLabelValue(from, through model.Time, userID string, metricName string, labelName string, labelValue string) ([]Query, error) {
    40  	queries, err := s.SeriesStoreSchema.GetReadQueriesForMetricLabelValue(from, through, userID, metricName, labelName, labelValue)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	return s.setImmutability(from, through, queries), nil
    45  }
    46  
    47  // If the query resulted in series IDs, use this method to find chunks.
    48  func (s *schemaCaching) GetChunksForSeries(from, through model.Time, userID string, seriesID []byte) ([]Query, error) {
    49  	queries, err := s.SeriesStoreSchema.GetChunksForSeries(from, through, userID, seriesID)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	return s.setImmutability(from, through, queries), nil
    54  }
    55  
    56  func (s *schemaCaching) GetLabelNamesForSeries(from, through model.Time, userID string, seriesID []byte) ([]Query, error) {
    57  	queries, err := s.SeriesStoreSchema.GetLabelNamesForSeries(from, through, userID, seriesID)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	return s.setImmutability(from, through, queries), nil
    62  }
    63  
    64  func (s *schemaCaching) setImmutability(_, through model.Time, queries []Query) []Query {
    65  	cacheBefore := model.TimeFromUnix(mtime.Now().Add(-s.cacheOlderThan).Unix())
    66  
    67  	// If the entire query is cacheable then cache it.
    68  	// While not super effective stand-alone, when combined with query-frontend and splitting,
    69  	// old queries will mostly be all behind boundary.
    70  	// To cleanly split cacheable and non-cacheable ranges, we'd need bucket start and end times
    71  	// which we don't know.
    72  	// See: https://github.com/cortexproject/cortex/issues/1698
    73  	if through.Before(cacheBefore) {
    74  		for i := range queries {
    75  			queries[i].Immutable = true
    76  		}
    77  	}
    78  
    79  	return queries
    80  }