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 }