Skip to content

Commit d22fb9e

Browse files
authored
Exclude expired keys in data retrieval methods
1 parent 1e6fd11 commit d22fb9e

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

cache.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,8 @@ func (c *Cache[K, V]) Has(key K) bool {
339339
c.items.mu.RLock()
340340
defer c.items.mu.RUnlock()
341341

342-
_, ok := c.items.values[key]
343-
return ok
342+
elem, ok := c.items.values[key]
343+
return ok && !elem.Value.(*Item[K, V]).isExpiredUnsafe()
344344
}
345345

346346
// GetOrSet retrieves an item from the cache by the provided key.
@@ -440,22 +440,31 @@ func (c *Cache[K, V]) Touch(key K) {
440440
c.items.mu.Unlock()
441441
}
442442

443-
// Len returns the total number of items in the cache.
443+
// Len returns the number of unexpired items in the cache.
444444
func (c *Cache[K, V]) Len() int {
445445
c.items.mu.RLock()
446446
defer c.items.mu.RUnlock()
447447

448-
return len(c.items.values)
448+
size := 0
449+
for _, elem := range c.items.values {
450+
if !elem.Value.(*Item[K, V]).isExpiredUnsafe() {
451+
size++
452+
}
453+
}
454+
455+
return size
449456
}
450457

451-
// Keys returns all keys currently present in the cache.
458+
// Keys returns all unexpired keys in the cache.
452459
func (c *Cache[K, V]) Keys() []K {
453460
c.items.mu.RLock()
454461
defer c.items.mu.RUnlock()
455462

456-
res := make([]K, 0, len(c.items.values))
457-
for k := range c.items.values {
458-
res = append(res, k)
463+
res := make([]K, 0)
464+
for k, elem := range c.items.values {
465+
if !elem.Value.(*Item[K, V]).isExpiredUnsafe() {
466+
res = append(res, k)
467+
}
459468
}
460469

461470
return res
@@ -478,7 +487,7 @@ func (c *Cache[K, V]) Items() map[K]*Item[K, V] {
478487
return items
479488
}
480489

481-
// Range calls fn for each item present in the cache. If fn returns false,
490+
// Range calls fn for each unexpired item in the cache. If fn returns false,
482491
// Range stops the iteration.
483492
func (c *Cache[K, V]) Range(fn func(item *Item[K, V]) bool) {
484493
c.items.mu.RLock()
@@ -491,9 +500,10 @@ func (c *Cache[K, V]) Range(fn func(item *Item[K, V]) bool) {
491500

492501
for item := c.items.lru.Front(); item != c.items.lru.Back().Next(); item = item.Next() {
493502
i := item.Value.(*Item[K, V])
503+
expired := i.isExpiredUnsafe()
494504
c.items.mu.RUnlock()
495505

496-
if !fn(i) {
506+
if !expired && !fn(i) {
497507
return
498508
}
499509

cache_test.go

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -652,35 +652,12 @@ func Test_Cache_Delete(t *testing.T) {
652652
}
653653

654654
func Test_Cache_Has(t *testing.T) {
655-
cc := map[string]struct {
656-
keys []string
657-
searchKey string
658-
has bool
659-
}{
660-
"Empty cache": {
661-
keys: []string{},
662-
searchKey: "key1",
663-
has: false,
664-
},
665-
"Key exists": {
666-
keys: []string{"key1", "key2", "key3"},
667-
searchKey: "key2",
668-
has: true,
669-
},
670-
"Key doesn't exist": {
671-
keys: []string{"key1", "key2", "key3"},
672-
searchKey: "key4",
673-
has: false,
674-
},
675-
}
655+
cache := prepCache(time.Hour, "1")
656+
addToCache(cache, time.Nanosecond, "2")
676657

677-
for name, tc := range cc {
678-
t.Run(name, func(t *testing.T) {
679-
c := prepCache(NoTTL, tc.keys...)
680-
has := c.Has(tc.searchKey)
681-
assert.Equal(t, tc.has, has)
682-
})
683-
}
658+
assert.True(t, cache.Has("1"))
659+
assert.False(t, cache.Has("2"))
660+
assert.False(t, cache.Has("3"))
684661
}
685662

686663
func Test_Cache_GetOrSet(t *testing.T) {
@@ -827,11 +804,13 @@ func Test_Cache_Touch(t *testing.T) {
827804

828805
func Test_Cache_Len(t *testing.T) {
829806
cache := prepCache(time.Hour, "1", "2")
807+
addToCache(cache, time.Nanosecond, "3")
830808
assert.Equal(t, 2, cache.Len())
831809
}
832810

833811
func Test_Cache_Keys(t *testing.T) {
834812
cache := prepCache(time.Hour, "1", "2", "3")
813+
addToCache(cache, time.Nanosecond, "4")
835814
assert.ElementsMatch(t, []string{"1", "2", "3"}, cache.Keys())
836815
}
837816

@@ -851,6 +830,7 @@ func Test_Cache_Items(t *testing.T) {
851830

852831
func Test_Cache_Range(t *testing.T) {
853832
c := prepCache(DefaultTTL, "1", "2", "3", "4", "5")
833+
addToCache(c, time.Nanosecond, "6")
854834
var results []string
855835

856836
c.Range(func(item *Item[string, string]) bool {

0 commit comments

Comments
 (0)