Skip to content

Commit

Permalink
Refactor DeleteExpired for safer behavior
Browse files Browse the repository at this point in the history
- make sure that expManager queue is not empty before popping,
  which can happen if an explicit delete happens while DeleteExpired
  releases the lock.

- evict()  now returns shouldContinue instead of a shouldBreak to
  simplify the loop.
  • Loading branch information
AxelPrel committed Jun 27, 2024
1 parent a6de649 commit 064ff83
Showing 1 changed file with 10 additions and 13 deletions.
23 changes: 10 additions & 13 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ func (item *Item[K, V]) hasExpiration() bool {
return !item.Expiration.IsZero()
}

//Print tries to make a readable log of the item

// Expired returns true if the item has expired.
func (item *Item[K, V]) Expired() bool {
if !item.hasExpiration() {
Expand Down Expand Up @@ -241,31 +243,26 @@ func (c *Cache[K, V]) GetOrSet(key K, val V, opts ...ItemOption) (actual V, load

// DeleteExpired all expired items from the cache.
func (c *Cache[K, V]) DeleteExpired() {
c.mu.Lock()
l := c.expManager.len()
c.mu.Unlock()

evict := func() bool {
c.mu.Lock()
defer c.mu.Unlock()
if c.expManager.len() == 0 {
return false
}
key := c.expManager.pop()
// if is expired, delete it and return nil instead
item, ok := c.cache.Get(key)
if ok {
if item.Expired() {
c.cache.Delete(key)
return false
return true
}
c.expManager.update(key, item.Expiration)
}
return true
return false
}

for i := 0; i < l; i++ {
c.mu.Lock()
shouldBreak := evict()
c.mu.Unlock()
if shouldBreak {
break
}
for evict() {
}
}

Expand Down

0 comments on commit 064ff83

Please sign in to comment.