diff --git a/FastCache/FastCache.cs b/FastCache/FastCache.cs
index 5dad6b8..9ea45ab 100644
--- a/FastCache/FastCache.cs
+++ b/FastCache/FastCache.cs
@@ -173,13 +173,7 @@ public bool TryAdd(TKey key, TValue value, TimeSpan ttl)
return _dict.TryAdd(key, new TtlValue(value, ttl));
}
- ///
- /// Adds a key/value pair by using the specified function if the key does not already exist, or returns the existing value if the key exists.
- ///
- /// The key to add
- /// The factory function used to generate the item for the key
- /// TTL of the item
- public TValue GetOrAdd(TKey key, Func valueFactory, TimeSpan ttl)
+ private TValue GetOrAddCore(TKey key, Func valueFactory, TimeSpan ttl)
{
bool wasAdded = false; //flag to indicate "add vs get". TODO: wrap in ref type some day to avoid captures/closures
var ttlValue = _dict.GetOrAdd(
@@ -187,19 +181,28 @@ public TValue GetOrAdd(TKey key, Func valueFactory, TimeSpan ttl)
(k) =>
{
wasAdded = true;
- return new TtlValue(valueFactory(k), ttl);
+ return new TtlValue(valueFactory(), ttl);
});
//if the item is expired, update value and TTL
//since TtlValue is a reference type we can update its properties in-place, instead of removing and re-adding to the dictionary (extra lookups)
if (!wasAdded) //performance hack: skip expiration check if a brand item was just added
{
- ttlValue.ModifyIfExpired(() => valueFactory(key), ttl);
+ ttlValue.ModifyIfExpired(valueFactory, ttl);
}
return ttlValue.Value;
}
+ ///
+ /// Adds a key/value pair by using the specified function if the key does not already exist, or returns the existing value if the key exists.
+ ///
+ /// The key to add
+ /// The factory function used to generate the item for the key
+ /// TTL of the item
+ public TValue GetOrAdd(TKey key, Func valueFactory, TimeSpan ttl)
+ => GetOrAddCore(key, () => valueFactory(key), ttl);
+
///
/// Adds a key/value pair by using the specified function if the key does not already exist, or returns the existing value if the key exists.
///
@@ -208,25 +211,7 @@ public TValue GetOrAdd(TKey key, Func valueFactory, TimeSpan ttl)
/// TTL of the item
/// Argument value to pass into valueFactory
public TValue GetOrAdd(TKey key, Func valueFactory, TimeSpan ttl, TArg factoryArgument)
- {
- bool wasAdded = false; //flag to indicate "add vs get"
- var ttlValue = _dict.GetOrAdd(
- key,
- (k) =>
- {
- wasAdded = true;
- return new TtlValue(valueFactory(k, factoryArgument), ttl);
- });
-
- //if the item is expired, update value and TTL
- //since TtlValue is a reference type we can update its properties in-place, instead of removing and re-adding to the dictionary (extra lookups)
- if (!wasAdded) //performance hack: skip expiration check if a brand item was just added
- {
- ttlValue.ModifyIfExpired(() => valueFactory(key, factoryArgument), ttl);
- }
-
- return ttlValue.Value;
- }
+ => GetOrAddCore(key, () => valueFactory(key, factoryArgument), ttl);
///
/// Adds a key/value pair by using the specified function if the key does not already exist, or returns the existing value if the key exists.
@@ -235,24 +220,7 @@ public TValue GetOrAdd(TKey key, Func valueFactory, Ti
/// The value to add
/// TTL of the item
public TValue GetOrAdd(TKey key, TValue value, TimeSpan ttl)
- {
- bool wasAdded = false; //flag to indicate "add vs get"
- var ttlValue = _dict.GetOrAdd(key,
- (k) =>
- {
- wasAdded = true;
- return new TtlValue(value, ttl);
- });
-
- //if the item is expired, update value and TTL
- //since TtlValue is a reference type we can update its properties in-place, instead of removing and re-adding to the dictionary (extra lookups)
- if (!wasAdded) //performance hack: skip expiration check if a brand item was just added
- {
- ttlValue.ModifyIfExpired(() => value, ttl);
- }
-
- return ttlValue.Value;
- }
+ => GetOrAddCore(key, () => value, ttl);
///
/// Tries to remove item with the specified key