Skip to content

Commit 47a547e

Browse files
authored
Mark LRU as cold during trim (#476)
1 parent 226e561 commit 47a547e

File tree

3 files changed

+76
-10
lines changed

3 files changed

+76
-10
lines changed

BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,25 @@ public void WhenWarmThenClearedIsWarmIsReset()
953953
lru.Count.Should().Be(capacity.Hot + capacity.Warm + capacity.Cold);
954954
}
955955

956+
[Fact]
957+
public void WhenWarmThenTrimIsWarmIsReset()
958+
{
959+
for (int i = 0; i < 20; i++)
960+
{
961+
lru.GetOrAdd(i, k => k.ToString());
962+
}
963+
964+
lru.Trim(6);
965+
lru.Count.Should().Be(3);
966+
967+
for (int i = 0; i < 20; i++)
968+
{
969+
lru.GetOrAdd(i, k => k.ToString());
970+
}
971+
972+
lru.Count.Should().Be(capacity.Hot + capacity.Warm + capacity.Cold);
973+
}
974+
956975
[Fact]
957976
public void WhenItemsAreDisposableClearDisposesItemsOnRemove()
958977
{

BitFaster.Caching.UnitTests/Lru/ConcurrentTLruTests.cs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
using BitFaster.Caching.Lru;
33
using System;
44
using System.Collections.Generic;
5-
using System.Threading.Tasks;
65
using Xunit;
76
using System.Runtime.InteropServices;
8-
using System.Threading;
97

108
namespace BitFaster.Caching.UnitTests.Lru
119
{
@@ -166,6 +164,45 @@ public void WhenItemsAreExpiredExpireRemovesExpiredItems()
166164
);
167165
}
168166

167+
[Fact]
168+
public void WhenExpiredItemsAreTrimmedCacheMarkedCold()
169+
{
170+
Timed.Execute(
171+
lru,
172+
lru =>
173+
{
174+
lru.AddOrUpdate(1, "1");
175+
lru.AddOrUpdate(2, "2");
176+
lru.AddOrUpdate(3, "3");
177+
lru.GetOrAdd(1, valueFactory.Create);
178+
lru.GetOrAdd(2, valueFactory.Create);
179+
lru.GetOrAdd(3, valueFactory.Create);
180+
181+
lru.AddOrUpdate(4, "4");
182+
lru.AddOrUpdate(5, "5");
183+
lru.AddOrUpdate(6, "6");
184+
185+
lru.AddOrUpdate(7, "7");
186+
lru.AddOrUpdate(8, "8");
187+
lru.AddOrUpdate(9, "9");
188+
189+
return lru;
190+
},
191+
timeToLive.MultiplyBy(ttlWaitMlutiplier),
192+
lru =>
193+
{
194+
lru.Policy.ExpireAfterWrite.Value.TrimExpired();
195+
196+
for (int i = 0; i < lru.Policy.Eviction.Value.Capacity; i++)
197+
{
198+
lru.GetOrAdd(i, k => k.ToString());
199+
}
200+
201+
lru.Count.Should().Be(lru.Policy.Eviction.Value.Capacity);
202+
}
203+
);
204+
}
205+
169206
[Fact]
170207
public void WhenCacheHasExpiredAndFreshItemsExpireRemovesOnlyExpiredItems()
171208
{

BitFaster.Caching/Lru/ConcurrentLruCore.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,6 @@ public void AddOrUpdate(K key, V value)
423423
public void Clear()
424424
{
425425
this.TrimLiveItems(itemsRemoved: 0, this.Count, ItemRemovedReason.Cleared);
426-
Volatile.Write(ref this.isWarm, false);
427426
}
428427

429428
/// <summary>
@@ -468,10 +467,9 @@ private void TrimExpired()
468467
// backcompat: make internal
469468
protected int TrimAllDiscardedItems()
470469
{
471-
int itemsRemoved = 0;
472-
473-
void RemoveDiscardableItems(ConcurrentQueue<I> q, ref int queueCounter)
470+
int RemoveDiscardableItems(ConcurrentQueue<I> q, ref int queueCounter)
474471
{
472+
int itemsRemoved = 0;
475473
int localCount = queueCounter;
476474

477475
for (int i = 0; i < localCount; i++)
@@ -490,13 +488,20 @@ void RemoveDiscardableItems(ConcurrentQueue<I> q, ref int queueCounter)
490488
}
491489
}
492490
}
491+
492+
return itemsRemoved;
493493
}
494494

495-
RemoveDiscardableItems(coldQueue, ref this.counter.cold);
496-
RemoveDiscardableItems(warmQueue, ref this.counter.warm);
497-
RemoveDiscardableItems(hotQueue, ref this.counter.hot);
495+
int coldRem = RemoveDiscardableItems(coldQueue, ref this.counter.cold);
496+
int warmRem = RemoveDiscardableItems(warmQueue, ref this.counter.warm);
497+
int hotRem = RemoveDiscardableItems(hotQueue, ref this.counter.hot);
498+
499+
if (warmRem > 0)
500+
{
501+
Volatile.Write(ref this.isWarm, false);
502+
}
498503

499-
return itemsRemoved;
504+
return coldRem + warmRem + hotRem;
500505
}
501506

502507
private void TrimLiveItems(int itemsRemoved, int itemCount, ItemRemovedReason reason)
@@ -526,6 +531,11 @@ private void TrimLiveItems(int itemsRemoved, int itemCount, ItemRemovedReason re
526531
trimWarmAttempts++;
527532
}
528533
}
534+
535+
if (Volatile.Read(ref this.counter.warm) < this.capacity.Warm)
536+
{
537+
Volatile.Write(ref this.isWarm, false);
538+
}
529539
}
530540

531541
private void TrimWarmOrHot(ItemRemovedReason reason)

0 commit comments

Comments
 (0)