Skip to content

Commit

Permalink
Merge branch 'main' into users/alexpeck/v2.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
bitfaster authored Oct 5, 2023
2 parents 0065097 + 26063a4 commit 09a88ad
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="Moq" Version="4.20.69" />
<PackageReference Include="xunit" Version="2.5.0" />
<PackageReference Include="xunit" Version="2.5.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
37 changes: 28 additions & 9 deletions BitFaster.Caching.UnitTests/Lfu/ConcurrentLfuTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ public void WhenKeyIsRequestedWithArgItIsCreatedAndCached()
[Fact]
public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync()
{
var result1 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result2 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result1 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync);
var result2 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand All @@ -66,8 +66,8 @@ public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync()
[Fact]
public async Task WhenKeyIsRequestedWithArgItIsCreatedAndCachedAsync()
{
var result1 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync, 9).ConfigureAwait(false);
var result2 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync, 17).ConfigureAwait(false);
var result1 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync, 9);
var result2 = await cache.GetOrAddAsync(1, valueFactory.CreateAsync, 17);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand Down Expand Up @@ -676,18 +676,37 @@ public void WhenItemDoesNotExistTryUpdateIsFalse()

[Fact]
public void WhenClearedCacheIsEmpty()
{
{
cache.GetOrAdd(1, k => k);
cache.GetOrAdd(2, k => k);
cache.DoMaintenance();

cache.GetOrAdd(2, k => k);

cache.Clear();
cache.DoMaintenance();

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

[Fact]
public void WhenBackgroundMaintenanceRepeatedReadThenClearResultsInEmpty()
{
cache = new ConcurrentLfu<int, int>(1, 40, new BackgroundThreadScheduler(), EqualityComparer<int>.Default);

var overflow = 0;
for (var a = 0; a < 200; a++)
{
for (var i = 0; i < 40; i++)
{
cache.GetOrAdd(i, k => k);
}

cache.Clear();
overflow += cache.Count;
}

// there should be no iteration of the loop where count != 0
overflow.Should().Be(0);
}

[Fact]
public void TrimRemovesNItems()
{
Expand Down
12 changes: 6 additions & 6 deletions BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ public void WhenKeyIsRequestedWithArgItIsCreatedAndCached()
[Fact]
public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand All @@ -205,8 +205,8 @@ public async Task WhenKeyIsRequesteItIsCreatedAndCachedAsync()
[Fact]
public async Task WhenKeyIsRequestedWithArgItIsCreatedAndCachedAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "x").ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "y").ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "x");
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "y");

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand All @@ -227,8 +227,8 @@ public void WhenDifferentKeysAreRequestedValueIsCreatedForEach()
[Fact]
public async Task WhenDifferentKeysAreRequesteValueIsCreatedForEachAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(2, valueFactory.CreateAsync).ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);
var result2 = await lru.GetOrAddAsync(2, valueFactory.CreateAsync);

valueFactory.timesCalled.Should().Be(2);

Expand Down
33 changes: 26 additions & 7 deletions BitFaster.Caching.UnitTests/Lru/ConcurrentLruTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void WhenItemIsAddedCountIsCorrect()
public async Task WhenItemIsAddedCountIsCorrectAsync()
{
lru.Count.Should().Be(0);
await lru.GetOrAddAsync(0, valueFactory.CreateAsync).ConfigureAwait(false);
await lru.GetOrAddAsync(0, valueFactory.CreateAsync);
lru.Count.Should().Be(1);
}

Expand Down Expand Up @@ -261,8 +261,8 @@ public void WhenKeyIsRequestedWithArgItIsCreatedAndCached()
[Fact]
public async Task WhenKeyIsRequestedItIsCreatedAndCachedAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand All @@ -271,8 +271,8 @@ public async Task WhenKeyIsRequestedItIsCreatedAndCachedAsync()
[Fact]
public async Task WhenKeyIsRequestedWithArgItIsCreatedAndCachedAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "x").ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "y").ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "x");
var result2 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync, "y");

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
Expand All @@ -293,8 +293,8 @@ public void WhenDifferentKeysAreRequestedValueIsCreatedForEach()
[Fact]
public async Task WhenDifferentKeysAreRequesteValueIsCreatedForEachAsync()
{
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync).ConfigureAwait(false);
var result2 = await lru.GetOrAddAsync(2, valueFactory.CreateAsync).ConfigureAwait(false);
var result1 = await lru.GetOrAddAsync(1, valueFactory.CreateAsync);
var result2 = await lru.GetOrAddAsync(2, valueFactory.CreateAsync);

valueFactory.timesCalled.Should().Be(2);

Expand Down Expand Up @@ -866,6 +866,25 @@ public void WhenItemsExistClearRemovesAllItems()
lru.HotCount.Should().Be(0);
lru.WarmCount.Should().Be(0);
lru.ColdCount.Should().Be(0);
}

[Fact]
public void WhenWarmThenClearedIsWarmIsReset()
{
for (int i = 0; i < 20; i++)
{
lru.GetOrAdd(i, k => k.ToString());
}

lru.Clear();
lru.Count.Should().Be(0);

for (int i = 0; i < 20; i++)
{
lru.GetOrAdd(i, k => k.ToString());
}

lru.Count.Should().Be(capacity.Hot + capacity.Warm + capacity.Cold);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ public async Task WhenWorkThrowsLastExceptionIsPopulated()
[Fact]
public void WhenBacklogExceededTasksAreDropped()
{
var tcs = new TaskCompletionSource<bool>();
var mre = new ManualResetEvent(false);

for (int i = 0; i < BackgroundThreadScheduler.MaxBacklog * 2; i++)
{
scheduler.Run(() => { tcs.Task.Wait(); });
scheduler.Run(() => { mre.WaitOne(); });
}

tcs.SetResult(true);
mre.Set();

scheduler.RunCount.Should().BeCloseTo(BackgroundThreadScheduler.MaxBacklog, 1);
}
Expand Down
7 changes: 6 additions & 1 deletion BitFaster.Caching/Lfu/ConcurrentLfu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,12 @@ private static void TakeCandidatesInLruOrder(LfuNodeList<K, V> lru, List<LfuNode

while (candidates.Count < itemCount && curr != null)
{
candidates.Add(curr);
// LRUs can contain items that are already removed, skip those
if (!curr.WasRemoved)
{
candidates.Add(curr);
}

curr = curr.Next;
}
}
Expand Down
2 changes: 2 additions & 0 deletions BitFaster.Caching/Lru/ConcurrentLruCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,8 @@ public void Clear()
CycleWarmUnchecked(ItemRemovedReason.Cleared);
TryRemoveCold(ItemRemovedReason.Cleared);
}

Volatile.Write(ref this.isWarm, false);
}

/// <summary>
Expand Down

0 comments on commit 09a88ad

Please sign in to comment.