Skip to content

Commit 822e160

Browse files
authored
ConcurrentLfu.Clear() polluted by removed items (#401)
* fix * cleanup ---------
1 parent 1e7741f commit 822e160

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -676,18 +676,37 @@ public void WhenItemDoesNotExistTryUpdateIsFalse()
676676

677677
[Fact]
678678
public void WhenClearedCacheIsEmpty()
679-
{
679+
{
680680
cache.GetOrAdd(1, k => k);
681-
cache.GetOrAdd(2, k => k);
682-
cache.DoMaintenance();
683-
681+
cache.GetOrAdd(2, k => k);
682+
684683
cache.Clear();
685-
cache.DoMaintenance();
686684

687685
cache.Count.Should().Be(0);
688686
cache.TryGet(1, out var _).Should().BeFalse();
689687
}
690688

689+
[Fact]
690+
public void WhenBackgroundMaintenanceRepeatedReadThenClearResultsInEmpty()
691+
{
692+
cache = new ConcurrentLfu<int, int>(1, 40, new BackgroundThreadScheduler(), EqualityComparer<int>.Default);
693+
694+
var overflow = 0;
695+
for (var a = 0; a < 200; a++)
696+
{
697+
for (var i = 0; i < 40; i++)
698+
{
699+
cache.GetOrAdd(i, k => k);
700+
}
701+
702+
cache.Clear();
703+
overflow += cache.Count;
704+
}
705+
706+
// there should be no iteration of the loop where count != 0
707+
overflow.Should().Be(0);
708+
}
709+
691710
[Fact]
692711
public void TrimRemovesNItems()
693712
{

BitFaster.Caching/Lfu/ConcurrentLfu.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,12 @@ private static void TakeCandidatesInLruOrder(LfuNodeList<K, V> lru, List<LfuNode
426426

427427
while (candidates.Count < itemCount && curr != null)
428428
{
429-
candidates.Add(curr);
429+
// LRUs can contain items that are already removed, skip those
430+
if (!curr.WasRemoved)
431+
{
432+
candidates.Add(curr);
433+
}
434+
430435
curr = curr.Next;
431436
}
432437
}

0 commit comments

Comments
 (0)