diff --git a/BitFaster.Caching/Lru/Builder/AsyncConcurrentLruBuilder.cs b/BitFaster.Caching/Lru/Builder/AsyncConcurrentLruBuilder.cs index db39e689..92272032 100644 --- a/BitFaster.Caching/Lru/Builder/AsyncConcurrentLruBuilder.cs +++ b/BitFaster.Caching/Lru/Builder/AsyncConcurrentLruBuilder.cs @@ -16,13 +16,7 @@ internal AsyncConcurrentLruBuilder(LruInfo info) /// public override IAsyncCache Build() { - return info switch - { - LruInfo i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue => new ConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), - LruInfo i when i.WithMetrics && i.TimeToExpireAfterWrite.HasValue => new ConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), - LruInfo i when i.TimeToExpireAfterWrite.HasValue => new FastConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), - _ => new FastConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), - }; + return LruFactory.CreateConcurrent(this.info) as IAsyncCache; } } } diff --git a/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs b/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs index 96f5192a..541d5897 100644 --- a/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs +++ b/BitFaster.Caching/Lru/ConcurrentLruBuilder.cs @@ -40,24 +40,7 @@ internal ConcurrentLruBuilder(LruInfo info) /// public override ICache Build() { - if (info.TimeToExpireAfterWrite.HasValue && info.TimeToExpireAfterAccess.HasValue) - Throw.InvalidOp("Specifying both ExpireAfterWrite and ExpireAfterAccess is not supported."); - - return info switch - { - LruInfo i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new ConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), - LruInfo i when i.WithMetrics && i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new ConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), - LruInfo i when i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new FastConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), - LruInfo i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue && i.TimeToExpireAfterAccess.HasValue => CreateExpireAfterAccess>(info), - LruInfo i when !i.TimeToExpireAfterWrite.HasValue && i.TimeToExpireAfterAccess.HasValue => CreateExpireAfterAccess>(info), - _ => new FastConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), - }; - } - - private static ICache CreateExpireAfterAccess(LruInfo info) where TP : struct, ITelemetryPolicy - { - return new ConcurrentLruCore, AfterAccessLongTicksPolicy, TP>( - info.ConcurrencyLevel, info.Capacity, info.KeyComparer, new AfterAccessLongTicksPolicy(info.TimeToExpireAfterAccess.Value), default); + return LruFactory.CreateConcurrent(this.info); } } } diff --git a/BitFaster.Caching/Lru/LruFactory.cs b/BitFaster.Caching/Lru/LruFactory.cs new file mode 100644 index 00000000..82ceecb0 --- /dev/null +++ b/BitFaster.Caching/Lru/LruFactory.cs @@ -0,0 +1,38 @@ +using System.Linq.Expressions; +using BitFaster.Caching.Lru.Builder; + +namespace BitFaster.Caching.Lru +{ + /// + /// Factory class for creating ConcurrentLru variants. + /// + internal static class LruFactory + { + /// + /// Creates a ConcurrentLru instance based on the provided LruInfo. + /// + /// The LruInfo + /// A ConcurrentLru + internal static ICache CreateConcurrent(LruInfo info) + { + if (info.TimeToExpireAfterWrite.HasValue && info.TimeToExpireAfterAccess.HasValue) + Throw.InvalidOp("Specifying both ExpireAfterWrite and ExpireAfterAccess is not supported."); + + return (info.WithMetrics, info.TimeToExpireAfterWrite.HasValue, info.TimeToExpireAfterAccess.HasValue) switch + { + (true, false, false) => new ConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), + (true, true, false) => new ConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), + (false, true, false) => new FastConcurrentTLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value), + (true, false, true) => CreateExpireAfterAccess>(info), + (false, false, true) => CreateExpireAfterAccess>(info), + _ => new FastConcurrentLru(info.ConcurrencyLevel, info.Capacity, info.KeyComparer), + }; + } + + private static ICache CreateExpireAfterAccess(LruInfo info) where TP : struct, ITelemetryPolicy + { + return new ConcurrentLruCore, AfterAccessLongTicksPolicy, TP>( + info.ConcurrencyLevel, info.Capacity, info.KeyComparer, new AfterAccessLongTicksPolicy(info.TimeToExpireAfterAccess.Value), default); + } + } +}