Created
November 11, 2009 10:35
-
-
Save JeffreyZhao/231847 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
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; | |
} | |
} |
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
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