2
0

CacheEntry.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //
  2. // System.Web.Caching
  3. //
  4. // Author:
  5. // Patrik Torstensson
  6. // Daniel Cazzulino ([email protected])
  7. //
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Threading;
  30. namespace System.Web.Caching {
  31. internal class CacheEntry {
  32. enum Flags {
  33. Removed = 1,
  34. Public = 2
  35. }
  36. internal static readonly byte NoBucketHash = byte.MaxValue;
  37. internal static readonly int NoIndexInBucket = int.MaxValue;
  38. CacheItemPriority _enumPriority;
  39. long _longHits;
  40. byte _byteExpiresBucket;
  41. int _intExpiresIndex;
  42. long _ticksExpires;
  43. long _ticksSlidingExpiration;
  44. string _strKey;
  45. object _objItem;
  46. long _longMinHits;
  47. Flags _enumFlags;
  48. CacheDependency _objDependency;
  49. Cache _objCache;
  50. ReaderWriterLock _lock = new ReaderWriterLock();
  51. internal event CacheItemRemovedCallback _onRemoved;
  52. internal CacheEntry (Cache objManager, string strKey, object objItem,CacheDependency objDependency,
  53. CacheItemRemovedCallback eventRemove, DateTime dtExpires, TimeSpan tsSpan,
  54. long longMinHits, bool boolPublic, CacheItemPriority enumPriority )
  55. {
  56. if (boolPublic)
  57. _enumFlags |= Flags.Public;
  58. _strKey = strKey;
  59. _objItem = objItem;
  60. _objCache = objManager;
  61. _onRemoved += eventRemove;
  62. _enumPriority = enumPriority;
  63. _ticksExpires = dtExpires.ToUniversalTime ().Ticks;
  64. _ticksSlidingExpiration = tsSpan.Ticks;
  65. // If we have a sliding expiration it overrides the absolute expiration (MS behavior)
  66. // This is because sliding expiration causes the absolute expiration to be
  67. // moved after each period, and the absolute expiration is the value used
  68. // for all expiration calculations.
  69. if (tsSpan.Ticks != Cache.NoSlidingExpiration.Ticks)
  70. _ticksExpires = DateTime.UtcNow.AddTicks (_ticksSlidingExpiration).Ticks;
  71. _objDependency = objDependency;
  72. if (_objDependency != null)
  73. // Add the entry to the cache dependency handler (we support multiple entries per handler)
  74. _objDependency.Changed += new CacheDependencyChangedHandler (OnChanged);
  75. _longMinHits = longMinHits;
  76. }
  77. internal void OnChanged (object sender, CacheDependencyChangedArgs objDependency)
  78. {
  79. _objCache.Remove (_strKey, CacheItemRemovedReason.DependencyChanged);
  80. }
  81. internal void Close (CacheItemRemovedReason enumReason)
  82. {
  83. Delegate [] removedEvents = null;
  84. _lock.AcquireWriterLock(-1);
  85. try {
  86. // Check if the item already is removed
  87. if ((_enumFlags & Flags.Removed) != 0)
  88. return;
  89. _enumFlags |= Flags.Removed;
  90. if (_onRemoved != null)
  91. removedEvents = _onRemoved.GetInvocationList ();
  92. } finally {
  93. _lock.ReleaseWriterLock();
  94. }
  95. if (removedEvents != null) {
  96. // Call the delegate to tell that we are now removing the entry
  97. foreach (Delegate del in removedEvents) {
  98. CacheItemRemovedCallback removed = (CacheItemRemovedCallback) del;
  99. try {
  100. removed (_strKey, _objItem, enumReason);
  101. } catch (Exception obj) {
  102. if (IsPublic)
  103. HttpApplicationFactory.SignalError (obj);
  104. }
  105. }
  106. }
  107. _lock.AcquireWriterLock(-1);
  108. try {
  109. // If we have a dependency, remove the entry
  110. if (_objDependency != null)
  111. _objDependency.Changed -= new CacheDependencyChangedHandler (OnChanged);
  112. } finally {
  113. _lock.ReleaseWriterLock();
  114. }
  115. }
  116. internal bool HasUsage {
  117. get {
  118. if (_longMinHits == System.Int64.MaxValue)
  119. return false;
  120. return true;
  121. }
  122. }
  123. internal bool HasAbsoluteExpiration {
  124. get {
  125. if (_ticksExpires == Cache.NoAbsoluteExpiration.Ticks)
  126. return false;
  127. return true;
  128. }
  129. }
  130. internal bool HasSlidingExpiration {
  131. get {
  132. if (_ticksSlidingExpiration == Cache.NoSlidingExpiration.Ticks)
  133. return false;
  134. return true;
  135. }
  136. }
  137. internal byte ExpiresBucket {
  138. get { return _byteExpiresBucket; }
  139. set { _byteExpiresBucket = value; }
  140. }
  141. internal int ExpiresIndex {
  142. get { return _intExpiresIndex; }
  143. set { _intExpiresIndex = value; }
  144. }
  145. internal long Expires {
  146. get { return _ticksExpires; }
  147. set { _ticksExpires = value; }
  148. }
  149. internal long SlidingExpiration {
  150. get { return _ticksSlidingExpiration; }
  151. }
  152. internal object Item {
  153. get { return _objItem; }
  154. }
  155. internal string Key {
  156. get { return _strKey; }
  157. }
  158. internal long Hits {
  159. get { return _longHits; }
  160. }
  161. internal long MinimumHits {
  162. get { return _longMinHits; }
  163. }
  164. internal CacheItemPriority Priority {
  165. get { return _enumPriority; }
  166. }
  167. internal bool IsPublic {
  168. get { return (_enumFlags & Flags.Public) != 0; }
  169. }
  170. internal void Hit ()
  171. {
  172. Interlocked.Increment (ref _longHits);
  173. }
  174. }
  175. }