github.com/thanos-io/thanos@v0.32.5/internal/cortex/chunk/cache/cache_gen.go (about) 1 // Copyright (c) The Cortex Authors. 2 // Licensed under the Apache License 2.0. 3 4 package cache 5 6 import ( 7 "context" 8 ) 9 10 type contextKey int 11 12 // cacheGenContextKey is used for setting a Cache Generation number in context. 13 const cacheGenContextKey contextKey = 0 14 15 // GenNumMiddleware adds gen number to keys from context. Expected size of gen numbers is upto 2 digits. 16 // If we start seeing problems with keys exceeding length limit, we need to look into resetting gen numbers. 17 type GenNumMiddleware struct { 18 downstreamCache Cache 19 } 20 21 // NewCacheGenNumMiddleware creates a new GenNumMiddleware. 22 func NewCacheGenNumMiddleware(downstreamCache Cache) Cache { 23 return &GenNumMiddleware{downstreamCache} 24 } 25 26 // Store adds cache gen number to keys before calling Store method of downstream cache. 27 func (c GenNumMiddleware) Store(ctx context.Context, keys []string, buf [][]byte) { 28 keys = addCacheGenNumToCacheKeys(ctx, keys) 29 c.downstreamCache.Store(ctx, keys, buf) 30 } 31 32 // Fetch adds cache gen number to keys before calling Fetch method of downstream cache. 33 // It also removes gen number before responding back with found and missing keys to make sure consumer of response gets to see same keys. 34 func (c GenNumMiddleware) Fetch(ctx context.Context, keys []string) (found []string, bufs [][]byte, missing []string) { 35 keys = addCacheGenNumToCacheKeys(ctx, keys) 36 37 found, bufs, missing = c.downstreamCache.Fetch(ctx, keys) 38 39 found = removeCacheGenNumFromKeys(ctx, found) 40 missing = removeCacheGenNumFromKeys(ctx, missing) 41 42 return 43 } 44 45 // Stop calls Stop method of downstream cache. 46 func (c GenNumMiddleware) Stop() { 47 c.downstreamCache.Stop() 48 } 49 50 // InjectCacheGenNumber returns a derived context containing the cache gen. 51 func InjectCacheGenNumber(ctx context.Context, cacheGen string) context.Context { 52 return context.WithValue(ctx, interface{}(cacheGenContextKey), cacheGen) 53 } 54 55 // ExtractCacheGenNumbersFromHeaders gets the cache gen from the context. 56 func ExtractCacheGenNumber(ctx context.Context) string { 57 cacheGenNumber, ok := ctx.Value(cacheGenContextKey).(string) 58 if !ok { 59 return "" 60 } 61 return cacheGenNumber 62 } 63 64 // addCacheGenNumToCacheKeys adds gen number to keys as prefix. 65 func addCacheGenNumToCacheKeys(ctx context.Context, keys []string) []string { 66 cacheGen := ExtractCacheGenNumber(ctx) 67 if cacheGen == "" { 68 return keys 69 } 70 71 prefixedKeys := make([]string, len(keys)) 72 73 for i := range keys { 74 prefixedKeys[i] = cacheGen + keys[i] 75 } 76 77 return prefixedKeys 78 } 79 80 // removeCacheGenNumFromKeys removes prefixed gen number from keys. 81 func removeCacheGenNumFromKeys(ctx context.Context, keys []string) []string { 82 cacheGen := ExtractCacheGenNumber(ctx) 83 if cacheGen == "" { 84 return keys 85 } 86 87 unprefixedKeys := make([]string, len(keys)) 88 cacheGenPrefixLen := len(cacheGen) 89 90 for i := range keys { 91 unprefixedKeys[i] = keys[i][cacheGenPrefixLen:] 92 } 93 94 return unprefixedKeys 95 }