internal Object this[CacheObjType cacheType] {
get {
//Let's snapshot a reference to the array up front so that
//we don't have to worry about any writers. It's important
//to grab the cache first and then numItems. In the event that
//the cache gets cleared, m_numItems will be set to 0 before
//we actually release the cache. Getting it second will cause
//us to walk only 0 elements, but not to fault.
InternalCacheItem[] cache = m_cache;
int numItems = m_numItems;
int position = FindObjectPosition(cache, numItems, cacheType, false);
if (position>=0) {
if (!BCLDebug.m_loggingNotEnabled)
LogAction(CacheAction.LookupItemHit, cacheType, cache[position].Value);
return cache[position].Value;
}
//Couldn't find it -- oh, well.
if (!BCLDebug.m_loggingNotEnabled)
LogAction(CacheAction.LookupItemMiss, cacheType);
return null;
}
set {
int position;
if (!BCLDebug.m_loggingNotEnabled)
LogAction(CacheAction.AddItem, cacheType, value);
lock(this) {
position = FindObjectPosition(m_cache, m_numItems, cacheType, true);
if (position>0) {
m_cache[position].Value = value;
m_cache[position].Key = cacheType;
if (position==m_numItems) {
m_numItems++;
}
return;
}
if (m_cache==null) {
if (!BCLDebug.m_loggingNotEnabled)
LogAction(CacheAction.AllocateCache, cacheType);
// m_copying = true;
m_cache = new InternalCacheItem[MinCacheSize];
m_cache[0].Value = value;
m_cache[0].Key = cacheType;
m_numItems = 1;
// m_copying = false;
} else {
if (!BCLDebug.m_loggingNotEnabled)
LogAction(CacheAction.GrowCache, cacheType);
// m_copying = true;
InternalCacheItem[] tempCache = new InternalCacheItem[m_numItems * 2];
for (int i=0; i<m_numItems; i++) {
tempCache[i] = m_cache[i];
}
tempCache[m_numItems].Value = value;
tempCache[m_numItems].Key = cacheType;
m_cache = tempCache;
m_numItems++;
// m_copying = false;
}
}
}
}