/// <summary>Removes all items from the <see cref="Cache"/> object.</summary> public void Clear() { _rwl.AcquireWriterLock(LOCK_TIMEOUT_MSECS); try { if (_data.Count > 0) { foreach (object key in _data.Keys) { if (key != null) { CacheCollectionElement element = _data[key] as CacheCollectionElement; if (element != null) { element.IsCollectable = true; } } } _data.Clear(); } } finally { _rwl.ReleaseWriterLock(); } }
/// <summary>Removes the specified item from the <see cref="Cache"/> object.</summary> /// <param name="key">The cache key of the item to remove.</param> /// <returns>The item removed from the cache. If the value in the key parameter is not found, returns a null reference.</returns> public object Remove(object key) { if (key != null) { _rwl.AcquireWriterLock(LOCK_TIMEOUT_MSECS); try { CacheCollectionElement element = _data[key] as CacheCollectionElement; if (element != null) { object value = element.Value; element.IsCollectable = true; _data.Remove(key); return(value); } } finally { _rwl.ReleaseWriterLock(); } } else { throw new ArgumentNullException("key"); } return(null); }
/// <summary> /// Inserts an item into the <see cref="Cache"/> object with a specified lifetime using a cache key to reference its location. /// </summary> /// <param name="key">The cache key used to reference the item.</param> /// <param name="value">The object to be inserted into the cache.</param> /// <param name="lifetime">The lifetime of the inserted item (i.e. is it expendable or not).</param> public void Insert(object key, object value, CacheItemLifetime lifetime) { if (key != null) { _rwl.AcquireWriterLock(LOCK_TIMEOUT_MSECS); try { // remove any existing item for this key CacheCollectionElement element = _data[key] as CacheCollectionElement; if (element != null) { element.IsCollectable = true; _data.Remove(key); } // add new item element = new CacheCollectionElement(value, lifetime); _data[key] = element; } finally { _rwl.ReleaseWriterLock(); } } else { throw new ArgumentNullException("key"); } }
/// <summary>Compresses the <see cref="Cache"/>, removing references to collected items (if any).</summary> /// <returns>The count of live items in the <see cref="Cache"/>.</returns> private int Purge() { int liveItemCount = 0; _rwl.AcquireWriterLock(LOCK_TIMEOUT_MSECS); try { // if no items in Cache, we're done... if (_data.Count > 0) { // check to see if the data for any elements has been collected ArrayList collected = new ArrayList(); foreach (object key in _data.Keys) { if (key != null) { CacheCollectionElement element = _data[key] as CacheCollectionElement; if (element != null) { if (element.IsCollected) { collected.Add(key); } } } } // remove collected elements from the cache if (collected.Count > 0) { foreach (object key in collected) { _data.Remove(key); } } // the Cache item count should now only refer to live, accessible items... liveItemCount = _data.Count; } } finally { _rwl.ReleaseWriterLock(); } return(liveItemCount); }
/// <summary>Retrieves the specified item from the <see cref="Cache"/> object.</summary> /// <param name="key">The cache key of the item to retrieve.</param> /// <returns>The retrieved cache item, or a null reference if the key is not found.</returns> public object Get(object key) { if (key != null) { _rwl.AcquireReaderLock(LOCK_TIMEOUT_MSECS); try { CacheCollectionElement element = _data[key] as CacheCollectionElement; if (element != null) { if (!element.IsCollected) { return(element.Value); } else { // we're modifying the collection so upgrade to writer lock LockCookie lockCookie = _rwl.UpgradeToWriterLock(LOCK_TIMEOUT_MSECS); _data.Remove(key); // done -- downgrade to reader lock _rwl.DowngradeFromWriterLock(ref lockCookie); } } } finally { // ReleaseLock is used in lieu of ReleaseWriterLock/ReleaseReaderLock due to the lock upgrade logic. // Since we don't need to support nested locks here this should be OK... _rwl.ReleaseLock(); } } else { throw new ArgumentNullException("key"); } return(null); }