Skip to content

Instantly share code, notes, and snippets.

@JeffreyZhao
Created November 11, 2009 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JeffreyZhao/231847 to your computer and use it in GitHub Desktop.
Save JeffreyZhao/231847 to your computer and use it in GitHub Desktop.
public abstract class ReadFreeCache<TKey, TValue>
{
protected ReadFreeCache()
: this(null)
{ }
protected ReadFreeCache(IEqualityComparer<TKey> comparer)
{
this.m_storage = new Dictionary<TKey, TValue>(comparer);
}
public abstract TValue Create(TKey key);
private Dictionary<TKey, TValue> m_storage;
private readonly object m_writeLock = new object();
public TValue Get(TKey key)
{
TValue value;
if (this.m_storage.TryGetValue(key, out value))
{
return value;
}
lock (this.m_writeLock)
{
if (this.m_storage.TryGetValue(key, out value))
{
return value;
}
value = this.Create(key);
var newStorage = this.m_storage.ToDictionary(
p => p.Key,
p => p.Value,
this.m_storage.Comparer);
newStorage.Add(key, value);
this.m_storage = newStorage;
}
return value;
}
}
public abstract class ReadWriteCache<TKey, TValue>
{
protected ReadWriteCache()
: this(null)
{ }
protected ReadWriteCache(IEqualityComparer<TKey> comparer)
{
this.m_storage = new Dictionary<TKey, TValue>(comparer);
}
private readonly Dictionary<TKey, TValue> m_storage;
private readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();
protected abstract TValue Create(TKey key);
public TValue Get(TKey key)
{
TValue value;
this.m_rwLock.EnterReadLock();
try
{
if (this.m_storage.TryGetValue(key, out value))
{
return value;
}
}
finally
{
this.m_rwLock.ExitReadLock();
}
this.m_rwLock.EnterWriteLock();
try
{
if (this.m_storage.TryGetValue(key, out value))
{
return value;
}
value = this.Create(key);
this.m_storage.Add(key, value);
}
finally
{
this.m_rwLock.ExitWriteLock();
}
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment