Skip to content

Commit 482fbab

Browse files
committed
feat: add reason to OnEvictCallback
1 parent 27252e0 commit 482fbab

File tree

5 files changed

+34
-18
lines changed

5 files changed

+34
-18
lines changed

s3fifo/s3fifo.go

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package s3fifo
33
import (
44
"container/list"
55
"context"
6-
"github.com/scalalang2/golang-fifo/types"
76
"sync"
87
"time"
8+
9+
"github.com/scalalang2/golang-fifo/types"
910
)
1011

1112
const numberOfBuckets = 100
@@ -150,7 +151,7 @@ func (s *S3FIFO[K, V]) Remove(key K) (ok bool) {
150151
s.mu.Lock()
151152
defer s.mu.Unlock()
152153
if e, ok := s.items[key]; ok {
153-
s.removeEntry(e)
154+
s.removeEntry(e, types.EvictReasonRemoved)
154155
return true
155156
}
156157

@@ -209,9 +210,9 @@ func (s *S3FIFO[K, V]) Close() {
209210
s.mu.Unlock()
210211
}
211212

212-
func (s *S3FIFO[K, V]) removeEntry(e *entry[K, V]) {
213+
func (s *S3FIFO[K, V]) removeEntry(e *entry[K, V], reason types.EvictReason) {
213214
if s.callback != nil {
214-
s.callback(e.key, e.value)
215+
s.callback(e.key, e.value, reason)
215216
}
216217

217218
if s.ghost.contains(e.key) {
@@ -256,7 +257,7 @@ func (s *S3FIFO[K, V]) deleteExpired() {
256257
}
257258

258259
for _, e := range bucket.entries {
259-
s.removeEntry(e)
260+
s.removeEntry(e, types.EvictReasonExpired)
260261
}
261262

262263
s.mu.Unlock()
@@ -292,7 +293,7 @@ func (s *S3FIFO[K, V]) evictFromSmall() {
292293
s.evictFromMain()
293294
}
294295
} else {
295-
s.removeEntry(el)
296+
s.removeEntry(el, types.EvictReasonEvicted)
296297
s.ghost.add(key)
297298
evicted = true
298299
delete(s.items, key)
@@ -314,7 +315,7 @@ func (s *S3FIFO[K, V]) evictFromMain() {
314315
s.items[key].freq -= 1
315316
s.items[key].element = s.main.PushFront(el.key)
316317
} else {
317-
s.removeEntry(el)
318+
s.removeEntry(el, types.EvictReasonEvicted)
318319
evicted = true
319320
delete(s.items, key)
320321
}

s3fifo/s3fifo_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"fortio.org/assert"
9+
"github.com/scalalang2/golang-fifo/types"
910
)
1011

1112
const noEvictionTTL = 0
@@ -192,7 +193,7 @@ func TestEvictionCallback(t *testing.T) {
192193
cache := New[int, int](10, noEvictionTTL)
193194
evicted := make(map[int]int)
194195

195-
cache.SetOnEvicted(func(key int, value int) {
196+
cache.SetOnEvicted(func(key int, value int, _ types.EvictReason) {
196197
evicted[key] = value
197198
})
198199

@@ -216,7 +217,7 @@ func TestEvictionCallbackWithTTL(t *testing.T) {
216217
var mu sync.Mutex
217218
cache := New[int, int](10, time.Second)
218219
evicted := make(map[int]int)
219-
cache.SetOnEvicted(func(key int, value int) {
220+
cache.SetOnEvicted(func(key int, value int, _ types.EvictReason) {
220221
mu.Lock()
221222
evicted[key] = value
222223
mu.Unlock()

sieve/sieve.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ func (s *Sieve[K, V]) Remove(key K) (ok bool) {
149149
s.hand = s.hand.Prev()
150150
}
151151

152-
s.removeEntry(e)
152+
s.removeEntry(e, types.EvictReasonRemoved)
153153
return true
154154
}
155155

@@ -193,7 +193,7 @@ func (s *Sieve[K, V]) Purge() {
193193
defer s.mu.Unlock()
194194

195195
for _, e := range s.items {
196-
s.removeEntry(e)
196+
s.removeEntry(e, types.EvictReasonRemoved)
197197
}
198198

199199
for i := range s.buckets {
@@ -215,9 +215,9 @@ func (s *Sieve[K, V]) Close() {
215215
s.mu.Unlock()
216216
}
217217

218-
func (s *Sieve[K, V]) removeEntry(e *entry[K, V]) {
218+
func (s *Sieve[K, V]) removeEntry(e *entry[K, V], reason types.EvictReason) {
219219
if s.callback != nil {
220-
s.callback(e.key, e.value)
220+
s.callback(e.key, e.value, reason)
221221
}
222222

223223
s.ll.Remove(e.element)
@@ -251,7 +251,7 @@ func (s *Sieve[K, V]) evict() {
251251
}
252252

253253
s.hand = o.Prev()
254-
s.removeEntry(el)
254+
s.removeEntry(el, types.EvictReasonEvicted)
255255
}
256256

257257
func (s *Sieve[K, V]) addToBucket(e *entry[K, V]) {
@@ -287,7 +287,7 @@ func (s *Sieve[K, V]) deleteExpired() {
287287
}
288288

289289
for _, e := range bucket.entries {
290-
s.removeEntry(e)
290+
s.removeEntry(e, types.EvictReasonExpired)
291291
}
292292

293293
s.mu.Unlock()

sieve/sieve_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"time"
77

88
"fortio.org/assert"
9+
"github.com/scalalang2/golang-fifo/types"
910
)
1011

1112
const noEvictionTTL = 0
@@ -146,7 +147,7 @@ func TestEvictionCallback(t *testing.T) {
146147
cache := New[int, int](10, noEvictionTTL)
147148
evicted := make(map[int]int)
148149

149-
cache.SetOnEvicted(func(key int, value int) {
150+
cache.SetOnEvicted(func(key int, value int, _ types.EvictReason) {
150151
evicted[key] = value
151152
})
152153

@@ -170,7 +171,7 @@ func TestEvictionCallbackWithTTL(t *testing.T) {
170171
var mu sync.Mutex
171172
cache := New[int, int](10, time.Second)
172173
evicted := make(map[int]int)
173-
cache.SetOnEvicted(func(key int, value int) {
174+
cache.SetOnEvicted(func(key int, value int, _ types.EvictReason) {
174175
mu.Lock()
175176
evicted[key] = value
176177
mu.Unlock()

types/types.go

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
package types
22

3-
type OnEvictCallback[K comparable, V any] func(key K, value V)
3+
// EvictReason is the reason for an entry to be evicted from the cache.
4+
// It is used in the [OnEvictCallback] function.
5+
type EvictReason int
6+
7+
const (
8+
// EvictReasonExpired is used when an item is removed because its TTL has expired.
9+
EvictReasonExpired = iota
10+
// EvictReasonEvicted is used when an item is removed because the cache size limit was exceeded.
11+
EvictReasonEvicted
12+
// EvictReasonRemoved is used when an item is explicitly deleted.
13+
EvictReasonRemoved
14+
)
15+
16+
type OnEvictCallback[K comparable, V any] func(key K, value V, reason EvictReason)
417

518
// Cache is the interface for a cache.
619
type Cache[K comparable, V any] interface {

0 commit comments

Comments
 (0)