| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- //
- // System.Web.Caching
- //
- // Author:
- // Patrik Torstensson ([email protected])
- // Changes:
- // Daniel Cazzulino [DHC] ([email protected])
- //
- // (C) Copyright Patrik Torstensson, 2001
- //
- namespace System.Web.Caching
- {
- /// <summary>
- /// Class responsible for handling time based flushing of entries in the cache. The class creates
- /// and manages 60 buckets each holding every item that expires that minute. The bucket calculated
- /// for an entry is one minute more than the timeout just to make sure that the item end up in the
- /// bucket where it should be flushed.
- /// </summary>
- internal class CacheExpires : System.IDisposable
- {
- static int _intFlush;
- /// <summary>
- /// 1 bucket == 1 minute == 10M ticks (1 second) * 60
- /// </summary>
- static long _ticksPerBucket = 600000000;
- /// <summary>
- /// 1 cycle == 1 hour
- /// </summary>
- static long _ticksPerCycle = _ticksPerBucket * 60;
- private ExpiresBucket[] _arrBuckets;
- private System.Threading.Timer _objTimer;
- private Cache _objManager;
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="objManager">The cache manager, used when flushing items in a bucket.</param>
- internal CacheExpires(Cache objManager)
- {
- _objManager = objManager;
- Initialize();
- }
- /// <summary>
- /// Initializes the class.
- /// </summary>
- private void Initialize()
- {
- // Create one bucket per minute
- _arrBuckets = new ExpiresBucket[60];
- byte bytePos = 0;
- do
- {
- _arrBuckets[bytePos] = new ExpiresBucket(bytePos, _objManager);
- bytePos++;
- } while (bytePos < 60);
- // GC Bucket controller
- _intFlush = System.DateTime.Now.Minute - 1;
- _objTimer = new System.Threading.Timer(new System.Threading.TimerCallback(GarbageCleanup), null, 10000, 60000);
- }
- /// <summary>
- /// Adds a Cache entry to the correct flush bucket.
- /// </summary>
- /// <param name="objEntry">Cache entry to add.</param>
- internal void Add (CacheEntry objEntry)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
- _arrBuckets[GetHashBucket(objEntry.Expires)].Add(objEntry);
- }
- }
- internal void Remove(CacheEntry objEntry)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
- _arrBuckets[GetHashBucket(objEntry.Expires)].Remove(objEntry);
- }
- }
- internal void Update(CacheEntry objEntry, long ticksExpires)
- {
- lock(this)
- {
- // If the entry doesn't have a expires time we assume that the entry is due to expire now.
- if (objEntry.Expires == 0)
- {
- objEntry.Expires = System.DateTime.Now.Ticks;
- }
- _arrBuckets[GetHashBucket(objEntry.Expires)].Update(objEntry, ticksExpires);
- }
- }
- internal void GarbageCleanup(object State)
- {
- ExpiresBucket objBucket;
- lock(this)
- {
- // Do cleanup of the bucket
- objBucket = _arrBuckets[(++_intFlush) % 60];
- }
- // Flush expired items in the current bucket (defined by _intFlush)
- objBucket.FlushExpiredItems();
- }
- private int GetHashBucket(long ticks)
- {
- // Get bucket to add expire item into, add one minute to the bucket just to make sure that we get it in the bucket gc
- return (int) (((((ticks + 60000) % _ticksPerCycle) / _ticksPerBucket) + 1) % 60);
- }
- /// <summary>
- /// Called by the cache for cleanup.
- /// </summary>
- public void Dispose()
- {
- lock(this)
- {
- // Cleanup the internal timer
- if (_objTimer != null)
- {
- _objTimer.Dispose();
- _objTimer = null;
- }
- }
- }
- }
- }
|