Skip to content

Commit 59ea4b2

Browse files
authored
fix(shard): ensure correct evicted entries count (#30)
When evicting all entries (100% eviction), store the count before clearing the map. Previously we were reporting the length of an empty map, resulting in incorrect eviction metrics. The fix ensures accurate reporting of mass evictions for monitoring cache behavior. Added test coverage to verify both the evicted entries count and forced eviction events are correct. Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
1 parent e2d1302 commit 59ea4b2

2 files changed

Lines changed: 26 additions & 5 deletions

File tree

cache_test.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,20 +181,40 @@ func TestForceEvictAllEntries(t *testing.T) {
181181
ttl := time.Hour
182182
evictionpercentage := 100
183183
clock := sturdyc.NewTestClock(time.Now())
184+
metricRecorder := newTestMetricsRecorder(numShards)
184185
c := sturdyc.New[string](capacity, numShards, ttl, evictionpercentage,
185186
sturdyc.WithClock(clock),
187+
sturdyc.WithMetrics(metricRecorder),
186188
)
187189

188-
// Now we're going to write 101 records to the cache which should
189-
// exceed its capacity and trigger a forced eviction.
190-
for i := 0; i < 101; i++ {
190+
// Fill the cache to capacity
191+
for i := 0; i < capacity; i++ {
191192
c.Set(strconv.Itoa(i), strconv.Itoa(i))
192193
}
193194

195+
// Record metrics before eviction
196+
preEvictionCount := metricRecorder.evictedEntries
197+
198+
// Trigger eviction by adding one more entry
194199
// When the eviction is triggered by the 100th write, we expect the cache to
195200
// be emptied. Therefore, the 101th write should mean that the size is now 1.
201+
c.Set("trigger", "value")
202+
203+
// When the eviction is triggered, we expect the cache to be emptied
204+
// and only contain the trigger value
196205
if c.Size() != 1 {
197-
t.Errorf("expected cache size to be 0, got %d", c.Size())
206+
t.Errorf("expected cache size to be 1, got %d", c.Size())
207+
}
208+
209+
// Verify eviction metrics
210+
metricRecorder.Lock()
211+
defer metricRecorder.Unlock()
212+
evictedEntries := metricRecorder.evictedEntries - preEvictionCount
213+
if evictedEntries != capacity {
214+
t.Errorf("got %d evicted entries, want %d", evictedEntries, capacity)
215+
}
216+
if metricRecorder.forcedEvictions != 1 {
217+
t.Errorf("got %d forced eviction events, want 1", metricRecorder.forcedEvictions)
198218
}
199219
}
200220

shard.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ func (s *shard[T]) forceEvict() {
6767

6868
// Check if we should evict all entries.
6969
if s.evictionPercentage == 100 {
70+
evictedCount := len(s.entries)
7071
s.entries = make(map[string]*entry[T])
71-
s.reportEntriesEvicted(len(s.entries))
72+
s.reportEntriesEvicted(evictedCount)
7273
return
7374
}
7475

0 commit comments

Comments
 (0)