-
-
Save thomaslevesque/ecdd3640a0601768386f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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