From 0086967dc945ea732dcca604b3fc87dab4b2984b Mon Sep 17 00:00:00 2001 From: Raphael Cohen Date: Sat, 28 Oct 2023 11:24:54 +0200 Subject: [PATCH 1/2] feat: Add function to check if cache contains a key --- bigcache.go | 7 +++++++ bigcache_test.go | 28 ++++++++++++++++++++++++++++ shard.go | 10 ++++++++++ 3 files changed, 45 insertions(+) diff --git a/bigcache.go b/bigcache.go index 5620c0ef..afb7b2ba 100644 --- a/bigcache.go +++ b/bigcache.go @@ -229,6 +229,13 @@ func (c *BigCache) Iterator() *EntryInfoIterator { return newIterator(c) } +// Contains returns whether the given key exists in cache +func (c *BigCache) Contains(key string) bool { + hashedKey := c.hash.Sum64(key) + shard := c.getShard(hashedKey) + return shard.contains(key, hashedKey) +} + func (c *BigCache) onEvict(oldestEntry []byte, currentTimestamp uint64, evict func(reason RemoveReason) error) bool { oldestTimestamp := readTimestampFromEntry(oldestEntry) if currentTimestamp < oldestTimestamp { diff --git a/bigcache_test.go b/bigcache_test.go index 43ec3f57..278af117 100644 --- a/bigcache_test.go +++ b/bigcache_test.go @@ -1388,3 +1388,31 @@ func TestRemoveNonExpiredData(t *testing.T) { noError(t, err) } } + +func TestContainsExists(t *testing.T) { + t.Parallel() + + // given + cache, _ := New(context.Background(), DefaultConfig(5*time.Second)) + value := []byte("value") + + // when + cache.Set("key", value) + exists := cache.Contains("key") + + // then + assertEqual(t, true, exists) +} + +func TestContainsNotExists(t *testing.T) { + t.Parallel() + + // given + cache, _ := New(context.Background(), DefaultConfig(5*time.Second)) + + // when + exists := cache.Contains("key") + + // then + assertEqual(t, false, exists) +} diff --git a/shard.go b/shard.go index 4f03b53e..0b7c2442 100644 --- a/shard.go +++ b/shard.go @@ -117,6 +117,16 @@ func (s *cacheShard) getValidWrapEntry(key string, hashedKey uint64) ([]byte, er return wrappedEntry, nil } +func (s *cacheShard) contains(key string, hashedKey uint64) bool { + s.lock.RLock() + defer s.lock.RUnlock() + wrappedEntry, err := s.getWrappedEntry(hashedKey) + if err != nil { + return false + } + return key == readKeyFromEntry(wrappedEntry) +} + func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error { currentTimestamp := uint64(s.clock.Epoch()) From 76e25b351da68832a12d6da119bab05e47a33c56 Mon Sep 17 00:00:00 2001 From: Raphael Cohen Date: Thu, 2 Nov 2023 19:39:40 +0100 Subject: [PATCH 2/2] feat: Applies PR review suggestions --- shard.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shard.go b/shard.go index 0b7c2442..fc922e4c 100644 --- a/shard.go +++ b/shard.go @@ -119,12 +119,14 @@ func (s *cacheShard) getValidWrapEntry(key string, hashedKey uint64) ([]byte, er func (s *cacheShard) contains(key string, hashedKey uint64) bool { s.lock.RLock() - defer s.lock.RUnlock() wrappedEntry, err := s.getWrappedEntry(hashedKey) if err != nil { + s.lock.RUnlock() return false } - return key == readKeyFromEntry(wrappedEntry) + entryKey := readKeyFromEntry(wrappedEntry) + s.lock.RUnlock() + return key == entryKey } func (s *cacheShard) set(key string, hashedKey uint64, entry []byte) error {