| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- //
- // System.Web.Caching
- //
- // Author:
- // Patrik Torstensson ([email protected])
- //
- // (C) Copyright Patrik Torstensson, 2001
- //
- namespace System.Web.Caching
- {
- /// <summary>
- /// Responsible for holding a cache entry in the linked list bucket.
- /// </summary>
- public struct ExpiresEntry
- {
- public CacheEntry _objEntry;
- public long _ticksExpires;
- public int _intNext;
- }
- /// <summary>
- /// Holds cache entries that has a expiration in a bucket list.
- /// </summary>
- public class ExpiresBucket
- {
- private static int MIN_ENTRIES = 16;
-
- private byte _byteID;
- private int _intSize;
- private int _intCount;
- private int _intNext;
- private Cache _objManager;
- private ExpiresEntry [] _arrEntries;
- /// <summary>
- /// Constructs a new bucket.
- /// </summary>
- /// <param name="bucket">Current bucket ID.</param>
- /// <param name="objManager">Cache manager reponsible for the item(s) in the expires bucket.</param>
- public ExpiresBucket(byte bucket, Cache objManager)
- {
- _objManager = objManager;
- Initialize(bucket);
- }
- /// <summary>
- /// Initializes the expires bucket, creates a linked list of MIN_ENTRIES.
- /// </summary>
- /// <param name="bucket">Bucket ID.</param>
- private void Initialize(byte bucket)
- {
- _byteID = bucket;
- _intNext = 0;
- _intCount = 0;
- _arrEntries = new ExpiresEntry[MIN_ENTRIES];
- _intSize = MIN_ENTRIES;
- int intPos = 0;
- do
- {
- _arrEntries[intPos]._intNext = intPos + 1;
- _arrEntries[intPos]._ticksExpires = System.DateTime.MaxValue.Ticks;
-
- intPos++;
- } while (intPos < _intSize);
- _arrEntries[_intSize - 1]._intNext = -1;
- }
- /// <summary>
- /// Expands the bucket linked array list.
- /// </summary>
- private void Expand()
- {
- ExpiresEntry [] arrData;
- int intPos = 0;
- int intOldSize;
- lock(this)
- {
- intOldSize = _intSize;
- _intSize *= 2;
- // Create a new array and copy the old data into the new array
- arrData = new ExpiresEntry[_intSize];
- do
- {
- arrData[intPos] = _arrEntries[intPos];
- intPos++;
- } while (intPos < intOldSize);
- _intNext = intPos;
- // Initialize the "new" positions.
- do
- {
- arrData[intPos]._intNext = intPos + 1;
- intPos++;
- } while (intPos < _intSize);
- arrData[_intSize - 1]._intNext = -1;
- _arrEntries = arrData;
- }
- }
- /// <summary>
- /// Adds a cache entry into the expires bucket.
- /// </summary>
- /// <param name="objEntry">Cache Entry object to be added.</param>
- public void Add(CacheEntry objEntry)
- {
- if (_intNext == -1)
- {
- Expand();
- }
-
- lock(this)
- {
- _arrEntries[_intNext]._ticksExpires = objEntry.Expires;
- _arrEntries[_intNext]._objEntry = objEntry;
- _intNext = _arrEntries[_intNext]._intNext;
-
- _intCount++;
- }
- }
- /// <summary>
- /// Removes a cache entry from the expires bucket.
- /// </summary>
- /// <param name="objEntry">Cache entry to be removed.</param>
- public void Remove(CacheEntry objEntry)
- {
- lock(this)
- {
- // Check if this is our bucket
- if (objEntry.ExpiresIndex != _byteID) return;
- if (objEntry.ExpiresIndex == System.Int32.MaxValue) return;
- if (_arrEntries.Length < objEntry.ExpiresIndex) return;
- _intCount--;
- _arrEntries[objEntry.ExpiresIndex]._objEntry.ExpiresBucket = byte.MaxValue;
- _arrEntries[objEntry.ExpiresIndex]._objEntry.ExpiresIndex = int.MaxValue;
- _arrEntries[objEntry.ExpiresIndex]._objEntry = null;
- _intNext = _arrEntries[objEntry.ExpiresIndex]._intNext;
- }
- }
- /// <summary>
- /// Updates a cache entry in the expires bucket, this is called during a hit of an item if the
- /// cache item has a sliding expiration. The function is responsible for updating the cache
- /// entry.
- /// </summary>
- /// <param name="objEntry">Cache entry to update.</param>
- /// <param name="ticksExpires">New expiration value for the cache entry.</param>
- public void Update(CacheEntry objEntry, long ticksExpires)
- {
- lock(this)
- {
- // Check if this is our bucket
- if (objEntry.ExpiresIndex != _byteID) return;
- if (objEntry.ExpiresIndex == System.Int32.MaxValue) return;
- if (_arrEntries.Length < objEntry.ExpiresIndex) return;
- _arrEntries[objEntry.ExpiresIndex]._ticksExpires = ticksExpires;
- _arrEntries[objEntry.ExpiresIndex]._objEntry.Expires = ticksExpires;
- }
- }
- /// <summary>
- /// Flushes all cache entries that has expired and removes them from the cache manager.
- /// </summary>
- public void FlushExpiredItems()
- {
- ExpiresEntry objEntry;
- CacheEntry [] arrCacheEntries;
-
- int intCachePos;
- int intPos;
- long ticksNow;
-
- ticksNow = System.DateTime.Now.Ticks;
- intCachePos = 0;
- // Lookup all items that needs to be removed, this is done in a two part
- // operation to minimize the locking time.
- lock (this)
- {
- arrCacheEntries = new CacheEntry[_intSize];
- intPos = 0;
- do
- {
- objEntry = _arrEntries[intPos];
- if (objEntry._objEntry != null)
- {
- if (objEntry._ticksExpires < ticksNow)
- {
- arrCacheEntries[intCachePos++] = objEntry._objEntry;
- objEntry._objEntry.ExpiresBucket = byte.MaxValue;
- objEntry._objEntry.ExpiresIndex = int.MaxValue;
- objEntry._objEntry = null;
- _intNext = objEntry._intNext;
- }
- }
-
- intPos++;
- } while (intPos < _intSize);
- }
- // If we have any entries to remove, go ahead and call the cache manager remove.
- if (intCachePos > 0)
- {
- intPos = 0;
- do
- {
- _objManager.Remove(arrCacheEntries[intPos].Key, CacheItemRemovedReason.Expired);
- intPos++;
- } while (intPos < intCachePos);
- }
- }
- /// <summary>
- /// Returns the current size of the expires bucket.
- /// </summary>
- public int Size
- {
- get
- {
- return _arrEntries.Length;
- }
- }
- /// <summary>
- /// Returns number of items in the bucket.
- /// </summary>
- public int Count
- {
- get
- {
- return _intCount;
- }
- }
- }
- }
|