aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/allegro/bigcache/shard.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/allegro/bigcache/shard.go')
-rw-r--r--vendor/github.com/allegro/bigcache/shard.go41
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