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
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

namespace BitFaster.Caching.UnitTests.Synchronized
{
public class AsyncIdempotentTests
public class AsyncAtomicFactoryTests
{
[Fact]
public void DefaultCtorValueIsNotCreated()
{
var a = new AsyncIdempotent<int, int>();
var a = new AsyncAtomicFactory<int, int>();

a.IsValueCreated.Should().BeFalse();
a.ValueIfCreated.Should().Be(0);
Expand All @@ -24,7 +24,7 @@ public void DefaultCtorValueIsNotCreated()
[Fact]
public void WhenValuePassedToCtorValueIsStored()
{
var a = new AsyncIdempotent<int, int>(1);
var a = new AsyncAtomicFactory<int, int>(1);

a.ValueIfCreated.Should().Be(1);
a.IsValueCreated.Should().BeTrue();
Expand All @@ -33,7 +33,7 @@ public void WhenValuePassedToCtorValueIsStored()
[Fact]
public async Task WhenValueCreatedValueReturned()
{
var a = new AsyncIdempotent<int, int>();
var a = new AsyncAtomicFactory<int, int>();
(await a.GetValueAsync(1, k => Task.FromResult(2))).Should().Be(2);

a.ValueIfCreated.Should().Be(2);
Expand All @@ -43,15 +43,15 @@ public async Task WhenValueCreatedValueReturned()
[Fact]
public async Task WhenValueCreatedGetValueReturnsOriginalValue()
{
var a = new AsyncIdempotent<int, int>();
var a = new AsyncAtomicFactory<int, int>();
await a.GetValueAsync(1, k => Task.FromResult(2));
(await a.GetValueAsync(1, k => Task.FromResult(3))).Should().Be(2);
}

[Fact]
public async Task WhenValueCreateThrowsValueIsNotStored()
{
var a = new AsyncIdempotent<int, int>();
var a = new AsyncAtomicFactory<int, int>();

Func<Task> getOrAdd = async () => { await a.GetValueAsync(1, k => throw new ArithmeticException()); };

Expand All @@ -66,11 +66,11 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
var enter = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var resume = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

var idempotent = new AsyncIdempotent<int, int>();
var atomicFactory = new AsyncAtomicFactory<int, int>();
var result = 0;
var winnerCount = 0;

Task<int> first = idempotent.GetValueAsync(1, async k =>
Task<int> first = atomicFactory.GetValueAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand All @@ -80,7 +80,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
return 1;
});

Task<int> second = idempotent.GetValueAsync(1, async k =>
Task<int> second = atomicFactory.GetValueAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

namespace BitFaster.Caching.UnitTests.Synchronized
{
public class IdempotentTests
public class AtomicFactoryTests
{
[Fact]
public void DefaultCtorValueIsNotCreated()
{
var a = new Idempotent<int, int>();
var a = new AtomicFactory<int, int>();

a.IsValueCreated.Should().BeFalse();
a.ValueIfCreated.Should().Be(0);
Expand All @@ -24,7 +24,7 @@ public void DefaultCtorValueIsNotCreated()
[Fact]
public void WhenValuePassedToCtorValueIsStored()
{
var a = new Idempotent<int, int>(1);
var a = new AtomicFactory<int, int>(1);

a.ValueIfCreated.Should().Be(1);
a.IsValueCreated.Should().BeTrue();
Expand All @@ -33,7 +33,7 @@ public void WhenValuePassedToCtorValueIsStored()
[Fact]
public void WhenValueCreatedValueReturned()
{
var a = new Idempotent<int, int>();
var a = new AtomicFactory<int, int>();
a.GetValue(1, k => 2).Should().Be(2);

a.ValueIfCreated.Should().Be(2);
Expand All @@ -43,7 +43,7 @@ public void WhenValueCreatedValueReturned()
[Fact]
public void WhenValueCreatedGetValueReturnsOriginalValue()
{
var a = new Idempotent<int, int>();
var a = new AtomicFactory<int, int>();
a.GetValue(1, k => 2);
a.GetValue(1, k => 3).Should().Be(2);
}
Expand All @@ -54,13 +54,13 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
var enter = new ManualResetEvent(false);
var resume = new ManualResetEvent(false);

var idempotent = new Idempotent<int, int>();
var atomicFactory = new AtomicFactory<int, int>();
var result = 0;
var winnerCount = 0;

Task<int> first = Task.Run(() =>
{
return idempotent.GetValue(1, k =>
return atomicFactory.GetValue(1, k =>
{
enter.Set();
resume.WaitOne();
Expand All @@ -73,7 +73,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()

Task<int> second = Task.Run(() =>
{
return idempotent.GetValue(1, k =>
return atomicFactory.GetValue(1, k =>
{
enter.Set();
resume.WaitOne();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

namespace BitFaster.Caching.UnitTests.Synchronized
{
public class ScopedAsyncIdempotentTests
public class ScopedAsyncAtomicFactoryTests
{
[Fact]
public async Task WhenCreateFromValueLifetimeContainsValue()
{
var idempotent = new ScopedAsyncIdempotent<int, IntHolder>(new IntHolder() { actualNumber = 1 });
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>(new IntHolder() { actualNumber = 1 });

(bool r, Lifetime<IntHolder> l) result = await idempotent.TryCreateLifetimeAsync(1, k =>
(bool r, Lifetime<IntHolder> l) result = await atomicFactory.TryCreateLifetimeAsync(1, k =>
{
return Task.FromResult(new IntHolder() { actualNumber = 2 });
});
Expand All @@ -29,10 +29,10 @@ public async Task WhenCreateFromValueLifetimeContainsValue()
[Fact]
public async Task WhenScopeIsDisposedTryCreateReturnsFalse()
{
var idempotent = new ScopedAsyncIdempotent<int, IntHolder>(new IntHolder() { actualNumber = 1 });
idempotent.Dispose();
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>(new IntHolder() { actualNumber = 1 });
atomicFactory.Dispose();

(bool r, Lifetime<IntHolder> l) result = await idempotent.TryCreateLifetimeAsync(1, k =>
(bool r, Lifetime<IntHolder> l) result = await atomicFactory.TryCreateLifetimeAsync(1, k =>
{
return Task.FromResult(new IntHolder() { actualNumber = 2 });
});
Expand All @@ -45,9 +45,9 @@ public async Task WhenScopeIsDisposedTryCreateReturnsFalse()
public void WhenValueIsCreatedDisposeDisposesValue()
{
var holder = new IntHolder() { actualNumber = 2 };
var idempotent = new ScopedAsyncIdempotent<int, IntHolder>(holder);
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>(holder);

idempotent.Dispose();
atomicFactory.Dispose();

holder.disposed.Should().BeTrue();
}
Expand All @@ -58,11 +58,11 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
var enter = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var resume = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

var idempotent = new ScopedAsyncIdempotent<int, IntHolder>();
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>();
var winningNumber = 0;
var winnerCount = 0;

Task<(bool r, Lifetime<IntHolder> l)> first = idempotent.TryCreateLifetimeAsync(1, async k =>
Task<(bool r, Lifetime<IntHolder> l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand All @@ -72,7 +72,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner()
return new IntHolder() { actualNumber = 1 };
});

Task<(bool r, Lifetime<IntHolder> l)> second = idempotent.TryCreateLifetimeAsync(1, async k =>
Task<(bool r, Lifetime<IntHolder> l)> second = atomicFactory.TryCreateLifetimeAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand Down Expand Up @@ -103,10 +103,10 @@ public async Task WhenDisposedWhileInitResultIsDisposed()
var enter = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var resume = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

var idempotent = new ScopedAsyncIdempotent<int, IntHolder>();
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>();
var holder = new IntHolder() { actualNumber = 1 };

Task<(bool r, Lifetime<IntHolder> l)> first = idempotent.TryCreateLifetimeAsync(1, async k =>
Task<(bool r, Lifetime<IntHolder> l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand All @@ -115,7 +115,7 @@ public async Task WhenDisposedWhileInitResultIsDisposed()
});

await enter.Task;
idempotent.Dispose();
atomicFactory.Dispose();
resume.SetResult(true);

var result = await first;
Expand All @@ -132,10 +132,10 @@ public async Task WhenDisposedWhileThrowingNextInitIsDisposed()
var enter = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
var resume = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);

var idempotent = new ScopedAsyncIdempotent<int, IntHolder>();
var atomicFactory = new ScopedAsyncAtomicFactory<int, IntHolder>();
var holder = new IntHolder() { actualNumber = 1 };

Task<(bool r, Lifetime<IntHolder> l)> first = idempotent.TryCreateLifetimeAsync(1, async k =>
Task<(bool r, Lifetime<IntHolder> l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k =>
{
enter.SetResult(true);
await resume.Task;
Expand All @@ -144,7 +144,7 @@ public async Task WhenDisposedWhileThrowingNextInitIsDisposed()
});

await enter.Task;
idempotent.Dispose();
atomicFactory.Dispose();
resume.SetResult(true);

// At this point, the scoped value is not created but the initializer is marked
Expand All @@ -154,7 +154,7 @@ public async Task WhenDisposedWhileThrowingNextInitIsDisposed()
Func<Task> tryCreateAsync = async () => { await first; };
await tryCreateAsync.Should().ThrowAsync<InvalidOperationException>();

(bool r, Lifetime<IntHolder> l) result = await idempotent.TryCreateLifetimeAsync(1, k =>
(bool r, Lifetime<IntHolder> l) result = await atomicFactory.TryCreateLifetimeAsync(1, k =>
{
return Task.FromResult(holder);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

namespace BitFaster.Caching.UnitTests.Synchronized
{
public class ScopedIdempotentTests
public class ScopedAtomicFactoryTests
{
[Fact]
public void WhenInitializedWithValueTryCreateLifetimeCreatesLifetimeWithValue()
{
var expectedDisposable = new Disposable();
var sa = new ScopedIdempotent<int, Disposable>(expectedDisposable);
var sa = new ScopedAtomicFactory<int, Disposable>(expectedDisposable);

sa.TryCreateLifetime(1, k => new Disposable(), out var lifetime).Should().BeTrue();

Expand All @@ -26,7 +26,7 @@ public void WhenInitializedWithValueTryCreateLifetimeCreatesLifetimeWithValue()
public void WhenInitializedWithFactoryTryCreateLifetimeCreatesLifetimeWithValue()
{
var expectedDisposable = new Disposable();
var sa = new ScopedIdempotent<int, Disposable>();
var sa = new ScopedAtomicFactory<int, Disposable>();

sa.TryCreateLifetime(1, k => expectedDisposable, out var lifetime).Should().BeTrue();

Expand All @@ -37,7 +37,7 @@ public void WhenInitializedWithFactoryTryCreateLifetimeCreatesLifetimeWithValue(
public void WhenInitializedWithFactoryValueIsCached()
{
var expectedDisposable = new Disposable();
var sa = new ScopedIdempotent<int, Disposable>();
var sa = new ScopedAtomicFactory<int, Disposable>();

sa.TryCreateLifetime(1, k => expectedDisposable, out var lifetime1).Should().BeTrue();
sa.TryCreateLifetime(1, k => new Disposable(), out var lifetime2).Should().BeTrue();
Expand All @@ -48,7 +48,7 @@ public void WhenInitializedWithFactoryValueIsCached()
[Fact]
public void WhenInitializedWithValueThenDisposedCreateLifetimeIsFalse()
{
var sa = new ScopedIdempotent<int, Disposable>(new Disposable());
var sa = new ScopedAtomicFactory<int, Disposable>(new Disposable());
sa.Dispose();

sa.TryCreateLifetime(1, k => new Disposable(), out var l).Should().BeFalse();
Expand All @@ -57,7 +57,7 @@ public void WhenInitializedWithValueThenDisposedCreateLifetimeIsFalse()
[Fact]
public void WhenCreatedThenDisposedCreateLifetimeIsFalse()
{
var sa = new ScopedIdempotent<int, Disposable>();
var sa = new ScopedAtomicFactory<int, Disposable>();
sa.Dispose();

sa.TryCreateLifetime(1, k => new Disposable(), out var l).Should().BeFalse();
Expand All @@ -67,7 +67,7 @@ public void WhenCreatedThenDisposedCreateLifetimeIsFalse()
public void WhenInitializedLifetimeKeepsValueAlive()
{
var disposable = new Disposable();
var sa = new ScopedIdempotent<int, Disposable>();
var sa = new ScopedAtomicFactory<int, Disposable>();

sa.TryCreateLifetime(1, k => disposable, out var lifetime1).Should().BeTrue();
sa.TryCreateLifetime(1, k => null, out var lifetime2).Should().BeTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
namespace BitFaster.Caching.Synchronized
{
[DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueIfCreated}")]
public class AsyncIdempotent<K, V>
public class AsyncAtomicFactory<K, V>
{
private Initializer initializer;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private V value;

public AsyncIdempotent()
public AsyncAtomicFactory()
{
initializer = new Initializer();
}

public AsyncIdempotent(V value)
public AsyncAtomicFactory(V value)
{
this.value = value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
namespace BitFaster.Caching.Synchronized
{
[DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueIfCreated}")]
public class Idempotent<K, V>
public class AtomicFactory<K, V>
{
private Initializer initializer;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private V value;

public Idempotent()
public AtomicFactory()
{
initializer = new Initializer();
}

public Idempotent(V value)
public AtomicFactory(V value)
{
this.value = value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@

namespace BitFaster.Caching.Synchronized
{
public class ScopedAsyncIdempotent<K, V> : IScoped<V>, IDisposable where V : IDisposable
public class ScopedAsyncAtomicFactory<K, V> : IScoped<V>, IDisposable where V : IDisposable
{
private Scoped<V> scope;
private Initializer initializer;

public ScopedAsyncIdempotent()
public ScopedAsyncAtomicFactory()
{
initializer = new Initializer();
}

public ScopedAsyncIdempotent(V value)
public ScopedAsyncAtomicFactory(V value)
{
scope = new Scoped<V>(value);
}
Expand Down
Loading