github.com/thanos-io/thanos@v0.32.5/pkg/cache/caching_bucket_config.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package cache
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/thanos-io/objstore"
    10  )
    11  
    12  // Codec for encoding and decoding results of Iter call.
    13  type IterCodec interface {
    14  	Encode(files []string) ([]byte, error)
    15  	Decode(cachedData []byte) ([]string, error)
    16  }
    17  
    18  // CachingBucketConfig contains low-level configuration for individual bucket operations.
    19  // This is not exposed to the user, but it is expected that code sets up individual
    20  // operations based on user-provided configuration.
    21  type CachingBucketConfig struct {
    22  	get        map[string]*GetConfig
    23  	iter       map[string]*IterConfig
    24  	exists     map[string]*ExistsConfig
    25  	getRange   map[string]*GetRangeConfig
    26  	attributes map[string]*AttributesConfig
    27  }
    28  
    29  func NewCachingBucketConfig() *CachingBucketConfig {
    30  	return &CachingBucketConfig{
    31  		get:        map[string]*GetConfig{},
    32  		iter:       map[string]*IterConfig{},
    33  		exists:     map[string]*ExistsConfig{},
    34  		getRange:   map[string]*GetRangeConfig{},
    35  		attributes: map[string]*AttributesConfig{},
    36  	}
    37  }
    38  
    39  // SetCacheImplementation sets the value of Cache for all configurations.
    40  func (cfg *CachingBucketConfig) SetCacheImplementation(c Cache) {
    41  	for k := range cfg.get {
    42  		cfg.get[k].Cache = c
    43  	}
    44  	for k := range cfg.iter {
    45  		cfg.iter[k].Cache = c
    46  	}
    47  	for k := range cfg.exists {
    48  		cfg.exists[k].Cache = c
    49  	}
    50  	for k := range cfg.getRange {
    51  		cfg.getRange[k].Cache = c
    52  	}
    53  	for k := range cfg.attributes {
    54  		cfg.attributes[k].Cache = c
    55  	}
    56  }
    57  
    58  // Generic config for single operation.
    59  type OperationConfig struct {
    60  	Matcher func(name string) bool
    61  	Cache   Cache
    62  }
    63  
    64  // Operation-specific configs.
    65  type IterConfig struct {
    66  	OperationConfig
    67  	TTL   time.Duration
    68  	Codec IterCodec
    69  }
    70  
    71  type ExistsConfig struct {
    72  	OperationConfig
    73  	ExistsTTL      time.Duration
    74  	DoesntExistTTL time.Duration
    75  }
    76  
    77  type GetConfig struct {
    78  	ExistsConfig
    79  	ContentTTL       time.Duration
    80  	MaxCacheableSize int
    81  }
    82  
    83  type GetRangeConfig struct {
    84  	OperationConfig
    85  	SubrangeSize   int64
    86  	MaxSubRequests int
    87  	AttributesTTL  time.Duration
    88  	SubrangeTTL    time.Duration
    89  }
    90  
    91  type AttributesConfig struct {
    92  	OperationConfig
    93  	TTL time.Duration
    94  }
    95  
    96  func newOperationConfig(cache Cache, matcher func(string) bool) OperationConfig {
    97  	if matcher == nil {
    98  		panic("matcher")
    99  	}
   100  
   101  	return OperationConfig{
   102  		Matcher: matcher,
   103  		Cache:   cache,
   104  	}
   105  }
   106  
   107  // CacheIter configures caching of "Iter" operation for matching directories.
   108  func (cfg *CachingBucketConfig) CacheIter(configName string, cache Cache, matcher func(string) bool, ttl time.Duration, codec IterCodec) {
   109  	cfg.iter[configName] = &IterConfig{
   110  		OperationConfig: newOperationConfig(cache, matcher),
   111  		TTL:             ttl,
   112  		Codec:           codec,
   113  	}
   114  }
   115  
   116  // CacheGet configures caching of "Get" operation for matching files. Content of the object is cached, as well as whether object exists or not.
   117  func (cfg *CachingBucketConfig) CacheGet(configName string, cache Cache, matcher func(string) bool, maxCacheableSize int, contentTTL, existsTTL, doesntExistTTL time.Duration) {
   118  	cfg.get[configName] = &GetConfig{
   119  		ExistsConfig: ExistsConfig{
   120  			OperationConfig: newOperationConfig(cache, matcher),
   121  			ExistsTTL:       existsTTL,
   122  			DoesntExistTTL:  doesntExistTTL,
   123  		},
   124  		ContentTTL:       contentTTL,
   125  		MaxCacheableSize: maxCacheableSize,
   126  	}
   127  }
   128  
   129  // CacheExists configures caching of "Exists" operation for matching files. Negative values are cached as well.
   130  func (cfg *CachingBucketConfig) CacheExists(configName string, cache Cache, matcher func(string) bool, existsTTL, doesntExistTTL time.Duration) {
   131  	cfg.exists[configName] = &ExistsConfig{
   132  		OperationConfig: newOperationConfig(cache, matcher),
   133  		ExistsTTL:       existsTTL,
   134  		DoesntExistTTL:  doesntExistTTL,
   135  	}
   136  }
   137  
   138  // CacheGetRange configures caching of "GetRange" operation. Subranges (aligned on subrange size) are cached individually.
   139  // Since caching operation needs to know the object size to compute correct subranges, object size is cached as well.
   140  // Single "GetRange" requests can result in multiple smaller GetRange sub-requests issued on the underlying bucket.
   141  // MaxSubRequests specifies how many such subrequests may be issued. Values <= 0 mean there is no limit (requests
   142  // for adjacent missing subranges are still merged).
   143  func (cfg *CachingBucketConfig) CacheGetRange(configName string, cache Cache, matcher func(string) bool, subrangeSize int64, attributesTTL, subrangeTTL time.Duration, maxSubRequests int) {
   144  	cfg.getRange[configName] = &GetRangeConfig{
   145  		OperationConfig: newOperationConfig(cache, matcher),
   146  		SubrangeSize:    subrangeSize,
   147  		AttributesTTL:   attributesTTL,
   148  		SubrangeTTL:     subrangeTTL,
   149  		MaxSubRequests:  maxSubRequests,
   150  	}
   151  }
   152  
   153  // CacheAttributes configures caching of "Attributes" operation for matching files.
   154  func (cfg *CachingBucketConfig) CacheAttributes(configName string, cache Cache, matcher func(name string) bool, ttl time.Duration) {
   155  	cfg.attributes[configName] = &AttributesConfig{
   156  		OperationConfig: newOperationConfig(cache, matcher),
   157  		TTL:             ttl,
   158  	}
   159  }
   160  
   161  func (cfg *CachingBucketConfig) AllConfigNames() map[string][]string {
   162  	result := map[string][]string{}
   163  	for n := range cfg.get {
   164  		result[objstore.OpGet] = append(result[objstore.OpGet], n)
   165  	}
   166  	for n := range cfg.iter {
   167  		result[objstore.OpIter] = append(result[objstore.OpIter], n)
   168  	}
   169  	for n := range cfg.exists {
   170  		result[objstore.OpExists] = append(result[objstore.OpExists], n)
   171  	}
   172  	for n := range cfg.getRange {
   173  		result[objstore.OpGetRange] = append(result[objstore.OpGetRange], n)
   174  	}
   175  	for n := range cfg.attributes {
   176  		result[objstore.OpAttributes] = append(result[objstore.OpAttributes], n)
   177  	}
   178  	return result
   179  }
   180  
   181  func (cfg *CachingBucketConfig) FindIterConfig(dir string) (string, *IterConfig) {
   182  	for n, cfg := range cfg.iter {
   183  		if cfg.Matcher(dir) {
   184  			return n, cfg
   185  		}
   186  	}
   187  	return "", nil
   188  }
   189  
   190  func (cfg *CachingBucketConfig) FindExistConfig(name string) (string, *ExistsConfig) {
   191  	for n, cfg := range cfg.exists {
   192  		if cfg.Matcher(name) {
   193  			return n, cfg
   194  		}
   195  	}
   196  	return "", nil
   197  }
   198  
   199  func (cfg *CachingBucketConfig) FindGetConfig(name string) (string, *GetConfig) {
   200  	for n, cfg := range cfg.get {
   201  		if cfg.Matcher(name) {
   202  			return n, cfg
   203  		}
   204  	}
   205  	return "", nil
   206  }
   207  
   208  func (cfg *CachingBucketConfig) FindGetRangeConfig(name string) (string, *GetRangeConfig) {
   209  	for n, cfg := range cfg.getRange {
   210  		if cfg.Matcher(name) {
   211  			return n, cfg
   212  		}
   213  	}
   214  	return "", nil
   215  }
   216  
   217  func (cfg *CachingBucketConfig) FindAttributesConfig(name string) (string, *AttributesConfig) {
   218  	for n, cfg := range cfg.attributes {
   219  		if cfg.Matcher(name) {
   220  			return n, cfg
   221  		}
   222  	}
   223  	return "", nil
   224  }