Skip to content

Instantly share code, notes, and snippets.

@thomaslevesque
Forked from jaredpar/Cache.cs
Last active December 21, 2015 11:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomaslevesque/ecdd3640a0601768386f to your computer and use it in GitHub Desktop.
Save thomaslevesque/ecdd3640a0601768386f to your computer and use it in GitHub Desktop.
class Cache<TKey, TValue>
{
private IImmutableDictionary<TKey, TValue> _cache = ImmutableDictionary.Create<TKey, TValue>();
public TValue GetOrAdd(TKey key, [NotNull] Func<TKey, TValue> valueFactory)
{
valueFactory.CheckArgumentNull("valueFactory");
TValue newValue = default(TValue);
bool newValueCreated = false;
while (true)
{
var oldCache = _cache;
TValue value;
if (oldCache.TryGetValue(key, out value))
return value;
// Value not found; create it if necessary
if (!newValueCreated)
{
newValue = valueFactory(key);
newValueCreated = true;
}
// Add the new value to the cache
var newCache = oldCache.Add(key, newValue);
if (Interlocked.CompareExchange(ref _cache, newCache, oldCache) == oldCache)
{
// Cache successfully written
return newValue;
}
// Failed to write the new cache, try again
}
}
public void Clear()
{
_cache = _cache.Clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment