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())