From decd2c7973fbccb5c5dafbebae0a8c6646679982 Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 16:06:51 -0700 Subject: [PATCH 1/3] rename --- ....cs => AtomicAsyncConcurrentLruBuilder.cs} | 4 +- ...ilder.cs => AtomicConcurrentLruBuilder.cs} | 4 +- ... AtomicScopedAsyncConcurrentLruBuilder.cs} | 4 +- ...cs => AtomicScopedConcurrentLruBuilder.cs} | 4 +- ....cs => ScopedAsyncConcurrentLruBuilder.cs} | 4 +- ...ilder.cs => ScopedConcurrentLruBuilder.cs} | 4 +- .../Lru/ConcurrentLruBuilderExtensions.cs | 44 +++++++++---------- 7 files changed, 34 insertions(+), 34 deletions(-) rename BitFaster.Caching/Lru/Builder/{AsyncAtomicLruBuilder.cs => AtomicAsyncConcurrentLruBuilder.cs} (69%) rename BitFaster.Caching/Lru/Builder/{AtomicLruBuilder.cs => AtomicConcurrentLruBuilder.cs} (71%) rename BitFaster.Caching/Lru/Builder/{ScopedAsyncAtomicLruBuilder.cs => AtomicScopedAsyncConcurrentLruBuilder.cs} (70%) rename BitFaster.Caching/Lru/Builder/{ScopedAtomicLruBuilder.cs => AtomicScopedConcurrentLruBuilder.cs} (68%) rename BitFaster.Caching/Lru/Builder/{ScopedAsyncLruBuilder.cs => ScopedAsyncConcurrentLruBuilder.cs} (71%) rename BitFaster.Caching/Lru/Builder/{ScopedLruBuilder.cs => ScopedConcurrentLruBuilder.cs} (71%) diff --git a/BitFaster.Caching/Lru/Builder/AsyncAtomicLruBuilder.cs b/BitFaster.Caching/Lru/Builder/AtomicAsyncConcurrentLruBuilder.cs similarity index 69% rename from BitFaster.Caching/Lru/Builder/AsyncAtomicLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/AtomicAsyncConcurrentLruBuilder.cs index f92c26c6..601400e3 100644 --- a/BitFaster.Caching/Lru/Builder/AsyncAtomicLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/AtomicAsyncConcurrentLruBuilder.cs @@ -7,11 +7,11 @@ namespace BitFaster.Caching.Lru.Builder { - public class AsyncAtomicLruBuilder : LruBuilderBase, IAsyncCache> + public class AtomicAsyncConcurrentLruBuilder : LruBuilderBase, IAsyncCache> { private readonly ConcurrentLruBuilder> inner; - internal AsyncAtomicLruBuilder(ConcurrentLruBuilder> inner) + internal AtomicAsyncConcurrentLruBuilder(ConcurrentLruBuilder> inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/Builder/AtomicLruBuilder.cs b/BitFaster.Caching/Lru/Builder/AtomicConcurrentLruBuilder.cs similarity index 71% rename from BitFaster.Caching/Lru/Builder/AtomicLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/AtomicConcurrentLruBuilder.cs index cc1940b5..e1b1050e 100644 --- a/BitFaster.Caching/Lru/Builder/AtomicLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/AtomicConcurrentLruBuilder.cs @@ -7,11 +7,11 @@ namespace BitFaster.Caching.Lru.Builder { - public class AtomicLruBuilder : LruBuilderBase, ICache> + public class AtomicConcurrentLruBuilder : LruBuilderBase, ICache> { private readonly ConcurrentLruBuilder> inner; - internal AtomicLruBuilder(ConcurrentLruBuilder> inner) + internal AtomicConcurrentLruBuilder(ConcurrentLruBuilder> inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/Builder/ScopedAsyncAtomicLruBuilder.cs b/BitFaster.Caching/Lru/Builder/AtomicScopedAsyncConcurrentLruBuilder.cs similarity index 70% rename from BitFaster.Caching/Lru/Builder/ScopedAsyncAtomicLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/AtomicScopedAsyncConcurrentLruBuilder.cs index 8553f91f..316792df 100644 --- a/BitFaster.Caching/Lru/Builder/ScopedAsyncAtomicLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/AtomicScopedAsyncConcurrentLruBuilder.cs @@ -7,11 +7,11 @@ namespace BitFaster.Caching.Lru.Builder { - public sealed class ScopedAsyncAtomicLruBuilder : LruBuilderBase, IScopedAsyncCache> where V : IDisposable + public sealed class AtomicScopedAsyncConcurrentLruBuilder : LruBuilderBase, IScopedAsyncCache> where V : IDisposable { private readonly AsyncConcurrentLruBuilder> inner; - internal ScopedAsyncAtomicLruBuilder(AsyncConcurrentLruBuilder> inner) + internal AtomicScopedAsyncConcurrentLruBuilder(AsyncConcurrentLruBuilder> inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/Builder/ScopedAtomicLruBuilder.cs b/BitFaster.Caching/Lru/Builder/AtomicScopedConcurrentLruBuilder.cs similarity index 68% rename from BitFaster.Caching/Lru/Builder/ScopedAtomicLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/AtomicScopedConcurrentLruBuilder.cs index 25b15daf..dd89bbc4 100644 --- a/BitFaster.Caching/Lru/Builder/ScopedAtomicLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/AtomicScopedConcurrentLruBuilder.cs @@ -7,11 +7,11 @@ namespace BitFaster.Caching.Lru.Builder { - public class ScopedAtomicLruBuilder : LruBuilderBase, IScopedCache> where V : IDisposable + public class AtomicScopedConcurrentLruBuilder : LruBuilderBase, IScopedCache> where V : IDisposable { private readonly ConcurrentLruBuilder> inner; - internal ScopedAtomicLruBuilder(ConcurrentLruBuilder> inner) + internal AtomicScopedConcurrentLruBuilder(ConcurrentLruBuilder> inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/Builder/ScopedAsyncLruBuilder.cs b/BitFaster.Caching/Lru/Builder/ScopedAsyncConcurrentLruBuilder.cs similarity index 71% rename from BitFaster.Caching/Lru/Builder/ScopedAsyncLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/ScopedAsyncConcurrentLruBuilder.cs index 2b280728..f1952876 100644 --- a/BitFaster.Caching/Lru/Builder/ScopedAsyncLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/ScopedAsyncConcurrentLruBuilder.cs @@ -6,11 +6,11 @@ namespace BitFaster.Caching.Lru.Builder { - public sealed class ScopedAsyncLruBuilder : LruBuilderBase, IScopedAsyncCache> where V : IDisposable + public sealed class ScopedAsyncConcurrentLruBuilder : LruBuilderBase, IScopedAsyncCache> where V : IDisposable { private readonly AsyncConcurrentLruBuilder> inner; - internal ScopedAsyncLruBuilder(AsyncConcurrentLruBuilder> inner) + internal ScopedAsyncConcurrentLruBuilder(AsyncConcurrentLruBuilder> inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/Builder/ScopedLruBuilder.cs b/BitFaster.Caching/Lru/Builder/ScopedConcurrentLruBuilder.cs similarity index 71% rename from BitFaster.Caching/Lru/Builder/ScopedLruBuilder.cs rename to BitFaster.Caching/Lru/Builder/ScopedConcurrentLruBuilder.cs index 8007103a..c0fe8167 100644 --- a/BitFaster.Caching/Lru/Builder/ScopedLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/ScopedConcurrentLruBuilder.cs @@ -7,11 +7,11 @@ namespace BitFaster.Caching.Lru.Builder { - public sealed class ScopedLruBuilder : LruBuilderBase, IScopedCache> where V : IDisposable where W : IScoped + public sealed class ScopedConcurrentLruBuilder : LruBuilderBase, IScopedCache> where V : IDisposable where W : IScoped { private readonly ConcurrentLruBuilder inner; - internal ScopedLruBuilder(ConcurrentLruBuilder inner) + internal ScopedConcurrentLruBuilder(ConcurrentLruBuilder inner) : base(inner.info) { this.inner = inner; diff --git a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs index 8805d849..2894d183 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs @@ -18,29 +18,29 @@ public static class ConcurrentLruBuilderExtensions /// The type of values in the cache. /// The ConcurrentLruBuilder to chain method calls onto. /// A ScopedLruBuilder - public static ScopedLruBuilder> WithScopedValues(this ConcurrentLruBuilder builder) where V : IDisposable + public static ScopedConcurrentLruBuilder> WithScopedValues(this ConcurrentLruBuilder builder) where V : IDisposable { var scoped = new ConcurrentLruBuilder>(builder.info); - return new ScopedLruBuilder>(scoped); + return new ScopedConcurrentLruBuilder>(scoped); } - public static AtomicLruBuilder WithAtomicCreate(this ConcurrentLruBuilder b) + public static AtomicConcurrentLruBuilder WithAtomicCreate(this ConcurrentLruBuilder b) { var a = new ConcurrentLruBuilder>(b.info); - return new AtomicLruBuilder(a); + return new AtomicConcurrentLruBuilder(a); } - public static ScopedAtomicLruBuilder WithAtomicCreate(this ScopedLruBuilder b) where V : IDisposable where W : IScoped + public static AtomicScopedConcurrentLruBuilder WithAtomicCreate(this ScopedConcurrentLruBuilder b) where V : IDisposable where W : IScoped { var atomicScoped = new ConcurrentLruBuilder>(b.info); - return new ScopedAtomicLruBuilder(atomicScoped); + return new AtomicScopedConcurrentLruBuilder(atomicScoped); } - public static ScopedAtomicLruBuilder WithScopedValues(this AtomicLruBuilder b) where V : IDisposable + public static AtomicScopedConcurrentLruBuilder WithScopedValues(this AtomicConcurrentLruBuilder b) where V : IDisposable { var atomicScoped = new ConcurrentLruBuilder>(b.info); - return new ScopedAtomicLruBuilder(atomicScoped); + return new AtomicScopedConcurrentLruBuilder(atomicScoped); } public static AsyncConcurrentLruBuilder AsAsyncCache(this ConcurrentLruBuilder builder) @@ -48,46 +48,46 @@ public static AsyncConcurrentLruBuilder AsAsyncCache(this Concurrent return new AsyncConcurrentLruBuilder(builder.info); } - public static ScopedAsyncLruBuilder WithScopedValues(this AsyncConcurrentLruBuilder b) where V : IDisposable + public static ScopedAsyncConcurrentLruBuilder WithScopedValues(this AsyncConcurrentLruBuilder b) where V : IDisposable { var asyncScoped = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncLruBuilder(asyncScoped); + return new ScopedAsyncConcurrentLruBuilder(asyncScoped); } - public static ScopedAsyncLruBuilder AsAsyncCache(this ScopedLruBuilder> b) where V : IDisposable + public static ScopedAsyncConcurrentLruBuilder AsAsyncCache(this ScopedConcurrentLruBuilder> b) where V : IDisposable { var asyncScoped = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncLruBuilder(asyncScoped); + return new ScopedAsyncConcurrentLruBuilder(asyncScoped); } - public static AsyncAtomicLruBuilder AsAsyncCache(this AtomicLruBuilder b) + public static AtomicAsyncConcurrentLruBuilder AsAsyncCache(this AtomicConcurrentLruBuilder b) { var a = new ConcurrentLruBuilder>(b.info); - return new AsyncAtomicLruBuilder(a); + return new AtomicAsyncConcurrentLruBuilder(a); } - public static AsyncAtomicLruBuilder WithAtomicCreate(this AsyncConcurrentLruBuilder b) + public static AtomicAsyncConcurrentLruBuilder WithAtomicCreate(this AsyncConcurrentLruBuilder b) { var a = new ConcurrentLruBuilder>(b.info); - return new AsyncAtomicLruBuilder(a); + return new AtomicAsyncConcurrentLruBuilder(a); } - public static ScopedAsyncAtomicLruBuilder AsAsyncCache(this ScopedAtomicLruBuilder b) where V : IDisposable + public static AtomicScopedAsyncConcurrentLruBuilder AsAsyncCache(this AtomicScopedConcurrentLruBuilder b) where V : IDisposable { var a = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncAtomicLruBuilder(a); + return new AtomicScopedAsyncConcurrentLruBuilder(a); } - public static ScopedAsyncAtomicLruBuilder WithScopedValues(this AsyncAtomicLruBuilder b) where V : IDisposable + public static AtomicScopedAsyncConcurrentLruBuilder WithScopedValues(this AtomicAsyncConcurrentLruBuilder b) where V : IDisposable { var a = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncAtomicLruBuilder(a); + return new AtomicScopedAsyncConcurrentLruBuilder(a); } - public static ScopedAsyncAtomicLruBuilder WithAtomicCreate(this ScopedAsyncLruBuilder b) where V : IDisposable + public static AtomicScopedAsyncConcurrentLruBuilder WithAtomicCreate(this ScopedAsyncConcurrentLruBuilder b) where V : IDisposable { var a = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncAtomicLruBuilder(a); + return new AtomicScopedAsyncConcurrentLruBuilder(a); } } } From c7008ce612b8fa982be8c91cc63c32c5d7b1669e Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 16:33:33 -0700 Subject: [PATCH 2/3] comments --- .../Lru/ConcurrentLruBuilderTests.cs | 12 -- BitFaster.Caching/Lru/ConcurrentLruBuilder.cs | 2 +- .../Lru/ConcurrentLruBuilderExtensions.cs | 156 ++++++++++++++---- 3 files changed, 121 insertions(+), 49 deletions(-) diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs index 9ffa9a59..260b5b74 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs @@ -315,8 +315,6 @@ public void AsAsyncWithAtomic() [Fact] public void WithAtomicWithScopedAsAsync() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .WithAtomicCreate() .WithScopedValues() @@ -331,8 +329,6 @@ public void WithAtomicWithScopedAsAsync() [Fact] public void WithAtomicAsAsyncWithScoped() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .WithAtomicCreate() .AsAsyncCache() @@ -347,8 +343,6 @@ public void WithAtomicAsAsyncWithScoped() [Fact] public void WithScopedWithAtomicAsAsync() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .WithScopedValues() .WithAtomicCreate() @@ -363,8 +357,6 @@ public void WithScopedWithAtomicAsAsync() [Fact] public void WithScopedAsAsyncWithAtomic() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .WithScopedValues() .AsAsyncCache() @@ -379,8 +371,6 @@ public void WithScopedAsAsyncWithAtomic() [Fact] public void AsAsyncWithScopedWithAtomic() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() .WithScopedValues() @@ -395,8 +385,6 @@ public void AsAsyncWithScopedWithAtomic() [Fact] public void AsAsyncWithAtomicWithScoped() { - // TODO: this will not resolve a TLru - IScopedAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() .WithAtomicCreate() diff --git a/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs b/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs index 91b3431d..57381fd1 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs @@ -24,7 +24,7 @@ namespace BitFaster.Caching.Lru public sealed class ConcurrentLruBuilder : LruBuilderBase, ICache> { /// - /// Creates a ConcurrentLruBuilder. + /// Creates a ConcurrentLruBuilder. Chain method calls onto ConcurrentLruBuilder to configure the cache then call Build to create a cache instance. /// public ConcurrentLruBuilder() : base(new LruInfo()) diff --git a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs index 2894d183..fde476e1 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs @@ -17,77 +17,161 @@ public static class ConcurrentLruBuilderExtensions /// The type of keys in the cache. /// The type of values in the cache. /// The ConcurrentLruBuilder to chain method calls onto. - /// A ScopedLruBuilder + /// A ScopedConcurrentLruBuilder. public static ScopedConcurrentLruBuilder> WithScopedValues(this ConcurrentLruBuilder builder) where V : IDisposable { - var scoped = new ConcurrentLruBuilder>(builder.info); - return new ScopedConcurrentLruBuilder>(scoped); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new ScopedConcurrentLruBuilder>(convertBuilder); } - public static AtomicConcurrentLruBuilder WithAtomicCreate(this ConcurrentLruBuilder b) + /// + /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// values from being disposed until the calling code completes. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AtomicConcurrentLruBuilder to chain method calls onto. + /// An AtomicScopedConcurrentLruBuilder. + public static AtomicScopedConcurrentLruBuilder WithScopedValues(this AtomicConcurrentLruBuilder builder) where V : IDisposable { - var a = new ConcurrentLruBuilder>(b.info); - return new AtomicConcurrentLruBuilder(a); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new AtomicScopedConcurrentLruBuilder(convertBuilder); } - public static AtomicScopedConcurrentLruBuilder WithAtomicCreate(this ScopedConcurrentLruBuilder b) where V : IDisposable where W : IScoped + /// + /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// values from being disposed until the calling code completes. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AsyncConcurrentLruBuilder to chain method calls onto. + /// A ScopedAsyncConcurrentLruBuilder. + public static ScopedAsyncConcurrentLruBuilder WithScopedValues(this AsyncConcurrentLruBuilder builder) where V : IDisposable { - var atomicScoped = new ConcurrentLruBuilder>(b.info); - - return new AtomicScopedConcurrentLruBuilder(atomicScoped); + var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); + return new ScopedAsyncConcurrentLruBuilder(convertBuilder); } - public static AtomicScopedConcurrentLruBuilder WithScopedValues(this AtomicConcurrentLruBuilder b) where V : IDisposable + /// + /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// values from being disposed until the calling code completes. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AtomicAsyncConcurrentLruBuilder to chain method calls onto. + /// An AtomicScopedAsyncConcurrentLruBuilder. + public static AtomicScopedAsyncConcurrentLruBuilder WithScopedValues(this AtomicAsyncConcurrentLruBuilder builder) where V : IDisposable { - var atomicScoped = new ConcurrentLruBuilder>(b.info); - return new AtomicScopedConcurrentLruBuilder(atomicScoped); + var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); + return new AtomicScopedAsyncConcurrentLruBuilder(convertBuilder); } - public static AsyncConcurrentLruBuilder AsAsyncCache(this ConcurrentLruBuilder builder) + /// + /// Execute the cache's GetOrAdd value factory atomically, such that it is applied at most once per key. Other threads + /// attempting to update the same key will be blocked until value factory completes. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The ConcurrentLruBuilder to chain method calls onto. + /// An AtomicConcurrentLruBuilder. + public static AtomicConcurrentLruBuilder WithAtomicCreate(this ConcurrentLruBuilder builder) { - return new AsyncConcurrentLruBuilder(builder.info); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new AtomicConcurrentLruBuilder(convertBuilder); } - public static ScopedAsyncConcurrentLruBuilder WithScopedValues(this AsyncConcurrentLruBuilder b) where V : IDisposable + /// + /// Execute the cache's ScopedGetOrAdd value factory atomically, such that it is applied at most once per key. Other threads + /// attempting to update the same key will be blocked until value factory completes. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The wrapped value type. + /// The ScopedConcurrentLruBuilder to chain method calls onto. + /// An AtomicScopedConcurrentLruBuilder. + public static AtomicScopedConcurrentLruBuilder WithAtomicCreate(this ScopedConcurrentLruBuilder builder) where V : IDisposable where W : IScoped { - var asyncScoped = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncConcurrentLruBuilder(asyncScoped); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new AtomicScopedConcurrentLruBuilder(convertBuilder); } - public static ScopedAsyncConcurrentLruBuilder AsAsyncCache(this ScopedConcurrentLruBuilder> b) where V : IDisposable + /// + /// Execute the cache's GetOrAddAsync value factory atomically, such that it is applied at most once per key. Other threads + /// attempting to update the same key will wait on the same value factory task. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AsyncConcurrentLruBuilder to chain method calls onto. + /// An AtomicAsyncConcurrentLruBuilder. + public static AtomicAsyncConcurrentLruBuilder WithAtomicCreate(this AsyncConcurrentLruBuilder builder) { - var asyncScoped = new AsyncConcurrentLruBuilder>(b.info); - return new ScopedAsyncConcurrentLruBuilder(asyncScoped); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new AtomicAsyncConcurrentLruBuilder(convertBuilder); } - public static AtomicAsyncConcurrentLruBuilder AsAsyncCache(this AtomicConcurrentLruBuilder b) + /// + /// Execute the cache's ScopedGetOrAddAsync value factory atomically, such that it is applied at most once per key. Other threads + /// attempting to update the same key will wait on the same value factory task. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The ScopedAsyncConcurrentLruBuilder to chain method calls onto. + /// An AtomicScopedAsyncConcurrentLruBuilder. + public static AtomicScopedAsyncConcurrentLruBuilder WithAtomicCreate(this ScopedAsyncConcurrentLruBuilder builder) where V : IDisposable { - var a = new ConcurrentLruBuilder>(b.info); - return new AtomicAsyncConcurrentLruBuilder(a); + var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); + return new AtomicScopedAsyncConcurrentLruBuilder(convertBuilder); } - public static AtomicAsyncConcurrentLruBuilder WithAtomicCreate(this AsyncConcurrentLruBuilder b) + /// + /// Build an IAsyncCache, the GetOrAdd method becomes GetOrAddAsync. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The ConcurrentLruBuilder to chain method calls onto. + /// An AsyncConcurrentLruBuilder. + public static AsyncConcurrentLruBuilder AsAsyncCache(this ConcurrentLruBuilder builder) { - var a = new ConcurrentLruBuilder>(b.info); - return new AtomicAsyncConcurrentLruBuilder(a); + return new AsyncConcurrentLruBuilder(builder.info); } - public static AtomicScopedAsyncConcurrentLruBuilder AsAsyncCache(this AtomicScopedConcurrentLruBuilder b) where V : IDisposable + /// + /// Build an IScopedAsyncCache, the ScopedGetOrAdd method becomes ScopedGetOrAddAsync. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The ScopedConcurrentLruBuilder to chain method calls onto. + /// A ScopedAsyncConcurrentLruBuilder. + public static ScopedAsyncConcurrentLruBuilder AsAsyncCache(this ScopedConcurrentLruBuilder> builder) where V : IDisposable { - var a = new AsyncConcurrentLruBuilder>(b.info); - return new AtomicScopedAsyncConcurrentLruBuilder(a); + var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); + return new ScopedAsyncConcurrentLruBuilder(convertBuilder); } - public static AtomicScopedAsyncConcurrentLruBuilder WithScopedValues(this AtomicAsyncConcurrentLruBuilder b) where V : IDisposable + /// + /// Build an IAsyncCache, the GetOrAdd method becomes GetOrAddAsync. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AtomicConcurrentLruBuilder to chain method calls onto. + /// An AtomicAsyncConcurrentLruBuilder. + public static AtomicAsyncConcurrentLruBuilder AsAsyncCache(this AtomicConcurrentLruBuilder builder) { - var a = new AsyncConcurrentLruBuilder>(b.info); - return new AtomicScopedAsyncConcurrentLruBuilder(a); + var convertBuilder = new ConcurrentLruBuilder>(builder.info); + return new AtomicAsyncConcurrentLruBuilder(convertBuilder); } - public static AtomicScopedAsyncConcurrentLruBuilder WithAtomicCreate(this ScopedAsyncConcurrentLruBuilder b) where V : IDisposable + /// + /// Build an IScopedAsyncCache, the ScopedGetOrAdd method becomes ScopedGetOrAddAsync. + /// + /// The type of keys in the cache. + /// The type of values in the cache. + /// The AtomicScopedConcurrentLruBuilder to chain method calls onto. + /// An AtomicScopedAsyncConcurrentLruBuilder. + public static AtomicScopedAsyncConcurrentLruBuilder AsAsyncCache(this AtomicScopedConcurrentLruBuilder builder) where V : IDisposable { - var a = new AsyncConcurrentLruBuilder>(b.info); - return new AtomicScopedAsyncConcurrentLruBuilder(a); + var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); + return new AtomicScopedAsyncConcurrentLruBuilder(convertBuilder); } } } From 01f890b5199dd4fd69fb92dbad2e0ec150197ccd Mon Sep 17 00:00:00 2001 From: Alex Peck Date: Sun, 24 Jul 2022 16:47:29 -0700 Subject: [PATCH 3/3] rename --- .../Lru/LruAsyncGet.cs | 2 +- .../Lru/LruJustGetOrAdd.cs | 2 +- .../Lru/ConcurrentLruBuilderTests.cs | 44 +++++++++---------- .../Lru/ConcurrentLruBuilderExtensions.cs | 24 +++++----- 4 files changed, 36 insertions(+), 36 deletions(-) diff --git a/BitFaster.Caching.Benchmarks/Lru/LruAsyncGet.cs b/BitFaster.Caching.Benchmarks/Lru/LruAsyncGet.cs index 02742ee1..50677f18 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruAsyncGet.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruAsyncGet.cs @@ -20,7 +20,7 @@ public class LruAsyncGet { // if the cache value is a value type, value task has no effect - so use string to repro. private static readonly IAsyncCache concurrentLru = new ConcurrentLruBuilder().AsAsyncCache().Build(); - private static readonly IAsyncCache atomicConcurrentLru = new ConcurrentLruBuilder().AsAsyncCache().WithAtomicCreate().Build(); + private static readonly IAsyncCache atomicConcurrentLru = new ConcurrentLruBuilder().AsAsyncCache().WithAtomicValueFactory().Build(); private static Task returnTask = Task.FromResult("1"); diff --git a/BitFaster.Caching.Benchmarks/Lru/LruJustGetOrAdd.cs b/BitFaster.Caching.Benchmarks/Lru/LruJustGetOrAdd.cs index d7a90a91..7d71d992 100644 --- a/BitFaster.Caching.Benchmarks/Lru/LruJustGetOrAdd.cs +++ b/BitFaster.Caching.Benchmarks/Lru/LruJustGetOrAdd.cs @@ -44,7 +44,7 @@ public class LruJustGetOrAdd private static readonly FastConcurrentLru fastConcurrentLru = new FastConcurrentLru(8, 9, EqualityComparer.Default); private static readonly FastConcurrentTLru fastConcurrentTLru = new FastConcurrentTLru(8, 9, EqualityComparer.Default, TimeSpan.FromMinutes(1)); - private static readonly ICache atomicFastLru = new ConcurrentLruBuilder().WithConcurrencyLevel(8).WithCapacity(9).WithAtomicCreate().Build(); + private static readonly ICache atomicFastLru = new ConcurrentLruBuilder().WithConcurrencyLevel(8).WithCapacity(9).WithAtomicValueFactory().Build(); private static readonly int key = 1; private static System.Runtime.Caching.MemoryCache memoryCache = System.Runtime.Caching.MemoryCache.Default; diff --git a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs index 260b5b74..c8920345 100644 --- a/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs +++ b/BitFaster.Caching.UnitTests/Lru/ConcurrentLruBuilderTests.cs @@ -196,7 +196,7 @@ public void TestPartitionCapacity() public void WithScopedValues() { IScopedCache lru = new ConcurrentLruBuilder() - .WithScopedValues() + .AsScopedCache() .WithCapacity(3) .Build(); @@ -209,7 +209,7 @@ public void WithScopedValues() public void WithAtomicFactory() { ICache lru = new ConcurrentLruBuilder() - .WithAtomicCreate() + .WithAtomicValueFactory() .WithCapacity(3) .Build(); @@ -233,8 +233,8 @@ public void AsAsync() public void WithAtomicWithScope() { IScopedCache lru = new ConcurrentLruBuilder() - .WithAtomicCreate() - .WithScopedValues() + .WithAtomicValueFactory() + .AsScopedCache() .WithCapacity(3) .Build(); @@ -247,8 +247,8 @@ public void WithAtomicWithScope() public void WithScopedWithAtomic() { IScopedCache lru = new ConcurrentLruBuilder() - .WithScopedValues() - .WithAtomicCreate() + .AsScopedCache() + .WithAtomicValueFactory() .WithCapacity(3) .Build(); @@ -262,7 +262,7 @@ public void AsAsyncWithScoped() { IScopedAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() - .WithScopedValues() + .AsScopedCache() .WithCapacity(3) .Build(); @@ -276,7 +276,7 @@ public void AsAsyncWithScoped() public void WithScopedAsAsync() { IScopedAsyncCache lru = new ConcurrentLruBuilder() - .WithScopedValues() + .AsScopedCache() .AsAsyncCache() .WithCapacity(3) .Build(); @@ -290,7 +290,7 @@ public void WithScopedAsAsync() public void WithAtomicAsAsync() { IAsyncCache lru = new ConcurrentLruBuilder() - .WithAtomicCreate() + .WithAtomicValueFactory() .AsAsyncCache() .WithCapacity(3) .Build(); @@ -304,7 +304,7 @@ public void AsAsyncWithAtomic() { IAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() - .WithAtomicCreate() + .WithAtomicValueFactory() .WithCapacity(3) .Build(); @@ -316,8 +316,8 @@ public void AsAsyncWithAtomic() public void WithAtomicWithScopedAsAsync() { IScopedAsyncCache lru = new ConcurrentLruBuilder() - .WithAtomicCreate() - .WithScopedValues() + .WithAtomicValueFactory() + .AsScopedCache() .AsAsyncCache() .WithCapacity(3) .Build(); @@ -330,9 +330,9 @@ public void WithAtomicWithScopedAsAsync() public void WithAtomicAsAsyncWithScoped() { IScopedAsyncCache lru = new ConcurrentLruBuilder() - .WithAtomicCreate() + .WithAtomicValueFactory() .AsAsyncCache() - .WithScopedValues() + .AsScopedCache() .WithCapacity(3) .Build(); @@ -344,8 +344,8 @@ public void WithAtomicAsAsyncWithScoped() public void WithScopedWithAtomicAsAsync() { IScopedAsyncCache lru = new ConcurrentLruBuilder() - .WithScopedValues() - .WithAtomicCreate() + .AsScopedCache() + .WithAtomicValueFactory() .AsAsyncCache() .WithCapacity(3) .Build(); @@ -358,9 +358,9 @@ public void WithScopedWithAtomicAsAsync() public void WithScopedAsAsyncWithAtomic() { IScopedAsyncCache lru = new ConcurrentLruBuilder() - .WithScopedValues() + .AsScopedCache() .AsAsyncCache() - .WithAtomicCreate() + .WithAtomicValueFactory() .WithCapacity(3) .Build(); @@ -373,8 +373,8 @@ public void AsAsyncWithScopedWithAtomic() { IScopedAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() - .WithScopedValues() - .WithAtomicCreate() + .AsScopedCache() + .WithAtomicValueFactory() .WithCapacity(3) .Build(); @@ -387,8 +387,8 @@ public void AsAsyncWithAtomicWithScoped() { IScopedAsyncCache lru = new ConcurrentLruBuilder() .AsAsyncCache() - .WithAtomicCreate() - .WithScopedValues() + .WithAtomicValueFactory() + .AsScopedCache() .WithCapacity(3) .Build(); diff --git a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs index fde476e1..a123050c 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruBuilderExtensions.cs @@ -11,56 +11,56 @@ namespace BitFaster.Caching.Lru public static class ConcurrentLruBuilderExtensions { /// - /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// Build an IScopedCache. IDisposable values are wrapped in a lifetime scope. Scoped caches return lifetimes that prevent /// values from being disposed until the calling code completes. /// /// The type of keys in the cache. /// The type of values in the cache. /// The ConcurrentLruBuilder to chain method calls onto. /// A ScopedConcurrentLruBuilder. - public static ScopedConcurrentLruBuilder> WithScopedValues(this ConcurrentLruBuilder builder) where V : IDisposable + public static ScopedConcurrentLruBuilder> AsScopedCache(this ConcurrentLruBuilder builder) where V : IDisposable { var convertBuilder = new ConcurrentLruBuilder>(builder.info); return new ScopedConcurrentLruBuilder>(convertBuilder); } /// - /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// Build an IScopedCache. IDisposable values are wrapped in a lifetime scope. Scoped caches return lifetimes that prevent /// values from being disposed until the calling code completes. /// /// The type of keys in the cache. /// The type of values in the cache. /// The AtomicConcurrentLruBuilder to chain method calls onto. /// An AtomicScopedConcurrentLruBuilder. - public static AtomicScopedConcurrentLruBuilder WithScopedValues(this AtomicConcurrentLruBuilder builder) where V : IDisposable + public static AtomicScopedConcurrentLruBuilder AsScopedCache(this AtomicConcurrentLruBuilder builder) where V : IDisposable { var convertBuilder = new ConcurrentLruBuilder>(builder.info); return new AtomicScopedConcurrentLruBuilder(convertBuilder); } /// - /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// Build an IScopedAsyncCache. IDisposable values are wrapped in a lifetime scope. Scoped caches return lifetimes that prevent /// values from being disposed until the calling code completes. /// /// The type of keys in the cache. /// The type of values in the cache. /// The AsyncConcurrentLruBuilder to chain method calls onto. /// A ScopedAsyncConcurrentLruBuilder. - public static ScopedAsyncConcurrentLruBuilder WithScopedValues(this AsyncConcurrentLruBuilder builder) where V : IDisposable + public static ScopedAsyncConcurrentLruBuilder AsScopedCache(this AsyncConcurrentLruBuilder builder) where V : IDisposable { var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); return new ScopedAsyncConcurrentLruBuilder(convertBuilder); } /// - /// Wrap IDisposable values in a lifetime scope. Scoped caches return lifetimes that prevent + /// Build an IScopedAsyncCache. IDisposable values are wrapped in a lifetime scope. Scoped caches return lifetimes that prevent /// values from being disposed until the calling code completes. /// /// The type of keys in the cache. /// The type of values in the cache. /// The AtomicAsyncConcurrentLruBuilder to chain method calls onto. /// An AtomicScopedAsyncConcurrentLruBuilder. - public static AtomicScopedAsyncConcurrentLruBuilder WithScopedValues(this AtomicAsyncConcurrentLruBuilder builder) where V : IDisposable + public static AtomicScopedAsyncConcurrentLruBuilder AsScopedCache(this AtomicAsyncConcurrentLruBuilder builder) where V : IDisposable { var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); return new AtomicScopedAsyncConcurrentLruBuilder(convertBuilder); @@ -74,7 +74,7 @@ public static AtomicScopedAsyncConcurrentLruBuilder WithScopedValues /// The type of values in the cache. /// The ConcurrentLruBuilder to chain method calls onto. /// An AtomicConcurrentLruBuilder. - public static AtomicConcurrentLruBuilder WithAtomicCreate(this ConcurrentLruBuilder builder) + public static AtomicConcurrentLruBuilder WithAtomicValueFactory(this ConcurrentLruBuilder builder) { var convertBuilder = new ConcurrentLruBuilder>(builder.info); return new AtomicConcurrentLruBuilder(convertBuilder); @@ -89,7 +89,7 @@ public static AtomicConcurrentLruBuilder WithAtomicCreate(this Concu /// The wrapped value type. /// The ScopedConcurrentLruBuilder to chain method calls onto. /// An AtomicScopedConcurrentLruBuilder. - public static AtomicScopedConcurrentLruBuilder WithAtomicCreate(this ScopedConcurrentLruBuilder builder) where V : IDisposable where W : IScoped + public static AtomicScopedConcurrentLruBuilder WithAtomicValueFactory(this ScopedConcurrentLruBuilder builder) where V : IDisposable where W : IScoped { var convertBuilder = new ConcurrentLruBuilder>(builder.info); return new AtomicScopedConcurrentLruBuilder(convertBuilder); @@ -103,7 +103,7 @@ public static AtomicScopedConcurrentLruBuilder WithAtomicCreate(t /// The type of values in the cache. /// The AsyncConcurrentLruBuilder to chain method calls onto. /// An AtomicAsyncConcurrentLruBuilder. - public static AtomicAsyncConcurrentLruBuilder WithAtomicCreate(this AsyncConcurrentLruBuilder builder) + public static AtomicAsyncConcurrentLruBuilder WithAtomicValueFactory(this AsyncConcurrentLruBuilder builder) { var convertBuilder = new ConcurrentLruBuilder>(builder.info); return new AtomicAsyncConcurrentLruBuilder(convertBuilder); @@ -117,7 +117,7 @@ public static AtomicAsyncConcurrentLruBuilder WithAtomicCreate(this /// The type of values in the cache. /// The ScopedAsyncConcurrentLruBuilder to chain method calls onto. /// An AtomicScopedAsyncConcurrentLruBuilder. - public static AtomicScopedAsyncConcurrentLruBuilder WithAtomicCreate(this ScopedAsyncConcurrentLruBuilder builder) where V : IDisposable + public static AtomicScopedAsyncConcurrentLruBuilder WithAtomicValueFactory(this ScopedAsyncConcurrentLruBuilder builder) where V : IDisposable { var convertBuilder = new AsyncConcurrentLruBuilder>(builder.info); return new AtomicScopedAsyncConcurrentLruBuilder(convertBuilder);