Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
322 changes: 161 additions & 161 deletions BitFaster.Caching.UnitTests/Lru/ClassicLruTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@

namespace BitFaster.Caching.UnitTests.Lru
{
public class ClassicLruTests
{
private const int capacity = 3;
public class ClassicLruTests
{
private const int capacity = 3;

private ClassicLru<int, string> lru = new ClassicLru<int, string>(1, capacity, EqualityComparer<int>.Default);
ValueFactory valueFactory = new ValueFactory();
private ClassicLru<int, string> lru = new ClassicLru<int, string>(1, capacity, EqualityComparer<int>.Default);
ValueFactory valueFactory = new ValueFactory();

[Fact]
public void WhenConcurrencyIsLessThan1CtorThrows()
Expand Down Expand Up @@ -49,137 +49,137 @@ public void ConstructAddAndRetrieveWithDefaultCtorReturnsValue()
}

[Fact]
public void WhenItemIsAddedCountIsCorrect()
{
lru.Count.Should().Be(0);
lru.GetOrAdd(1, valueFactory.Create);
lru.Count.Should().Be(1);
}

[Fact]
public void WhenItemExistsTryGetReturnsValueAndTrue()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(1, out var value);

result.Should().Be(true);
value.Should().Be("1");
}

[Fact]
public void WhenItemDoesNotExistTryGetReturnsNullAndFalse()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(2, out var value);

result.Should().Be(false);
value.Should().BeNull();
}

[Fact]
public void WhenItemIsAddedThenRetrievedHitRatioIsHalf()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(1, out var value);

lru.HitRatio.Should().Be(0.5);
}

[Fact]
public void WhenKeyIsRequestedItIsCreatedAndCached()
{
var result1 = lru.GetOrAdd(1, valueFactory.Create);
var result2 = lru.GetOrAdd(1, valueFactory.Create);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
}

[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);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
}

[Fact]
public void WhenDifferentKeysAreRequestedValueIsCreatedForEach()
{
var result1 = lru.GetOrAdd(1, valueFactory.Create);
var result2 = lru.GetOrAdd(2, valueFactory.Create);

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

result1.Should().Be("1");
result2.Should().Be("2");
}

[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);

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

result1.Should().Be("1");
result2.Should().Be("2");
}

[Fact]
public void WhenMoreKeysRequestedThanCapacityCountDoesNotIncrease()
{
for (int i = 0; i < capacity + 1; i++)
{
lru.GetOrAdd(i, valueFactory.Create);
}

lru.Count.Should().Be(capacity);
valueFactory.timesCalled.Should().Be(capacity + 1);
}

[Fact]
public async Task WhenMoreKeysRequestedThanCapacityCountDoesNotIncreaseAsync()
{
for (int i = 0; i < capacity + 1; i++)
{
await lru.GetOrAddAsync(i, valueFactory.CreateAsync);
}

lru.Count.Should().Be(capacity);
valueFactory.timesCalled.Should().Be(capacity + 1);
}

[Fact]
public void WhenMoreKeysRequestedThanCapacityOldestItemIsEvicted()
{
// request 10 items, LRU is now full
for (int i = 0; i < capacity; i++)
{
lru.GetOrAdd(i, valueFactory.Create);
}

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

// request 0, now item 1 is to be evicted
lru.GetOrAdd(0, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity);

// request next item after last, verify value factory was called
lru.GetOrAdd(capacity, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 1);

// request 0, verify value factory not called
lru.GetOrAdd(0, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 1);

// request 1, verify value factory is called (and it was therefore not cached)
lru.GetOrAdd(1, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 2);
}
public void WhenItemIsAddedCountIsCorrect()
{
lru.Count.Should().Be(0);
lru.GetOrAdd(1, valueFactory.Create);
lru.Count.Should().Be(1);
}

[Fact]
public void WhenItemExistsTryGetReturnsValueAndTrue()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(1, out var value);

result.Should().Be(true);
value.Should().Be("1");
}

[Fact]
public void WhenItemDoesNotExistTryGetReturnsNullAndFalse()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(2, out var value);

result.Should().Be(false);
value.Should().BeNull();
}

[Fact]
public void WhenItemIsAddedThenRetrievedHitRatioIsHalf()
{
lru.GetOrAdd(1, valueFactory.Create);
bool result = lru.TryGet(1, out var value);

lru.HitRatio.Should().Be(0.5);
}

