private void RemoveCacheEntryNoLock(MemoryCacheEntry cacheEntry) { ExpiresEntryRef entryRef = cacheEntry.ExpiresEntryRef; if (cacheEntry.ExpiresBucket != _bucket || entryRef.IsInvalid) { return; } ExpiresEntry[] entries = (_pages[(entryRef.PageIndex)]._entries); int entryIndex = entryRef.Index; RemoveCount(entries[entryIndex]._utcExpires); cacheEntry.ExpiresBucket = 0xff; cacheEntry.ExpiresEntryRef = ExpiresEntryRef.INVALID; entries[entryIndex]._cacheEntry = null; AddExpiresEntryToFreeList(entryRef); if (_cEntriesInUse == 0) { ResetCounts(DateTime.UtcNow); } Reduce(); Debug.WriteLine("CacheExpiresRemove", "Removed item=" + cacheEntry.Key + ",_bucket=" + _bucket + ",ref=" + entryRef + ",now=" + DateTime.Now.ToString("o", CultureInfo.InvariantCulture) + ",expires=" + cacheEntry.UtcAbsExp.ToLocalTime()); }
public void Dispose() { if (Interlocked.Exchange(ref this._disposed, 1) == 0) { this._expires.EnableExpirationTimer(false); ArrayList list = new ArrayList(this._entries.Count); lock (this._entriesLock) { foreach (DictionaryEntry entry in this._entries) { MemoryCacheEntry entry2 = entry.Value as MemoryCacheEntry; list.Add(entry2); } foreach (MemoryCacheEntry entry3 in list) { MemoryCacheKey key = entry3; entry3.State = EntryState.RemovingFromCache; this._entries.Remove(key); } } foreach (MemoryCacheEntry entry4 in list) { this.RemoveFromCache(entry4, CacheEntryRemovedReason.CacheSpecificEviction, false); } this._insertBlock.Close(); } }
internal MemoryCacheEntry Remove(MemoryCacheKey key, MemoryCacheEntry entryToRemove, CacheEntryRemovedReason reason) { MemoryCacheEntry objA = null; lock (this._entriesLock) { if (this._disposed == 0) { objA = this._entries[key] as MemoryCacheEntry; if ((entryToRemove == null) || object.ReferenceEquals(objA, entryToRemove)) { if (objA != null) { objA.State = EntryState.RemovingFromCache; } this._entries.Remove(key); } else { objA = null; } } } this.RemoveFromCache(objA, reason, false); return(objA); }
internal void UtcUpdate(MemoryCacheEntry cacheEntry, DateTime utcNewExpires) { int oldBucket = cacheEntry.ExpiresBucket; int newBucket = UtcCalcExpiresBucket(utcNewExpires); if (oldBucket != newBucket) { Dbg.Trace("CacheExpiresUpdate", "Updating item " + cacheEntry.Key + " from bucket " + oldBucket + " to new bucket " + newBucket); if (oldBucket != 0xff) { _buckets[oldBucket].RemoveCacheEntry(cacheEntry); cacheEntry.UtcAbsExp = utcNewExpires; _buckets[newBucket].AddCacheEntry(cacheEntry); } } else { if (oldBucket != 0xff) { _buckets[oldBucket].UtcUpdateCacheEntry(cacheEntry, utcNewExpires); } } }
// 'updatePerfCounters' defaults to true since this method is called by all Get() operations // to update both the performance counters and the sliding expiration. Callers that perform // nested sliding expiration updates (like a MemoryCacheEntry touching its update sentinel) // can pass false to prevent these from unintentionally showing up in the perf counters. internal void UpdateExpAndUsage(MemoryCacheEntry entry, bool updatePerfCounters = true) { if (entry != null) { if (entry.InUsage() || entry.SlidingExp > TimeSpan.Zero) { DateTime utcNow = DateTime.UtcNow; entry.UpdateSlidingExp(utcNow, _expires); entry.UpdateUsage(utcNow, _usage); } // DevDiv #67021: If this entry has an update sentinel, the sliding expiration is actually associated // with that sentinel, not with this entry. We need to update the sentinel's sliding expiration to // keep the sentinel from expiring, which in turn would force a removal of this entry from the cache. entry.UpdateSlidingExpForUpdateSentinel(); if (updatePerfCounters && _perfCounters != null) { _perfCounters.Increment(PerfCounterName.Hits); _perfCounters.Increment(PerfCounterName.HitRatio); _perfCounters.Increment(PerfCounterName.HitRatioBase); } } else { if (updatePerfCounters && _perfCounters != null) { _perfCounters.Increment(PerfCounterName.Misses); _perfCounters.Increment(PerfCounterName.HitRatioBase); } } }
internal void UtcUpdateCacheEntry(MemoryCacheEntry cacheEntry, DateTime utcExpires) { lock (this) { ExpiresEntryRef entryRef = cacheEntry.ExpiresEntryRef; if (cacheEntry.ExpiresBucket != _bucket || entryRef.IsInvalid) { return; } ExpiresEntry[] entries = (_pages[(entryRef.PageIndex)]._entries); int entryIndex = entryRef.Index; Dbg.Assert(cacheEntry == entries[entryIndex]._cacheEntry); RemoveCount(entries[entryIndex]._utcExpires); AddCount(utcExpires); entries[entryIndex]._utcExpires = utcExpires; cacheEntry.UtcAbsExp = utcExpires; Dbg.Validate("CacheValidateExpires", this); Dbg.Trace("CacheExpiresUpdate", "Updated item " + cacheEntry.Key + " in bucket " + _bucket); } }
internal MemoryCacheEntry RemoveEntry(string key, MemoryCacheEntry entry, CacheEntryRemovedReason reason) { MemoryCacheKey cacheKey = new MemoryCacheKey(key); MemoryCacheStore store = GetStore(cacheKey); return(store.Remove(cacheKey, entry, reason)); }
private void RemoveFromCache(MemoryCacheEntry entry, CacheEntryRemovedReason reason, bool delayRelease = false) { // release outside of lock if (entry != null) { if (entry.InExpires()) { _expires.Remove(entry); } if (entry.InUsage()) { _usage.Remove(entry); } Dbg.Assert(entry.State == EntryState.RemovingFromCache, "entry.State = EntryState.RemovingFromCache"); entry.State = EntryState.RemovedFromCache; if (!delayRelease) { entry.Release(_cache, reason); } if (_perfCounters != null) { _perfCounters.Decrement(PerfCounterName.Entries); _perfCounters.Increment(PerfCounterName.Turnover); } } }
internal void Add(MemoryCacheEntry cacheEntry) { byte bucket = cacheEntry.UsageBucket; Debug.Assert(bucket != 0xff, "bucket != 0xff"); _buckets[bucket].AddCacheEntry(cacheEntry); }
public MemoryCacheEntry Dequeue() { MemoryCacheEntry ret = null; MemoryCacheEntry[] heap; bool locked = false; int index; try { queueLock.EnterWriteLock(); locked = true; heap = GetHeapWithShrink(); if (heap == null || heapCount == 0) { return(null); } ret = heap [0]; index = checked (--heapCount); heap [0] = heap [index]; heap [index] = null; if (heapCount > 0) { BubbleDown(heap); } return(ret); } finally { if (locked) { queueLock.ExitWriteLock(); } } }
internal void AddCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { if (((byte)(cacheEntry.State & (EntryState.AddedToCache | EntryState.AddingToCache))) != 0) { ExpiresEntryRef expiresEntryRef = cacheEntry.ExpiresEntryRef; if ((cacheEntry.ExpiresBucket == 0xff) && expiresEntryRef.IsInvalid) { if (this._freeEntryList._head == -1) { this.Expand(); } ExpiresEntryRef freeExpiresEntry = this.GetFreeExpiresEntry(); cacheEntry.ExpiresBucket = this._bucket; cacheEntry.ExpiresEntryRef = freeExpiresEntry; ExpiresEntry[] entryArray = this._pages[freeExpiresEntry.PageIndex]._entries; int index = freeExpiresEntry.Index; entryArray[index]._cacheEntry = cacheEntry; entryArray[index]._utcExpires = cacheEntry.UtcAbsExp; this.AddCount(cacheEntry.UtcAbsExp); this._cEntriesInUse++; if (((byte)(cacheEntry.State & (EntryState.AddedToCache | EntryState.AddingToCache))) == 0) { this.RemoveCacheEntryNoLock(cacheEntry); } } } } }
internal void RemoveCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { UsageEntryRef entryRef = cacheEntry.UsageEntryRef; if (entryRef.IsInvalid) { return; } UsageEntry[] entries = (_pages[(entryRef.PageIndex)]._entries); int entryIndex = entryRef.Ref1Index; cacheEntry.UsageEntryRef = UsageEntryRef.INVALID; entries[entryIndex]._cacheEntry = null; RemoveEntryFromLastRefList(entryRef); AddUsageEntryToFreeList(entryRef); Reduce(); Dbg.Trace("CacheUsageRemove", "Removed item=" + cacheEntry.Key + ",_bucket=" + _bucket + ",ref=" + entryRef); } }
internal MemoryCacheEntry Remove(MemoryCacheKey key, MemoryCacheEntry entryToRemove, CacheEntryRemovedReason reason) { MemoryCacheEntry entry = null; lock (_entriesLock) { if (_disposed == 0) { // get current entry entry = _entries[key] as MemoryCacheEntry; // remove if it matches the entry to be removed (but always remove if entryToRemove is null) if (entryToRemove == null || Object.ReferenceEquals(entry, entryToRemove)) { // Dev10 865887: MemoryCache.Remove("\ue637\ud22a\u3e17") causes NullReferenceEx if (entry != null) { entry.State = EntryState.RemovingFromCache; _entries.Remove(key); } } else { entry = null; } } } // release outside of lock RemoveFromCache(entry, reason); return(entry); }
bool ExpireIfNeeded(string key, MemoryCacheEntry entry, bool needsLock = true, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Expired) { bool locked = false; try { if (entry.IsExpired) { if (needsLock) { cache_lock.EnterWriteLock(); locked = true; } cache.Remove(key); perfCounters.Decrement(MemoryCachePerformanceCounters.CACHE_ENTRIES); entry.Removed(owner, CacheEntryRemovedReason.Expired); return(true); } } finally { if (locked) { cache_lock.ExitWriteLock(); } } return(false); }
// private members private void AddToCache(MemoryCacheEntry entry) { // add outside of lock if (entry != null) { if (entry.HasExpiration()) { _expires.Add(entry); } if (entry.HasUsage() && (!entry.HasExpiration() || entry.UtcAbsExp - DateTime.UtcNow >= CacheUsage.MIN_LIFETIME_FOR_USAGE)) { _usage.Add(entry); } entry.State = EntryState.AddedToCache; entry.CallNotifyOnChanged(); if (_perfCounters != null) { _perfCounters.Increment(PerfCounterName.Entries); _perfCounters.Increment(PerfCounterName.Turnover); } } }
internal void RemoveCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { RemoveCacheEntryNoLock(cacheEntry); } }
public void Enqueue(MemoryCacheEntry item) { if (item == null) { return; } bool locked = false; MemoryCacheEntry[] heap; try { queueLock.EnterWriteLock(); locked = true; heap = GetHeapWithGrow(); heap [heapCount++] = item; BubbleUp(heap); } finally { if (locked) { queueLock.ExitWriteLock(); } } }
// Associates this entry with an update sentinel. If this entry has a sliding expiration, we need to // touch the sentinel so that it doesn't expire. internal void ConfigureUpdateSentinel(MemoryCacheStore sentinelStore, MemoryCacheEntry sentinelEntry) { lock (this) { _fields ??= new SeldomUsedFields(); _fields._updateSentinel = Tuple.Create(sentinelStore, sentinelEntry); } }
internal void Update(MemoryCacheEntry cacheEntry) { byte usageBucket = cacheEntry.UsageBucket; if (usageBucket != 0xff) { this._buckets[usageBucket].UpdateCacheEntry(cacheEntry); } }
internal void Update(MemoryCacheEntry cacheEntry) { byte usageBucket = cacheEntry.UsageBucket; if (usageBucket != 0xff) { this._buckets[usageBucket].UpdateCacheEntry(cacheEntry); } }
internal void Remove(MemoryCacheEntry cacheEntry) { byte expiresBucket = cacheEntry.ExpiresBucket; if (expiresBucket != 0xff) { this._buckets[expiresBucket].RemoveCacheEntry(cacheEntry); } }
internal void Remove(MemoryCacheEntry cacheEntry) { byte bucket = cacheEntry.ExpiresBucket; if (bucket != 0xff) { _buckets[bucket].RemoveCacheEntry(cacheEntry); } }
internal void Update(MemoryCacheEntry cacheEntry) { byte bucket = cacheEntry.UsageBucket; if (bucket != 0xff) { _buckets[bucket].UpdateCacheEntry(cacheEntry); } }
private void InitDisposableMembers(MemoryCache cache) { bool flag = true; try { bool hasChanged = false; string str = null; this._dependencies = new List <MemoryCacheEntry>(this._keys.Count); if (this._keys.Count == 1) { string key = this._keys[0]; MemoryCacheEntry entry = cache.GetEntry(key); DateTime utcCreated = DATETIME_MINVALUE_UTC; this.StartMonitoring(cache, entry, ref hasChanged, ref utcCreated); str = key + utcCreated.Ticks.ToString("X", CultureInfo.InvariantCulture); this._lastModified = utcCreated; } else { int capacity = 0; foreach (string str3 in this._keys) { capacity += str3.Length + 0x10; } StringBuilder builder = new StringBuilder(capacity); foreach (string str4 in this._keys) { MemoryCacheEntry entry2 = cache.GetEntry(str4); DateTime time2 = DATETIME_MINVALUE_UTC; this.StartMonitoring(cache, entry2, ref hasChanged, ref time2); builder.Append(str4); builder.Append(time2.Ticks.ToString("X", CultureInfo.InvariantCulture)); if (time2 > this._lastModified) { this._lastModified = time2; } } str = builder.ToString(); } this._uniqueId = str; if (hasChanged) { base.OnChanged(null); } flag = false; } finally { base.InitializationComplete(); if (flag) { base.Dispose(); } } }
} // hide default .ctor private void InitDisposableMembers(MemoryCache cache) { bool dispose = true; try { bool hasChanged = false; string uniqueId = null; _dependencies = new List <MemoryCacheEntry>(_keys.Count); if (_keys.Count == 1) { string k = _keys[0]; MemoryCacheEntry entry = cache.GetEntry(k); DateTime utcCreated = s_DATETIME_MINVALUE_UTC; StartMonitoring(cache, entry, ref hasChanged, ref utcCreated); uniqueId = k + utcCreated.Ticks.ToString("X", CultureInfo.InvariantCulture); _lastModified = utcCreated; } else { int capacity = 0; foreach (string key in _keys) { capacity += key.Length + MAX_CHAR_COUNT_OF_LONG_CONVERTED_TO_HEXADECIMAL_STRING; } StringBuilder sb = new StringBuilder(capacity); foreach (string key in _keys) { MemoryCacheEntry entry = cache.GetEntry(key); DateTime utcCreated = s_DATETIME_MINVALUE_UTC; StartMonitoring(cache, entry, ref hasChanged, ref utcCreated); sb.Append(key); sb.Append(utcCreated.Ticks.ToString("X", CultureInfo.InvariantCulture)); if (utcCreated > _lastModified) { _lastModified = utcCreated; } } uniqueId = sb.ToString(); } _uniqueId = uniqueId; if (hasChanged) { OnChanged(null); } dispose = false; } finally { InitializationComplete(); if (dispose) { Dispose(); } } }
internal void Add(MemoryCacheEntry cacheEntry) { DateTime utcNow = DateTime.UtcNow; if (utcNow > cacheEntry.UtcAbsExp) { cacheEntry.UtcAbsExp = utcNow; } int index = this.UtcCalcExpiresBucket(cacheEntry.UtcAbsExp); this._buckets[index].AddCacheEntry(cacheEntry); }
long DoRemoveExpiredItems(bool needLock) { long count = 0; bool locked = false; try { if (needLock) { cache_lock.EnterWriteLock(); locked = true; } if (timedItems == null) { return(0); } long now = DateTime.Now.Ticks; MemoryCacheEntry entry = timedItems.Peek(); while (entry != null) { if (entry.Disabled) { timedItems.Dequeue(); entry = timedItems.Peek(); continue; } if (entry.ExpiresAt > now) { break; } timedItems.Dequeue(); count++; DoRemoveEntry(entry, true, entry.Key, CacheEntryRemovedReason.Expired); entry = timedItems.Peek(); } if (entry == null) { timedItems = null; expirationTimer.Dispose(); expirationTimer = null; } return(count); } finally { if (locked) { cache_lock.ExitWriteLock(); } } }
internal void Remove(MemoryCacheEntry entry) { if (entry == null) { return; } string key = entry.Key; FindContainer(key).Remove(key); }
internal void Add(MemoryCacheEntry cacheEntry) { DateTime utcNow = DateTime.UtcNow; if (utcNow > cacheEntry.UtcAbsExp) { cacheEntry.UtcAbsExp = utcNow; } int index = this.UtcCalcExpiresBucket(cacheEntry.UtcAbsExp); this._buckets[index].AddCacheEntry(cacheEntry); }
internal MemoryCacheEntry Get(MemoryCacheKey key) { MemoryCacheEntry entryToRemove = this._entries[key] as MemoryCacheEntry; if ((entryToRemove != null) && (entryToRemove.UtcAbsExp <= DateTime.UtcNow)) { this.Remove(key, entryToRemove, CacheEntryRemovedReason.Expired); entryToRemove = null; } this.UpdateExpAndUsage(entryToRemove); return(entryToRemove); }
public object AddOrGetExisting(string key, object value, CacheItemPolicy policy) { bool readLocked = false, writeLocked = false; try { cache_lock.EnterUpgradeableReadLock(); readLocked = true; MemoryCacheEntry entry; if (cache.TryGetValue(key, out entry) && entry != null) { perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_HITS); if (entry.IsSliding) { entry.UpdateSlidingExpiry(); } return(entry.Value); } perfCounters.Increment(MemoryCachePerformanceCounters.CACHE_MISSES); cache_lock.EnterWriteLock(); writeLocked = true; if (policy == null) { entry = new MemoryCacheEntry(owner, key, value); } else { entry = new MemoryCacheEntry(owner, key, value, policy.AbsoluteExpiration, policy.ChangeMonitors, policy.Priority, policy.RemovedCallback, policy.SlidingExpiration, policy.UpdateCallback); } AddToCache(key, entry); return(null); } finally { if (writeLocked) { cache_lock.ExitWriteLock(); } if (readLocked) { cache_lock.ExitUpgradeableReadLock(); } } }
internal void Add(MemoryCacheEntry cacheEntry) { DateTime utcNow = DateTime.UtcNow; if (utcNow > cacheEntry.UtcAbsExp) { cacheEntry.UtcAbsExp = utcNow; } int bucket = UtcCalcExpiresBucket(cacheEntry.UtcAbsExp); _buckets[bucket].AddCacheEntry(cacheEntry); }
public void Remove (MemoryCacheEntry entry) { if (entry == null) return; int hash = entry.GetHashCode (); LinkedListNode <MemoryCacheEntry> node; if (index.TryGetValue (hash, out node)) { lru.Remove (node); index.Remove (hash); } }
private void StartMonitoring(MemoryCache cache, MemoryCacheEntry entry, ref bool hasChanged, ref DateTime utcCreated) { if (entry != null) { // pass reference to self so the dependency can notify us when it changes entry.AddDependent(cache, this); // add dependency to collection so we can dispose it later _dependencies.Add(entry); // has the entry already changed? if (entry.State != EntryState.AddedToCache) { hasChanged = true; } utcCreated = entry.UtcCreated; } else { // the entry does not exist--set hasChanged to true so the user is notified hasChanged = true; } }
public void Update (MemoryCacheEntry entry) { if (entry == null) return; int hash = entry.GetHashCode (); LinkedListNode <MemoryCacheEntry> node; if (!index.TryGetValue (hash, out node)) { node = new LinkedListNode <MemoryCacheEntry> (entry); index.Add (hash, node); } else { lru.Remove (node); node.Value = entry; } lru.AddLast (node); }
// private members private void AddToCache(MemoryCacheEntry entry) { // add outside of lock if (entry != null) { if (entry.HasExpiration()) { _expires.Add(entry); } if (entry.HasUsage() && (!entry.HasExpiration() || entry.UtcAbsExp - DateTime.UtcNow >= CacheUsage.MIN_LIFETIME_FOR_USAGE)) { _usage.Add(entry); } entry.State = EntryState.AddedToCache; entry.CallNotifyOnChanged(); if (_perfCounters != null) { _perfCounters.Increment(PerfCounterName.Entries); _perfCounters.Increment(PerfCounterName.Turnover); } } }
internal MemoryCacheEntry AddOrGetExisting(MemoryCacheKey key, MemoryCacheEntry entry) { if (this._useInsertBlock && entry.HasUsage()) { this.WaitInsertBlock(); } MemoryCacheEntry entry2 = null; MemoryCacheEntry entry3 = null; bool flag = false; lock (this._entriesLock) { if (this._disposed == 0) { entry2 = this._entries[key] as MemoryCacheEntry; if ((entry2 != null) && (entry.UtcAbsExp <= DateTime.UtcNow)) { entry3 = entry2; entry3.State = EntryState.RemovingFromCache; entry2 = null; } if (entry2 == null) { entry.State = EntryState.AddingToCache; flag = true; this._entries[key] = entry; } } } bool delayRelease = true; this.RemoveFromCache(entry3, CacheEntryRemovedReason.Expired, delayRelease); if (flag) { this.AddToCache(entry); } this.UpdateExpAndUsage(entry2); if (entry3 != null) { entry3.Release(this._cache, CacheEntryRemovedReason.Expired); } return entry2; }
private void RemoveFromCache(MemoryCacheEntry entry, CacheEntryRemovedReason reason, bool delayRelease = false) { // release outside of lock if (entry != null) { if (entry.InExpires()) { _expires.Remove(entry); } if (entry.InUsage()) { _usage.Remove(entry); } Dbg.Assert(entry.State == EntryState.RemovingFromCache, "entry.State = EntryState.RemovingFromCache"); entry.State = EntryState.RemovedFromCache; if (!delayRelease) { entry.Release(_cache, reason); } if (_perfCounters != null) { _perfCounters.Decrement(PerfCounterName.Entries); _perfCounters.Increment(PerfCounterName.Turnover); } } }
bool ExpireIfNeeded (string key, MemoryCacheEntry entry, bool needsLock = true, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Expired) { bool locked = false; try { if (entry.IsExpired) { if (needsLock) { cache_lock.EnterWriteLock (); locked = true; } cache.Remove (key); perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES); entry.Removed (owner, CacheEntryRemovedReason.Expired); return true; } } finally { if (locked) cache_lock.ExitWriteLock (); } return false; }
// NOTE: this method _MUST_ be called with the write lock held void AddToCache (string key, MemoryCacheEntry entry, bool update = false) { if (update) cache [key] = entry; else cache.Add (key, entry); lru.Update (entry); entry.Added (); if (!update) perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_ENTRIES); if (entry.IsExpirable) UpdateExpirable (entry); }
void BubbleDown (MemoryCacheEntry[] heap) { int index = 0; int left = 1; int right = 2; MemoryCacheEntry item = heap [0]; int selected = (right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt) ? 2 : 1; while (selected < heapCount && heap [selected].ExpiresAt < item.ExpiresAt) { heap [index] = heap [selected]; index = selected; left = checked((index << 1) + 1); right = left + 1; selected = right < heapCount && heap [right].ExpiresAt < heap [left].ExpiresAt ? right : left; } heap [index] = item; }
void BubbleUp (MemoryCacheEntry[] heap) { int index, parentIndex; MemoryCacheEntry parent, item; if (heapCount <= 1) return; index = checked(heapCount - 1); parentIndex = checked((index - 1) >> 1); item = heap [index]; while (index > 0) { parent = heap [parentIndex]; if (heap [index].ExpiresAt >= parent.ExpiresAt) break; heap [index] = parent; index = parentIndex; parentIndex = (index - 1) >> 1; } heap [index] = item; }
public void Enqueue (MemoryCacheEntry item) { if (item == null) return; bool locked = false; MemoryCacheEntry[] heap; try { queueLock.EnterWriteLock (); locked = true; heap = GetHeapWithGrow (); heap [checked(heapCount++)] = item; BubbleUp (heap); } finally { if (locked) queueLock.ExitWriteLock (); } }
internal MemoryCacheEntry AddOrGetExisting(MemoryCacheKey key, MemoryCacheEntry entry) { if (_useInsertBlock && entry.HasUsage()) { WaitInsertBlock(); } MemoryCacheEntry existingEntry = null; MemoryCacheEntry toBeReleasedEntry = null; bool added = false; lock (_entriesLock) { if (_disposed == 0) { existingEntry = _entries[key] as MemoryCacheEntry; // has it expired? if (existingEntry != null && existingEntry.UtcAbsExp <= DateTime.UtcNow) { toBeReleasedEntry = existingEntry; toBeReleasedEntry.State = EntryState.RemovingFromCache; existingEntry = null; } // can we add entry to the cache? if (existingEntry == null) { entry.State = EntryState.AddingToCache; added = true; _entries[key] = entry; } } } // release outside of lock RemoveFromCache(toBeReleasedEntry, CacheEntryRemovedReason.Expired, delayRelease:true); if (added) { // add outside of lock AddToCache(entry); } // update outside of lock UpdateExpAndUsage(existingEntry); // Dev10 861163: Call Release after the new entry has been completely added so // that the CacheItemRemovedCallback can take a dependency on the newly inserted item. if (toBeReleasedEntry != null) { toBeReleasedEntry.Release(_cache, CacheEntryRemovedReason.Expired); } return existingEntry; }
internal void UtcUpdate(MemoryCacheEntry cacheEntry, DateTime utcNewExpires) { int expiresBucket = cacheEntry.ExpiresBucket; int index = this.UtcCalcExpiresBucket(utcNewExpires); if (expiresBucket != index) { if (expiresBucket != 0xff) { this._buckets[expiresBucket].RemoveCacheEntry(cacheEntry); cacheEntry.UtcAbsExp = utcNewExpires; this._buckets[index].AddCacheEntry(cacheEntry); } } else if (expiresBucket != 0xff) { this._buckets[expiresBucket].UtcUpdateCacheEntry(cacheEntry, utcNewExpires); } }
// NOTE: this must be called with the write lock held void DoRemoveEntry (MemoryCacheEntry entry, bool updateLRU = true, string key = null, CacheEntryRemovedReason reason = CacheEntryRemovedReason.Removed) { if (key == null) key = entry.Key; cache.Remove (key); if (updateLRU) lru.Remove (entry); perfCounters.Decrement (MemoryCachePerformanceCounters.CACHE_ENTRIES); entry.Removed (owner, reason); }
internal void AddCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { if (this._freeEntryList._head == -1) { this.Expand(); } UsageEntryRef freeUsageEntry = this.GetFreeUsageEntry(); UsageEntryRef ref3 = new UsageEntryRef(freeUsageEntry.PageIndex, -freeUsageEntry.Ref1Index); cacheEntry.UsageEntryRef = freeUsageEntry; UsageEntry[] entryArray = this._pages[freeUsageEntry.PageIndex]._entries; int index = freeUsageEntry.Ref1Index; entryArray[index]._cacheEntry = cacheEntry; entryArray[index]._utcDate = DateTime.UtcNow; entryArray[index]._ref1._prev = UsageEntryRef.INVALID; entryArray[index]._ref2._next = this._addRef2Head; if (this._lastRefHead.IsInvalid) { entryArray[index]._ref1._next = ref3; entryArray[index]._ref2._prev = freeUsageEntry; this._lastRefTail = ref3; } else { UsageEntryRef iNVALID; UsageEntryRef ref5; entryArray[index]._ref1._next = this._lastRefHead; if (this._lastRefHead.IsRef1) { this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = freeUsageEntry; } else if (this._lastRefHead.IsRef2) { this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = freeUsageEntry; } else { this._lastRefTail = freeUsageEntry; } if (this._addRef2Head.IsInvalid) { ref5 = this._lastRefTail; iNVALID = UsageEntryRef.INVALID; } else { ref5 = this._pages[this._addRef2Head.PageIndex]._entries[this._addRef2Head.Ref2Index]._ref2._prev; iNVALID = this._addRef2Head; } entryArray[index]._ref2._prev = ref5; if (ref5.IsRef1) { this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._next = ref3; } else if (ref5.IsRef2) { this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._next = ref3; } else { this._lastRefHead = ref3; } if (iNVALID.IsRef1) { this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref1Index]._ref1._prev = ref3; } else if (iNVALID.IsRef2) { this._pages[iNVALID.PageIndex]._entries[iNVALID.Ref2Index]._ref2._prev = ref3; } else { this._lastRefTail = ref3; } } this._lastRefHead = freeUsageEntry; this._addRef2Head = ref3; this._cEntriesInUse++; } }
internal void UpdateCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { UsageEntryRef usageEntryRef = cacheEntry.UsageEntryRef; if (!usageEntryRef.IsInvalid) { UsageEntry[] entryArray = this._pages[usageEntryRef.PageIndex]._entries; int index = usageEntryRef.Ref1Index; UsageEntryRef ref3 = new UsageEntryRef(usageEntryRef.PageIndex, -usageEntryRef.Ref1Index); UsageEntryRef ref4 = entryArray[index]._ref2._prev; UsageEntryRef ref5 = entryArray[index]._ref2._next; if (ref4.IsRef1) { this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref5; } else if (ref4.IsRef2) { this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref5; } else { this._lastRefHead = ref5; } if (ref5.IsRef1) { this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref4; } else if (ref5.IsRef2) { this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref4; } else { this._lastRefTail = ref4; } if (this._addRef2Head == ref3) { this._addRef2Head = ref5; } entryArray[index]._ref2 = entryArray[index]._ref1; ref4 = entryArray[index]._ref2._prev; ref5 = entryArray[index]._ref2._next; if (ref4.IsRef1) { this._pages[ref4.PageIndex]._entries[ref4.Ref1Index]._ref1._next = ref3; } else if (ref4.IsRef2) { this._pages[ref4.PageIndex]._entries[ref4.Ref2Index]._ref2._next = ref3; } else { this._lastRefHead = ref3; } if (ref5.IsRef1) { this._pages[ref5.PageIndex]._entries[ref5.Ref1Index]._ref1._prev = ref3; } else if (ref5.IsRef2) { this._pages[ref5.PageIndex]._entries[ref5.Ref2Index]._ref2._prev = ref3; } else { this._lastRefTail = ref3; } entryArray[index]._ref1._prev = UsageEntryRef.INVALID; entryArray[index]._ref1._next = this._lastRefHead; if (this._lastRefHead.IsRef1) { this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref1Index]._ref1._prev = usageEntryRef; } else if (this._lastRefHead.IsRef2) { this._pages[this._lastRefHead.PageIndex]._entries[this._lastRefHead.Ref2Index]._ref2._prev = usageEntryRef; } else { this._lastRefTail = usageEntryRef; } this._lastRefHead = usageEntryRef; } } }
internal void RemoveCacheEntry(MemoryCacheEntry cacheEntry) { lock (this) { UsageEntryRef usageEntryRef = cacheEntry.UsageEntryRef; if (!usageEntryRef.IsInvalid) { UsageEntry[] entryArray = this._pages[usageEntryRef.PageIndex]._entries; int index = usageEntryRef.Ref1Index; cacheEntry.UsageEntryRef = UsageEntryRef.INVALID; entryArray[index]._cacheEntry = null; this.RemoveEntryFromLastRefList(usageEntryRef); this.AddUsageEntryToFreeList(usageEntryRef); this.Reduce(); } } }
internal MemoryCacheEntry RemoveEntry(string key, MemoryCacheEntry entry, CacheEntryRemovedReason reason) { MemoryCacheKey cacheKey = new MemoryCacheKey(key); MemoryCacheStore store = GetStore(cacheKey); return store.Remove(cacheKey, entry, reason); }
internal MemoryCacheEntry RemoveEntry(string key, MemoryCacheEntry entry, CacheEntryRemovedReason reason) { MemoryCacheKey key2 = new MemoryCacheKey(key); return this.GetStore(key2).Remove(key2, entry, reason); }
// DevDiv Bugs 162763: // Add a an event that fires *before* an item is evicted from the ASP.NET Cache internal void Set(string key, object value, Collection<ChangeMonitor> changeMonitors, DateTimeOffset absoluteExpiration, TimeSpan slidingExpiration, CacheEntryUpdateCallback onUpdateCallback) { if (key == null) { throw new ArgumentNullException("key"); } if (changeMonitors == null && absoluteExpiration == ObjectCache.InfiniteAbsoluteExpiration && slidingExpiration == ObjectCache.NoSlidingExpiration) { throw new ArgumentException(R.Invalid_argument_combination); } if (onUpdateCallback == null) { throw new ArgumentNullException("onUpdateCallback"); } if (IsDisposed) { if (changeMonitors != null) { foreach (ChangeMonitor monitor in changeMonitors) { if (monitor != null) { monitor.Dispose(); } } } return; } // Insert updatable cache entry MemoryCacheKey cacheKey = new MemoryCacheKey(key); MemoryCacheStore store = GetStore(cacheKey); MemoryCacheEntry cacheEntry = new MemoryCacheEntry(key, value, ObjectCache.InfiniteAbsoluteExpiration, ObjectCache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null, null, this); store.Set(cacheKey, cacheEntry); // Ensure the sentinel depends on its updatable entry string[] cacheKeys = { key }; ChangeMonitor expensiveObjectDep = CreateCacheEntryChangeMonitor(cacheKeys); if (changeMonitors == null) { changeMonitors = new Collection<ChangeMonitor>(); } changeMonitors.Add(expensiveObjectDep); // Insert sentinel entry for the updatable cache entry MemoryCacheKey sentinelCacheKey = new MemoryCacheKey("OnUpdateSentinel" + key); MemoryCacheStore sentinelStore = GetStore(sentinelCacheKey); MemoryCacheEntry sentinelCacheEntry = new MemoryCacheEntry(sentinelCacheKey.Key, new SentinelEntry(key, expensiveObjectDep, onUpdateCallback), absoluteExpiration, slidingExpiration, CacheItemPriority.NotRemovable, changeMonitors, s_sentinelRemovedCallback, this); sentinelStore.Set(sentinelCacheKey, sentinelCacheEntry); cacheEntry.ConfigureUpdateSentinel(sentinelStore, sentinelCacheEntry); }
// NOTE: this method _MUST_ be called with the write lock held void UpdateExpirable (MemoryCacheEntry entry) { if (timedItems == null) timedItems = new MemoryCacheEntryPriorityQueue (); timedItems.Enqueue (entry); if (expirationTimer == null) expirationTimer = new Timer (RemoveExpiredItems, null, owner.TimerPeriod, owner.TimerPeriod); }
internal void Set(MemoryCacheKey key, MemoryCacheEntry entry) { if (_useInsertBlock && entry.HasUsage()) { WaitInsertBlock(); } MemoryCacheEntry existingEntry = null; bool added = false; lock (_entriesLock) { if (_disposed == 0) { existingEntry = _entries[key] as MemoryCacheEntry; if (existingEntry != null) { existingEntry.State = EntryState.RemovingFromCache; } entry.State = EntryState.AddingToCache; added = true; _entries[key] = entry; } } CacheEntryRemovedReason reason = CacheEntryRemovedReason.Removed; if (existingEntry != null) { if (existingEntry.UtcAbsExp <= DateTime.UtcNow) { reason = CacheEntryRemovedReason.Expired; } RemoveFromCache(existingEntry, reason, delayRelease:true); } if (added) { AddToCache(entry); } // Dev10 861163: Call Release after the new entry has been completely added so // that the CacheItemRemovedCallback can take a dependency on the newly inserted item. if (existingEntry != null) { existingEntry.Release(_cache, reason); } }
public object AddOrGetExisting (string key, object value, CacheItemPolicy policy) { bool readLocked = false, writeLocked = false; try { cache_lock.EnterUpgradeableReadLock (); readLocked = true; MemoryCacheEntry entry; if (cache.TryGetValue (key, out entry) && entry != null) { perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS); if (entry.IsSliding) entry.UpdateSlidingExpiry (); return entry.Value; } perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES); cache_lock.EnterWriteLock (); writeLocked = true; if (policy == null) entry = new MemoryCacheEntry (owner, key, value); else entry = new MemoryCacheEntry (owner, key, value, policy.AbsoluteExpiration, policy.ChangeMonitors, policy.Priority, policy.RemovedCallback, policy.SlidingExpiration, policy.UpdateCallback); AddToCache (key, entry); return null; } finally { if (writeLocked) cache_lock.ExitWriteLock (); if (readLocked) cache_lock.ExitUpgradeableReadLock (); } }
internal MemoryCacheEntry Remove(MemoryCacheKey key, MemoryCacheEntry entryToRemove, CacheEntryRemovedReason reason) { MemoryCacheEntry entry = null; lock (_entriesLock) { if (_disposed == 0) { // get current entry entry = _entries[key] as MemoryCacheEntry; // remove if it matches the entry to be removed (but always remove if entryToRemove is null) if (entryToRemove == null || Object.ReferenceEquals(entry, entryToRemove)) { // Dev10 865887: MemoryCache.Remove("\ue637\ud22a\u3e17") causes NullReferenceEx if (entry != null) { entry.State = EntryState.RemovingFromCache; _entries.Remove(key); } } else { entry = null; } } } // release outside of lock RemoveFromCache(entry, reason); return entry; }
public void Set (string key, object value, CacheItemPolicy policy) { bool locked = false; try { cache_lock.EnterWriteLock (); locked = true; MemoryCacheEntry mce; bool update = false; if (cache.TryGetValue (key, out mce)) { if (mce != null) { perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_HITS); mce.Value = value; mce.SetPolicy (policy); if (mce.IsExpirable) UpdateExpirable (mce); lru.Update (mce); return; } update = true; } perfCounters.Increment (MemoryCachePerformanceCounters.CACHE_MISSES); if (policy != null) mce = new MemoryCacheEntry (owner, key, value, policy.AbsoluteExpiration, policy.ChangeMonitors, policy.Priority, policy.RemovedCallback, policy.SlidingExpiration, policy.UpdateCallback); else mce = new MemoryCacheEntry (owner, key, value); AddToCache (key, mce, update); } finally { if (locked) cache_lock.ExitWriteLock (); } }
internal void Remove(MemoryCacheEntry cacheEntry) { byte expiresBucket = cacheEntry.ExpiresBucket; if (expiresBucket != 0xff) { this._buckets[expiresBucket].RemoveCacheEntry(cacheEntry); } }
// Associates this entry with an update sentinel. If this entry has a sliding expiration, we need to // touch the sentinel so that it doesn't expire. internal void ConfigureUpdateSentinel(MemoryCacheStore sentinelStore, MemoryCacheEntry sentinelEntry) { lock (this) { if (_fields == null) { _fields = new SeldomUsedFields(); } _fields._updateSentinel = Tuple.Create(sentinelStore, sentinelEntry); } }
// 'updatePerfCounters' defaults to true since this method is called by all Get() operations // to update both the performance counters and the sliding expiration. Callers that perform // nested sliding expiration updates (like a MemoryCacheEntry touching its update sentinel) // can pass false to prevent these from unintentionally showing up in the perf counters. internal void UpdateExpAndUsage(MemoryCacheEntry entry, bool updatePerfCounters = true) { if (entry != null) { if (entry.InUsage() || entry.SlidingExp > TimeSpan.Zero) { DateTime utcNow = DateTime.UtcNow; entry.UpdateSlidingExp(utcNow, _expires); entry.UpdateUsage(utcNow, _usage); } // DevDiv #67021: If this entry has an update sentinel, the sliding expiration is actually associated // with that sentinel, not with this entry. We need to update the sentinel's sliding expiration to // keep the sentinel from expiring, which in turn would force a removal of this entry from the cache. entry.UpdateSlidingExpForUpdateSentinel(); if (updatePerfCounters && _perfCounters != null) { _perfCounters.Increment(PerfCounterName.Hits); _perfCounters.Increment(PerfCounterName.HitRatio); _perfCounters.Increment(PerfCounterName.HitRatioBase); } } else { if (updatePerfCounters && _perfCounters != null) { _perfCounters.Increment(PerfCounterName.Misses); _perfCounters.Increment(PerfCounterName.HitRatioBase); } } }