diff options
Diffstat (limited to 'vendor/github.com/allegro/bigcache/shard.go')
-rw-r--r-- | vendor/github.com/allegro/bigcache/shard.go | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/vendor/github.com/allegro/bigcache/shard.go b/vendor/github.com/allegro/bigcache/shard.go index 56a9fb089..a31094ff3 100644 --- a/vendor/github.com/allegro/bigcache/shard.go +++ b/vendor/github.com/allegro/bigcache/shard.go @@ -32,7 +32,7 @@ func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) { if itemIndex == 0 { s.lock.RUnlock() s.miss() - return nil, notFound(key) + return nil, ErrEntryNotFound } wrappedEntry, err := s.entries.Get(int(itemIndex)) @@ -47,11 +47,12 @@ func (s *cacheShard) get(key string, hashedKey uint64) ([]byte, error) { } s.lock.RUnlock() s.collision() - return nil, notFound(key) + return nil, ErrEntryNotFound } + entry := readEntry(wrappedEntry) s.lock.RUnlock() s.hit() - return readEntry(wrappedEntry), nil + return entry, nil } func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error { @@ -85,17 +86,17 @@ func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error { } func (s *cacheShard) del(key string, hashedKey uint64) error { + // Optimistic pre-check using only readlock s.lock.RLock() itemIndex := s.hashmap[hashedKey] if itemIndex == 0 { s.lock.RUnlock() s.delmiss() - return notFound(key) + return ErrEntryNotFound } - wrappedEntry, err := s.entries.Get(int(itemIndex)) - if err != nil { + if err := s.entries.CheckGet(int(itemIndex)); err != nil { s.lock.RUnlock() s.delmiss() return err @@ -104,6 +105,23 @@ func (s *cacheShard) del(key string, hashedKey uint64) error { s.lock.Lock() { + // After obtaining the writelock, we need to read the same again, + // since the data delivered earlier may be stale now + itemIndex = s.hashmap[hashedKey] + + if itemIndex == 0 { + s.lock.Unlock() + s.delmiss() + return ErrEntryNotFound + } + + wrappedEntry, err := s.entries.Get(int(itemIndex)) + if err != nil { + s.lock.Unlock() + s.delmiss() + return err + } + delete(s.hashmap, hashedKey) s.onRemove(wrappedEntry, Deleted) resetKeyFromEntry(wrappedEntry) @@ -136,17 +154,22 @@ func (s *cacheShard) cleanUp(currentTimestamp uint64) { } func (s *cacheShard) getOldestEntry() ([]byte, error) { + s.lock.RLock() + defer s.lock.RUnlock() return s.entries.Peek() } func (s *cacheShard) getEntry(index int) ([]byte, error) { - return s.entries.Get(index) + s.lock.RLock() + entry, err := s.entries.Get(index) + s.lock.RUnlock() + + return entry, err } func (s *cacheShard) copyKeys() (keys []uint32, next int) { - keys = make([]uint32, len(s.hashmap)) - s.lock.RLock() + keys = make([]uint32, len(s.hashmap)) for _, index := range s.hashmap { keys[next] = index |