[Fact]
public void WhenKeyIsRequestedItIsCreatedAndCached()
{
var result1 = lru.GetOrAdd(1, valueFactory.Create);
var result2 = lru.GetOrAdd(1, valueFactory.Create);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
}

[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);

valueFactory.timesCalled.Should().Be(1);
result1.Should().Be(result2);
}

[Fact]
public void WhenDifferentKeysAreRequestedValueIsCreatedForEach()
{
var result1 = lru.GetOrAdd(1, valueFactory.Create);
var result2 = lru.GetOrAdd(2, valueFactory.Create);

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

result1.Should().Be("1");
result2.Should().Be("2");
}

[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);

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

result1.Should().Be("1");
result2.Should().Be("2");
}

[Fact]
public void WhenMoreKeysRequestedThanCapacityCountDoesNotIncrease()
{
for (int i = 0; i < capacity + 1; i++)
{
lru.GetOrAdd(i, valueFactory.Create);
}

lru.Count.Should().Be(capacity);
valueFactory.timesCalled.Should().Be(capacity + 1);
}

[Fact]
public async Task WhenMoreKeysRequestedThanCapacityCountDoesNotIncreaseAsync()
{
for (int i = 0; i < capacity + 1; i++)
{
await lru.GetOrAddAsync(i, valueFactory.CreateAsync);
}

lru.Count.Should().Be(capacity);
valueFactory.timesCalled.Should().Be(capacity + 1);
}

[Fact]
public void WhenMoreKeysRequestedThanCapacityOldestItemIsEvicted()
{
// request 10 items, LRU is now full
for (int i = 0; i < capacity; i++)
{
lru.GetOrAdd(i, valueFactory.Create);
}

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

// request 0, now item 1 is to be evicted
lru.GetOrAdd(0, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity);

// request next item after last, verify value factory was called
lru.GetOrAdd(capacity, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 1);

// request 0, verify value factory not called
lru.GetOrAdd(0, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 1);

// request 1, verify value factory is called (and it was therefore not cached)
lru.GetOrAdd(1, valueFactory.Create);
valueFactory.timesCalled.Should().Be(capacity + 2);
}

[Fact]
public void WhenValueExpiresItIsDisposed()
Expand Down Expand Up @@ -212,31 +212,31 @@ public async Task WhenValueExpiresAsyncItIsDisposed()
}

[Fact]
public void WhenKeyDoesNotExistTryGetReturnsFalse()
{
lru.GetOrAdd(1, valueFactory.Create);
public void WhenKeyDoesNotExistTryGetReturnsFalse()
{
lru.GetOrAdd(1, valueFactory.Create);

lru.TryGet(2, out var result).Should().Be(false);
}
lru.TryGet(2, out var result).Should().Be(false);
}

[Fact]
public void WhenKeyExistsTryGetReturnsTrueAndOutValueIsCorrect()
{
lru.GetOrAdd(1, valueFactory.Create);
[Fact]
public void WhenKeyExistsTryGetReturnsTrueAndOutValueIsCorrect()
{
lru.GetOrAdd(1, valueFactory.Create);

bool result = lru.TryGet(1, out var value);
result.Should().Be(true);
value.Should().Be("1");
}
bool result = lru.TryGet(1, out var value);
result.Should().Be(true);
value.Should().Be("1");
}

[Fact]
public void WhenKeyExistsTryRemoveRemovesItemAndReturnsTrue()
[Fact]
public void WhenKeyExistsTryRemoveRemovesItemAndReturnsTrue()
{
lru.GetOrAdd(1, valueFactory.Create);
lru.GetOrAdd(1, valueFactory.Create);

lru.TryRemove(1).Should().BeTrue();
lru.TryGet(1, out var value).Should().BeFalse();
}
lru.TryRemove(1).Should().BeTrue();
lru.TryGet(1, out var value).Should().BeFalse();
}

[Fact]
public void WhenItemIsRemovedItIsDisposed()
Expand All @@ -251,11 +251,11 @@ public void WhenItemIsRemovedItIsDisposed()
}

[Fact]
public void WhenKeyDoesNotExistTryRemoveReturnsFalse()
{
lru.GetOrAdd(1, valueFactory.Create);
public void WhenKeyDoesNotExistTryRemoveReturnsFalse()
{
lru.GetOrAdd(1, valueFactory.Create);

lru.TryRemove(2).Should().BeFalse();
}
}
lru.TryRemove(2).Should().BeFalse();
}
}
}
Loading