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
8 changes: 1 addition & 7 deletions BitFaster.Caching/Lru/Builder/AsyncConcurrentLruBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@ internal AsyncConcurrentLruBuilder(LruInfo<K> info)
///<inheritdoc/>
public override IAsyncCache<K, V> Build()
{
return info switch
{
LruInfo<K> i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue => new ConcurrentLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
LruInfo<K> i when i.WithMetrics && i.TimeToExpireAfterWrite.HasValue => new ConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
LruInfo<K> i when i.TimeToExpireAfterWrite.HasValue => new FastConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
_ => new FastConcurrentLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
};
return LruFactory<K, V>.CreateConcurrent(this.info) as IAsyncCache<K, V>;
}
}
}
19 changes: 1 addition & 18 deletions BitFaster.Caching/Lru/ConcurrentLruBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,7 @@ internal ConcurrentLruBuilder(LruInfo<K> info)
///<inheritdoc/>
public override ICache<K, V> Build()
{
if (info.TimeToExpireAfterWrite.HasValue && info.TimeToExpireAfterAccess.HasValue)
Throw.InvalidOp("Specifying both ExpireAfterWrite and ExpireAfterAccess is not supported.");

return info switch
{
LruInfo<K> i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new ConcurrentLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
LruInfo<K> i when i.WithMetrics && i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new ConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
LruInfo<K> i when i.TimeToExpireAfterWrite.HasValue && !i.TimeToExpireAfterAccess.HasValue => new FastConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
LruInfo<K> i when i.WithMetrics && !i.TimeToExpireAfterWrite.HasValue && i.TimeToExpireAfterAccess.HasValue => CreateExpireAfterAccess<TelemetryPolicy<K, V>>(info),
LruInfo<K> i when !i.TimeToExpireAfterWrite.HasValue && i.TimeToExpireAfterAccess.HasValue => CreateExpireAfterAccess<NoTelemetryPolicy<K, V>>(info),
_ => new FastConcurrentLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
};
}

private static ICache<K, V> CreateExpireAfterAccess<TP>(LruInfo<K> info) where TP : struct, ITelemetryPolicy<K, V>
{
return new ConcurrentLruCore<K, V, LongTickCountLruItem<K, V>, AfterAccessLongTicksPolicy<K, V>, TP>(
info.ConcurrencyLevel, info.Capacity, info.KeyComparer, new AfterAccessLongTicksPolicy<K, V>(info.TimeToExpireAfterAccess.Value), default);
return LruFactory<K, V>.CreateConcurrent(this.info);
}
}
}
38 changes: 38 additions & 0 deletions BitFaster.Caching/Lru/LruFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Linq.Expressions;
using BitFaster.Caching.Lru.Builder;

namespace BitFaster.Caching.Lru
{
/// <summary>
/// Factory class for creating ConcurrentLru variants.
/// </summary>
internal static class LruFactory<K, V>
{
/// <summary>
/// Creates a ConcurrentLru instance based on the provided LruInfo.
/// </summary>
/// <param name="info">The LruInfo</param>
/// <returns>A ConcurrentLru</returns>
internal static ICache<K, V> CreateConcurrent(LruInfo<K> 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<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
(true, true, false) => new ConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
(false, true, false) => new FastConcurrentTLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer, info.TimeToExpireAfterWrite.Value),
(true, false, true) => CreateExpireAfterAccess<TelemetryPolicy<K, V>>(info),
(false, false, true) => CreateExpireAfterAccess<NoTelemetryPolicy<K, V>>(info),
_ => new FastConcurrentLru<K, V>(info.ConcurrencyLevel, info.Capacity, info.KeyComparer),
};
}

private static ICache<K, V> CreateExpireAfterAccess<TP>(LruInfo<K> info) where TP : struct, ITelemetryPolicy<K, V>
{
return new ConcurrentLruCore<K, V, LongTickCountLruItem<K, V>, AfterAccessLongTicksPolicy<K, V>, TP>(
info.ConcurrencyLevel, info.Capacity, info.KeyComparer, new AfterAccessLongTicksPolicy<K, V>(info.TimeToExpireAfterAccess.Value), default);
}
}
}