diff --git a/BitFaster.Caching.UnitTests/Synchronized/AsyncIdempotentTests.cs b/BitFaster.Caching.UnitTests/Synchronized/AsyncAtomicFactoryTests.cs similarity index 82% rename from BitFaster.Caching.UnitTests/Synchronized/AsyncIdempotentTests.cs rename to BitFaster.Caching.UnitTests/Synchronized/AsyncAtomicFactoryTests.cs index e411bf38..18f8e3ef 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/AsyncIdempotentTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/AsyncAtomicFactoryTests.cs @@ -10,12 +10,12 @@ namespace BitFaster.Caching.UnitTests.Synchronized { - public class AsyncIdempotentTests + public class AsyncAtomicFactoryTests { [Fact] public void DefaultCtorValueIsNotCreated() { - var a = new AsyncIdempotent(); + var a = new AsyncAtomicFactory(); a.IsValueCreated.Should().BeFalse(); a.ValueIfCreated.Should().Be(0); @@ -24,7 +24,7 @@ public void DefaultCtorValueIsNotCreated() [Fact] public void WhenValuePassedToCtorValueIsStored() { - var a = new AsyncIdempotent(1); + var a = new AsyncAtomicFactory(1); a.ValueIfCreated.Should().Be(1); a.IsValueCreated.Should().BeTrue(); @@ -33,7 +33,7 @@ public void WhenValuePassedToCtorValueIsStored() [Fact] public async Task WhenValueCreatedValueReturned() { - var a = new AsyncIdempotent(); + var a = new AsyncAtomicFactory(); (await a.GetValueAsync(1, k => Task.FromResult(2))).Should().Be(2); a.ValueIfCreated.Should().Be(2); @@ -43,7 +43,7 @@ public async Task WhenValueCreatedValueReturned() [Fact] public async Task WhenValueCreatedGetValueReturnsOriginalValue() { - var a = new AsyncIdempotent(); + var a = new AsyncAtomicFactory(); await a.GetValueAsync(1, k => Task.FromResult(2)); (await a.GetValueAsync(1, k => Task.FromResult(3))).Should().Be(2); } @@ -51,7 +51,7 @@ public async Task WhenValueCreatedGetValueReturnsOriginalValue() [Fact] public async Task WhenValueCreateThrowsValueIsNotStored() { - var a = new AsyncIdempotent(); + var a = new AsyncAtomicFactory(); Func getOrAdd = async () => { await a.GetValueAsync(1, k => throw new ArithmeticException()); }; @@ -66,11 +66,11 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() var enter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var resume = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var idempotent = new AsyncIdempotent(); + var atomicFactory = new AsyncAtomicFactory(); var result = 0; var winnerCount = 0; - Task first = idempotent.GetValueAsync(1, async k => + Task first = atomicFactory.GetValueAsync(1, async k => { enter.SetResult(true); await resume.Task; @@ -80,7 +80,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() return 1; }); - Task second = idempotent.GetValueAsync(1, async k => + Task second = atomicFactory.GetValueAsync(1, async k => { enter.SetResult(true); await resume.Task; diff --git a/BitFaster.Caching.UnitTests/Synchronized/IdempotentTests.cs b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryTests.cs similarity index 83% rename from BitFaster.Caching.UnitTests/Synchronized/IdempotentTests.cs rename to BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryTests.cs index 4ed3b629..01a536f5 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/IdempotentTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/AtomicFactoryTests.cs @@ -10,12 +10,12 @@ namespace BitFaster.Caching.UnitTests.Synchronized { - public class IdempotentTests + public class AtomicFactoryTests { [Fact] public void DefaultCtorValueIsNotCreated() { - var a = new Idempotent(); + var a = new AtomicFactory(); a.IsValueCreated.Should().BeFalse(); a.ValueIfCreated.Should().Be(0); @@ -24,7 +24,7 @@ public void DefaultCtorValueIsNotCreated() [Fact] public void WhenValuePassedToCtorValueIsStored() { - var a = new Idempotent(1); + var a = new AtomicFactory(1); a.ValueIfCreated.Should().Be(1); a.IsValueCreated.Should().BeTrue(); @@ -33,7 +33,7 @@ public void WhenValuePassedToCtorValueIsStored() [Fact] public void WhenValueCreatedValueReturned() { - var a = new Idempotent(); + var a = new AtomicFactory(); a.GetValue(1, k => 2).Should().Be(2); a.ValueIfCreated.Should().Be(2); @@ -43,7 +43,7 @@ public void WhenValueCreatedValueReturned() [Fact] public void WhenValueCreatedGetValueReturnsOriginalValue() { - var a = new Idempotent(); + var a = new AtomicFactory(); a.GetValue(1, k => 2); a.GetValue(1, k => 3).Should().Be(2); } @@ -54,13 +54,13 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() var enter = new ManualResetEvent(false); var resume = new ManualResetEvent(false); - var idempotent = new Idempotent(); + var atomicFactory = new AtomicFactory(); var result = 0; var winnerCount = 0; Task first = Task.Run(() => { - return idempotent.GetValue(1, k => + return atomicFactory.GetValue(1, k => { enter.Set(); resume.WaitOne(); @@ -73,7 +73,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() Task second = Task.Run(() => { - return idempotent.GetValue(1, k => + return atomicFactory.GetValue(1, k => { enter.Set(); resume.WaitOne(); diff --git a/BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncIdempotentTests.cs b/BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncAtomicFactoryTests.cs similarity index 75% rename from BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncIdempotentTests.cs rename to BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncAtomicFactoryTests.cs index bae6dd9d..42c76f37 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncIdempotentTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/ScopedAsyncAtomicFactoryTests.cs @@ -10,14 +10,14 @@ namespace BitFaster.Caching.UnitTests.Synchronized { - public class ScopedAsyncIdempotentTests + public class ScopedAsyncAtomicFactoryTests { [Fact] public async Task WhenCreateFromValueLifetimeContainsValue() { - var idempotent = new ScopedAsyncIdempotent(new IntHolder() { actualNumber = 1 }); + var atomicFactory = new ScopedAsyncAtomicFactory(new IntHolder() { actualNumber = 1 }); - (bool r, Lifetime l) result = await idempotent.TryCreateLifetimeAsync(1, k => + (bool r, Lifetime l) result = await atomicFactory.TryCreateLifetimeAsync(1, k => { return Task.FromResult(new IntHolder() { actualNumber = 2 }); }); @@ -29,10 +29,10 @@ public async Task WhenCreateFromValueLifetimeContainsValue() [Fact] public async Task WhenScopeIsDisposedTryCreateReturnsFalse() { - var idempotent = new ScopedAsyncIdempotent(new IntHolder() { actualNumber = 1 }); - idempotent.Dispose(); + var atomicFactory = new ScopedAsyncAtomicFactory(new IntHolder() { actualNumber = 1 }); + atomicFactory.Dispose(); - (bool r, Lifetime l) result = await idempotent.TryCreateLifetimeAsync(1, k => + (bool r, Lifetime l) result = await atomicFactory.TryCreateLifetimeAsync(1, k => { return Task.FromResult(new IntHolder() { actualNumber = 2 }); }); @@ -45,9 +45,9 @@ public async Task WhenScopeIsDisposedTryCreateReturnsFalse() public void WhenValueIsCreatedDisposeDisposesValue() { var holder = new IntHolder() { actualNumber = 2 }; - var idempotent = new ScopedAsyncIdempotent(holder); + var atomicFactory = new ScopedAsyncAtomicFactory(holder); - idempotent.Dispose(); + atomicFactory.Dispose(); holder.disposed.Should().BeTrue(); } @@ -58,11 +58,11 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() var enter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var resume = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var idempotent = new ScopedAsyncIdempotent(); + var atomicFactory = new ScopedAsyncAtomicFactory(); var winningNumber = 0; var winnerCount = 0; - Task<(bool r, Lifetime l)> first = idempotent.TryCreateLifetimeAsync(1, async k => + Task<(bool r, Lifetime l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k => { enter.SetResult(true); await resume.Task; @@ -72,7 +72,7 @@ public async Task WhenCallersRunConcurrentlyResultIsFromWinner() return new IntHolder() { actualNumber = 1 }; }); - Task<(bool r, Lifetime l)> second = idempotent.TryCreateLifetimeAsync(1, async k => + Task<(bool r, Lifetime l)> second = atomicFactory.TryCreateLifetimeAsync(1, async k => { enter.SetResult(true); await resume.Task; @@ -103,10 +103,10 @@ public async Task WhenDisposedWhileInitResultIsDisposed() var enter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var resume = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var idempotent = new ScopedAsyncIdempotent(); + var atomicFactory = new ScopedAsyncAtomicFactory(); var holder = new IntHolder() { actualNumber = 1 }; - Task<(bool r, Lifetime l)> first = idempotent.TryCreateLifetimeAsync(1, async k => + Task<(bool r, Lifetime l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k => { enter.SetResult(true); await resume.Task; @@ -115,7 +115,7 @@ public async Task WhenDisposedWhileInitResultIsDisposed() }); await enter.Task; - idempotent.Dispose(); + atomicFactory.Dispose(); resume.SetResult(true); var result = await first; @@ -132,10 +132,10 @@ public async Task WhenDisposedWhileThrowingNextInitIsDisposed() var enter = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var resume = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - var idempotent = new ScopedAsyncIdempotent(); + var atomicFactory = new ScopedAsyncAtomicFactory(); var holder = new IntHolder() { actualNumber = 1 }; - Task<(bool r, Lifetime l)> first = idempotent.TryCreateLifetimeAsync(1, async k => + Task<(bool r, Lifetime l)> first = atomicFactory.TryCreateLifetimeAsync(1, async k => { enter.SetResult(true); await resume.Task; @@ -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 @@ -154,7 +154,7 @@ public async Task WhenDisposedWhileThrowingNextInitIsDisposed() Func tryCreateAsync = async () => { await first; }; await tryCreateAsync.Should().ThrowAsync(); - (bool r, Lifetime l) result = await idempotent.TryCreateLifetimeAsync(1, k => + (bool r, Lifetime l) result = await atomicFactory.TryCreateLifetimeAsync(1, k => { return Task.FromResult(holder); }); diff --git a/BitFaster.Caching.UnitTests/Synchronized/ScopedIdempotentTests.cs b/BitFaster.Caching.UnitTests/Synchronized/ScopedAtomicFactoryTests.cs similarity index 83% rename from BitFaster.Caching.UnitTests/Synchronized/ScopedIdempotentTests.cs rename to BitFaster.Caching.UnitTests/Synchronized/ScopedAtomicFactoryTests.cs index f00a0bfa..b201171b 100644 --- a/BitFaster.Caching.UnitTests/Synchronized/ScopedIdempotentTests.cs +++ b/BitFaster.Caching.UnitTests/Synchronized/ScopedAtomicFactoryTests.cs @@ -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(expectedDisposable); + var sa = new ScopedAtomicFactory(expectedDisposable); sa.TryCreateLifetime(1, k => new Disposable(), out var lifetime).Should().BeTrue(); @@ -26,7 +26,7 @@ public void WhenInitializedWithValueTryCreateLifetimeCreatesLifetimeWithValue() public void WhenInitializedWithFactoryTryCreateLifetimeCreatesLifetimeWithValue() { var expectedDisposable = new Disposable(); - var sa = new ScopedIdempotent(); + var sa = new ScopedAtomicFactory(); sa.TryCreateLifetime(1, k => expectedDisposable, out var lifetime).Should().BeTrue(); @@ -37,7 +37,7 @@ public void WhenInitializedWithFactoryTryCreateLifetimeCreatesLifetimeWithValue( public void WhenInitializedWithFactoryValueIsCached() { var expectedDisposable = new Disposable(); - var sa = new ScopedIdempotent(); + var sa = new ScopedAtomicFactory(); sa.TryCreateLifetime(1, k => expectedDisposable, out var lifetime1).Should().BeTrue(); sa.TryCreateLifetime(1, k => new Disposable(), out var lifetime2).Should().BeTrue(); @@ -48,7 +48,7 @@ public void WhenInitializedWithFactoryValueIsCached() [Fact] public void WhenInitializedWithValueThenDisposedCreateLifetimeIsFalse() { - var sa = new ScopedIdempotent(new Disposable()); + var sa = new ScopedAtomicFactory(new Disposable()); sa.Dispose(); sa.TryCreateLifetime(1, k => new Disposable(), out var l).Should().BeFalse(); @@ -57,7 +57,7 @@ public void WhenInitializedWithValueThenDisposedCreateLifetimeIsFalse() [Fact] public void WhenCreatedThenDisposedCreateLifetimeIsFalse() { - var sa = new ScopedIdempotent(); + var sa = new ScopedAtomicFactory(); sa.Dispose(); sa.TryCreateLifetime(1, k => new Disposable(), out var l).Should().BeFalse(); @@ -67,7 +67,7 @@ public void WhenCreatedThenDisposedCreateLifetimeIsFalse() public void WhenInitializedLifetimeKeepsValueAlive() { var disposable = new Disposable(); - var sa = new ScopedIdempotent(); + var sa = new ScopedAtomicFactory(); sa.TryCreateLifetime(1, k => disposable, out var lifetime1).Should().BeTrue(); sa.TryCreateLifetime(1, k => null, out var lifetime2).Should().BeTrue(); diff --git a/BitFaster.Caching/Synchronized/AsyncIdempotent.cs b/BitFaster.Caching/Synchronized/AsyncAtomicFactory.cs similarity index 96% rename from BitFaster.Caching/Synchronized/AsyncIdempotent.cs rename to BitFaster.Caching/Synchronized/AsyncAtomicFactory.cs index 97d26729..80f10d12 100644 --- a/BitFaster.Caching/Synchronized/AsyncIdempotent.cs +++ b/BitFaster.Caching/Synchronized/AsyncAtomicFactory.cs @@ -9,19 +9,19 @@ namespace BitFaster.Caching.Synchronized { [DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueIfCreated}")] - public class AsyncIdempotent + public class AsyncAtomicFactory { 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; } diff --git a/BitFaster.Caching/Synchronized/Idempotent.cs b/BitFaster.Caching/Synchronized/AtomicFactory.cs similarity index 95% rename from BitFaster.Caching/Synchronized/Idempotent.cs rename to BitFaster.Caching/Synchronized/AtomicFactory.cs index 5f9371d4..95ec6940 100644 --- a/BitFaster.Caching/Synchronized/Idempotent.cs +++ b/BitFaster.Caching/Synchronized/AtomicFactory.cs @@ -9,19 +9,19 @@ namespace BitFaster.Caching.Synchronized { [DebuggerDisplay("IsValueCreated={IsValueCreated}, Value={ValueIfCreated}")] - public class Idempotent + public class AtomicFactory { 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; } diff --git a/BitFaster.Caching/Synchronized/ScopedAsyncIdempotent.cs b/BitFaster.Caching/Synchronized/ScopedAsyncAtomicFactory.cs similarity index 96% rename from BitFaster.Caching/Synchronized/ScopedAsyncIdempotent.cs rename to BitFaster.Caching/Synchronized/ScopedAsyncAtomicFactory.cs index 2c1953c4..a44fe0d4 100644 --- a/BitFaster.Caching/Synchronized/ScopedAsyncIdempotent.cs +++ b/BitFaster.Caching/Synchronized/ScopedAsyncAtomicFactory.cs @@ -7,17 +7,17 @@ namespace BitFaster.Caching.Synchronized { - public class ScopedAsyncIdempotent : IScoped, IDisposable where V : IDisposable + public class ScopedAsyncAtomicFactory : IScoped, IDisposable where V : IDisposable { private Scoped scope; private Initializer initializer; - public ScopedAsyncIdempotent() + public ScopedAsyncAtomicFactory() { initializer = new Initializer(); } - public ScopedAsyncIdempotent(V value) + public ScopedAsyncAtomicFactory(V value) { scope = new Scoped(value); } diff --git a/BitFaster.Caching/Synchronized/ScopedIdempotent.cs b/BitFaster.Caching/Synchronized/ScopedAtomicFactory.cs similarity index 93% rename from BitFaster.Caching/Synchronized/ScopedIdempotent.cs rename to BitFaster.Caching/Synchronized/ScopedAtomicFactory.cs index b5fbf148..7c43068c 100644 --- a/BitFaster.Caching/Synchronized/ScopedIdempotent.cs +++ b/BitFaster.Caching/Synchronized/ScopedAtomicFactory.cs @@ -12,17 +12,17 @@ namespace BitFaster.Caching.Synchronized // 1. Exactly once disposal. // 2. Exactly once invocation of value factory (synchronized create). // 3. Resolve race between create dispose init, if disposed is called before value is created, scoped value is disposed for life. - public class ScopedIdempotent : IScoped, IDisposable where V : IDisposable + public class ScopedAtomicFactory : IScoped, IDisposable where V : IDisposable { private Scoped scope; private Initializer initializer; - public ScopedIdempotent() + public ScopedAtomicFactory() { initializer = new Initializer(); } - public ScopedIdempotent(V value) + public ScopedAtomicFactory(V value) { scope = new Scoped(value); } @@ -108,7 +108,7 @@ public Scoped TryCreateDisposedScope() return value; } - // don't expose to other threads until disposed + // don't expose to other threads until disposed (else they may use the invalid default value) var temp = new Scoped(default); temp.Dispose(); value = temp;