@@ -8,6 +8,8 @@ package bucketcache
8
8
import (
9
9
"bytes"
10
10
"context"
11
+ "crypto"
12
+ "encoding/hex"
11
13
"encoding/json"
12
14
"io"
13
15
"strconv"
@@ -165,20 +167,22 @@ func NewCachingBucket(bucketID string, bucketClient objstore.Bucket, cfg *Cachin
165
167
}
166
168
167
169
func (cb * CachingBucket ) Upload (ctx context.Context , name string , r io.Reader ) error {
168
- cb .invalidation .start (ctx , name )
170
+ hashedName := cachingKeyHash (name )
171
+ cb .invalidation .start (ctx , name , hashedName )
169
172
err := cb .Bucket .Upload (ctx , name , r )
170
173
if err == nil {
171
- cb .invalidation .finish (ctx , name )
174
+ cb .invalidation .finish (ctx , name , hashedName )
172
175
}
173
176
174
177
return err
175
178
}
176
179
177
180
func (cb * CachingBucket ) Delete (ctx context.Context , name string ) error {
178
- cb .invalidation .start (ctx , name )
181
+ hashedName := cachingKeyHash (name )
182
+ cb .invalidation .start (ctx , name , hashedName )
179
183
err := cb .Bucket .Delete (ctx , name )
180
184
if err == nil {
181
- cb .invalidation .finish (ctx , name )
185
+ cb .invalidation .finish (ctx , name , hashedName )
182
186
}
183
187
184
188
return err
@@ -259,8 +263,9 @@ func (cb *CachingBucket) Exists(ctx context.Context, name string) (bool, error)
259
263
return cb .Bucket .Exists (ctx , name )
260
264
}
261
265
262
- key := cachingKeyExists (cb .bucketID , name )
263
- lockKey := cachingKeyExistsLock (cb .bucketID , name )
266
+ hashedName := cachingKeyHash (name )
267
+ key := cachingKeyExists (cb .bucketID , hashedName )
268
+ lockKey := cachingKeyExistsLock (cb .bucketID , hashedName )
264
269
265
270
// Lookup the cache.
266
271
if isCacheLookupEnabled (ctx ) {
@@ -308,10 +313,11 @@ func (cb *CachingBucket) Get(ctx context.Context, name string) (io.ReadCloser, e
308
313
return cb .Bucket .Get (ctx , name )
309
314
}
310
315
311
- contentLockKey := cachingKeyContentLock (cb .bucketID , name )
312
- contentKey := cachingKeyContent (cb .bucketID , name )
313
- existsLockKey := cachingKeyExistsLock (cb .bucketID , name )
314
- existsKey := cachingKeyExists (cb .bucketID , name )
316
+ hashedName := cachingKeyHash (name )
317
+ contentLockKey := cachingKeyContentLock (cb .bucketID , hashedName )
318
+ contentKey := cachingKeyContent (cb .bucketID , hashedName )
319
+ existsLockKey := cachingKeyExistsLock (cb .bucketID , hashedName )
320
+ existsKey := cachingKeyExists (cb .bucketID , hashedName )
315
321
316
322
// Lookup the cache.
317
323
if isCacheLookupEnabled (ctx ) {
@@ -393,7 +399,8 @@ func (cb *CachingBucket) GetRange(ctx context.Context, name string, off, length
393
399
return cb .Bucket .GetRange (ctx , name , off , length )
394
400
}
395
401
396
- return cb .cachedGetRange (ctx , name , off , length , cfgName , cfg )
402
+ hashedName := cachingKeyHash (name )
403
+ return cb .cachedGetRange (ctx , name , hashedName , off , length , cfgName , cfg )
397
404
}
398
405
399
406
func (cb * CachingBucket ) Attributes (ctx context.Context , name string ) (objstore.ObjectAttributes , error ) {
@@ -402,12 +409,13 @@ func (cb *CachingBucket) Attributes(ctx context.Context, name string) (objstore.
402
409
return cb .Bucket .Attributes (ctx , name )
403
410
}
404
411
405
- return cb .cachedAttributes (ctx , name , cfgName , cfg .cache , cfg .ttl )
412
+ hashedName := cachingKeyHash (name )
413
+ return cb .cachedAttributes (ctx , name , hashedName , cfgName , cfg .cache , cfg .ttl )
406
414
}
407
415
408
- func (cb * CachingBucket ) cachedAttributes (ctx context.Context , name , cfgName string , cache cache.Cache , ttl time.Duration ) (objstore.ObjectAttributes , error ) {
409
- lockKey := cachingKeyAttributesLock (cb .bucketID , name )
410
- key := cachingKeyAttributes (cb .bucketID , name )
416
+ func (cb * CachingBucket ) cachedAttributes (ctx context.Context , name , hashedName , cfgName string , cache cache.Cache , ttl time.Duration ) (objstore.ObjectAttributes , error ) {
417
+ lockKey := cachingKeyAttributesLock (cb .bucketID , hashedName )
418
+ key := cachingKeyAttributes (cb .bucketID , hashedName )
411
419
412
420
// Lookup the cache.
413
421
if isCacheLookupEnabled (ctx ) {
@@ -445,8 +453,8 @@ func (cb *CachingBucket) cachedAttributes(ctx context.Context, name, cfgName str
445
453
return attrs , nil
446
454
}
447
455
448
- func (cb * CachingBucket ) cachedGetRange (ctx context.Context , name string , offset , length int64 , cfgName string , cfg * getRangeConfig ) (io.ReadCloser , error ) {
449
- attrs , err := cb .cachedAttributes (ctx , name , cfgName , cfg .attributes .cache , cfg .attributes .ttl )
456
+ func (cb * CachingBucket ) cachedGetRange (ctx context.Context , name , hashedName string , offset , length int64 , cfgName string , cfg * getRangeConfig ) (io.ReadCloser , error ) {
457
+ attrs , err := cb .cachedAttributes (ctx , name , hashedName , cfgName , cfg .attributes .cache , cfg .attributes .ttl )
450
458
if err != nil {
451
459
return nil , errors .Wrapf (err , "failed to get object attributes: %s" , name )
452
460
}
@@ -484,7 +492,7 @@ func (cb *CachingBucket) cachedGetRange(ctx context.Context, name string, offset
484
492
}
485
493
totalRequestedBytes += (end - off )
486
494
487
- k := cachingKeyObjectSubrange (cb .bucketID , name , off , end )
495
+ k := cachingKeyObjectSubrange (cb .bucketID , hashedName , off , end )
488
496
keys = append (keys , k )
489
497
offsetKeys [off ] = k
490
498
}
@@ -663,7 +671,7 @@ func newCacheInvalidation(bucketID string, cfg *CachingBucketConfig, logger log.
663
671
// prevent new cache entries for that item from being stored. This ensures that when the
664
672
// cache entries for the item are deleted after it is mutated, reads which try to "add"
665
673
// the lock key cannot and will go directly to object storage for a short period of time.
666
- func (i * cacheInvalidation ) start (ctx context.Context , name string ) {
674
+ func (i * cacheInvalidation ) start (ctx context.Context , name , hashedName string ) {
667
675
logger := spanlogger .FromContext (ctx , i .logger )
668
676
669
677
_ , attrCfg := i .cfg .findAttributesConfig (name )
@@ -673,9 +681,9 @@ func (i *cacheInvalidation) start(ctx context.Context, name string) {
673
681
existCfg = & getCfg .existsConfig
674
682
}
675
683
676
- attrLockKey := cachingKeyAttributesLock (i .bucketID , name )
677
- contentLockKey := cachingKeyContentLock (i .bucketID , name )
678
- existsLockKey := cachingKeyExistsLock (i .bucketID , name )
684
+ attrLockKey := cachingKeyAttributesLock (i .bucketID , hashedName )
685
+ contentLockKey := cachingKeyContentLock (i .bucketID , hashedName )
686
+ existsLockKey := cachingKeyExistsLock (i .bucketID , hashedName )
679
687
680
688
if attrCfg != nil || getCfg != nil || existCfg != nil {
681
689
err := i .runWithRetries (ctx , func () error {
@@ -703,7 +711,7 @@ func (i *cacheInvalidation) start(ctx context.Context, name string) {
703
711
// finish removes attribute, existence, and content entries in a cache associated with
704
712
// a given item. Note that it does not remove the "lock" entries in the cache to ensure
705
713
// that other requests must read directly from object storage until the lock expires.
706
- func (i * cacheInvalidation ) finish (ctx context.Context , name string ) {
714
+ func (i * cacheInvalidation ) finish (ctx context.Context , name , hashedName string ) {
707
715
logger := spanlogger .FromContext (ctx , i .logger )
708
716
709
717
_ , attrCfg := i .cfg .findAttributesConfig (name )
@@ -713,9 +721,9 @@ func (i *cacheInvalidation) finish(ctx context.Context, name string) {
713
721
existCfg = & getCfg .existsConfig
714
722
}
715
723
716
- attrKey := cachingKeyAttributes (i .bucketID , name )
717
- contentKey := cachingKeyContent (i .bucketID , name )
718
- existsKey := cachingKeyExists (i .bucketID , name )
724
+ attrKey := cachingKeyAttributes (i .bucketID , hashedName )
725
+ contentKey := cachingKeyContent (i .bucketID , hashedName )
726
+ existsKey := cachingKeyExists (i .bucketID , hashedName )
719
727
720
728
if attrCfg != nil || getCfg != nil || existCfg != nil {
721
729
err := i .runWithRetries (ctx , func () error {
@@ -772,6 +780,13 @@ func (i *cacheInvalidation) runWithRetries(ctx context.Context, f func() error)
772
780
return retry .Err ()
773
781
}
774
782
783
+ func cachingKeyHash (name string ) string {
784
+ hasher := crypto .SHA3_256 .New ()
785
+ _ , _ = hasher .Write ([]byte (name )) // This will never error.
786
+ // Hex because memcache keys must be non-whitespace non-control ASCII
787
+ return hex .EncodeToString (hasher .Sum (nil ))
788
+ }
789
+
775
790
func cachingKeyAttributes (bucketID , name string ) string {
776
791
return composeCachingKey ("attrs" , bucketID , name )
777
792
}
0 commit comments