6 // Daniel Cazzulino (dcazzulino@users.sf.net)
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System.Threading;
33 namespace System.Web.Caching {
34 internal class CacheEntry {
40 internal static readonly byte NoBucketHash = byte.MaxValue;
41 internal static readonly int NoIndexInBucket = int.MaxValue;
43 CacheItemPriority _enumPriority;
45 byte _byteExpiresBucket;
48 long _ticksSlidingExpiration;
53 CacheDependency _objDependency;
55 ReaderWriterLock _lock = new ReaderWriterLock();
57 internal event CacheItemRemovedCallback _onRemoved;
59 internal CacheEntry (Cache objManager, string strKey, object objItem,CacheDependency objDependency,
60 CacheItemRemovedCallback eventRemove, DateTime dtExpires, TimeSpan tsSpan,
61 long longMinHits, bool boolPublic, CacheItemPriority enumPriority )
64 _enumFlags |= Flags.Public;
68 _objCache = objManager;
69 _onRemoved += eventRemove;
70 _enumPriority = enumPriority;
71 _ticksExpires = dtExpires.ToUniversalTime ().Ticks;
72 _ticksSlidingExpiration = tsSpan.Ticks;
74 // If we have a sliding expiration it overrides the absolute expiration (MS behavior)
75 // This is because sliding expiration causes the absolute expiration to be
76 // moved after each period, and the absolute expiration is the value used
77 // for all expiration calculations.
78 if (tsSpan.Ticks != Cache.NoSlidingExpiration.Ticks)
79 _ticksExpires = DateTime.UtcNow.AddTicks (_ticksSlidingExpiration).Ticks;
81 _objDependency = objDependency;
82 if (_objDependency != null)
83 // Add the entry to the cache dependency handler (we support multiple entries per handler)
84 _objDependency.Changed += new CacheDependencyChangedHandler (OnChanged);
86 _longMinHits = longMinHits;
90 internal void OnChanged (object sender, CacheDependencyChangedArgs objDependency)
92 _objCache.Remove (_strKey, CacheItemRemovedReason.DependencyChanged);
95 internal void Close (CacheItemRemovedReason enumReason)
97 Delegate [] removedEvents = null;
99 _lock.AcquireWriterLock(-1);
101 // Check if the item already is removed
102 if ((_enumFlags & Flags.Removed) != 0)
105 _enumFlags |= Flags.Removed;
107 if (_onRemoved != null)
108 removedEvents = _onRemoved.GetInvocationList ();
110 _lock.ReleaseWriterLock();
113 if (removedEvents != null) {
114 // Call the delegate to tell that we are now removing the entry
115 foreach (Delegate del in removedEvents) {
116 CacheItemRemovedCallback removed = (CacheItemRemovedCallback) del;
118 removed (_strKey, _objItem, enumReason);
119 } catch (Exception obj) {
121 HttpApplicationFactory.SignalError (obj);
126 _lock.AcquireWriterLock(-1);
128 // If we have a dependency, remove the entry
129 if (_objDependency != null)
130 _objDependency.Changed -= new CacheDependencyChangedHandler (OnChanged);
132 _lock.ReleaseWriterLock();
136 internal bool HasUsage {
138 if (_longMinHits == System.Int64.MaxValue)
145 internal bool HasAbsoluteExpiration {
147 if (_ticksExpires == Cache.NoAbsoluteExpiration.Ticks)
154 internal bool HasSlidingExpiration {
156 if (_ticksSlidingExpiration == Cache.NoSlidingExpiration.Ticks)
163 internal byte ExpiresBucket {
164 get { return _byteExpiresBucket; }
165 set { _byteExpiresBucket = value; }
168 internal int ExpiresIndex {
169 get { return _intExpiresIndex; }
170 set { _intExpiresIndex = value; }
173 internal long Expires {
174 get { return _ticksExpires; }
175 set { _ticksExpires = value; }
178 internal long SlidingExpiration {
179 get { return _ticksSlidingExpiration; }
182 internal object Item {
183 get { return _objItem; }
186 internal string Key {
187 get { return _strKey; }
191 get { return _longHits; }
194 internal long MinimumHits {
195 get { return _longMinHits; }
198 internal CacheItemPriority Priority {
199 get { return _enumPriority; }
202 internal bool IsPublic {
203 get { return (_enumFlags & Flags.Public) != 0; }
208 Interlocked.Increment (ref _longHits);