/// <summary> /// Removes the object and key pair from the cache. The key is specified as parameter. /// Moreover it take a removal reason and a boolean specifying if a notification should /// be raised. /// </summary> /// <param name="key">key of the entry.</param> /// <param name="removalReason">reason for the removal.</param> /// <param name="notify">boolean specifying to raise the event.</param> /// <param name="isUserOperation"></param> /// <param name="lockId"></param> /// <param name="accessType"></param> /// <param name="operationContext"></param> /// <returns>item value</returns> public override CacheEntry Remove(object key, ItemRemoveReason removalReason, bool notify, bool isUserOperation, object lockId, LockAccessType accessType, OperationContext operationContext) { CacheEntry e = null; CacheEntry pe = null; { object actualKey = key; if (key is object[]) { actualKey = ((object[])key)[0]; } if (accessType != LockAccessType.IGNORE_LOCK) { pe = GetInternal(actualKey, false, operationContext); if (pe != null) { if (pe.IsItemLocked() && !pe.CompareLock(lockId)) { throw new LockingException("Item is locked."); } } } e = RemoveInternal(actualKey, removalReason, isUserOperation, operationContext); EventId eventId = null; EventContext eventContext = null; OperationID opId = operationContext.OperatoinID; if (e != null) { if (_stateTransferKeyList != null && _stateTransferKeyList.ContainsKey(key)) _stateTransferKeyList.Remove(key); // commented by muds try { if (e.ExpirationHint != null) { _context.ExpiryMgr.RemoveFromIndex(key); ((IDisposable)e.ExpirationHint).Dispose(); } } catch (Exception ex) { NCacheLog.Error("LocalCacheBase.Remove(object, ItemRemovedReason, bool):", ex.ToString()); } if (IsSelfInternal) { // Disposed the one and only cache entry. ((IDisposable)e).Dispose(); if (removalReason == ItemRemoveReason.Expired) { _context.PerfStatsColl.IncrementExpiryPerSecStats(); } else if (!_context.CacheImpl.IsEvictionAllowed && removalReason == ItemRemoveReason.Underused) { _context.PerfStatsColl.IncrementEvictPerSecStats(); } _context.PerfStatsColl.IncrementCountStats((long)Count); } if (notify) { CallbackEntry cbEtnry = e.Value as CallbackEntry;// e.DeflattedValue(_context.SerializationContext); if (cbEtnry != null && cbEtnry.ItemRemoveCallbackListener != null && cbEtnry.ItemRemoveCallbackListener.Count > 0) { //generate event id if (!operationContext.Contains(OperationContextFieldName.EventContext)) //for atomic operations { eventId = EventId.CreateEventId(opId); } else //for bulk { eventId = ((EventContext)operationContext.GetValueByField(OperationContextFieldName.EventContext)).EventID; } eventId.EventType = EventType.ITEM_REMOVED_CALLBACK; eventContext = new EventContext(); eventContext.Add(EventContextFieldName.EventID, eventId); EventCacheEntry eventCacheEntry = CacheHelper.CreateCacheEventEntry(cbEtnry.ItemRemoveCallbackListener, e); eventContext.Item = eventCacheEntry; eventContext.Add(EventContextFieldName.ItemRemoveCallbackList, cbEtnry.ItemRemoveCallbackListener.Clone()); //Will always reaise the whole entry for old clients NotifyCustomRemoveCallback(actualKey, e, removalReason, false, (OperationContext)operationContext.Clone(), eventContext); } } } else if (_stateTransferKeyList != null && _stateTransferKeyList.ContainsKey(key)) { _stateTransferKeyList.Remove(key); } } _stats.UpdateCount(this.Count); if (_context.PerfStatsColl != null) { _context.PerfStatsColl.SetCacheSize(Size); } return e; }
/// <summary> /// Adds a pair of key and value to the cache. If the specified key already exists /// in the cache; it is updated, otherwise a new item is added to the cache. /// </summary> /// <param name="key">key of the entry.</param> /// <param name="cacheEntry">the cache entry.</param> /// <returns>returns the result of operation.</returns> public sealed override CacheInsResultWithEntry Insert(object key, CacheEntry cacheEntry, bool notify, bool isUserOperation, object lockId, LockAccessType access, OperationContext operationContext) { CacheInsResultWithEntry result = new CacheInsResultWithEntry(); try { CacheEntry pe = null; CallbackEntry cbEtnry = null; OperationID opId = operationContext.OperatoinID; EventId eventId = null; EventContext eventContext = null; pe = GetInternal(key, false, operationContext); result.Entry = pe; if (pe != null && access != LockAccessType.IGNORE_LOCK) { { if (access == LockAccessType.RELEASE || access == LockAccessType.DONT_RELEASE) { if (pe.IsItemLocked() && !pe.CompareLock(lockId)) { result.Result = CacheInsResult.ItemLocked; result.Entry = null; return result; } } if (access == LockAccessType.DONT_RELEASE) { cacheEntry.CopyLock(pe.LockId, pe.LockDate, pe.LockExpiration); } else { cacheEntry.ReleaseLock(); } } } ExpirationHint peExh = pe == null ? null : pe.ExpirationHint; if (pe != null && pe.Value is CallbackEntry) { cbEtnry = pe.Value as CallbackEntry; cacheEntry = CacheHelper.MergeEntries(pe, cacheEntry); } result.Result = InsertInternal(key, cacheEntry, isUserOperation, pe, operationContext); if ((result.Result == CacheInsResult.Success || result.Result == CacheInsResult.SuccessNearEvicition) && _stateTransferKeyList != null && _stateTransferKeyList.ContainsKey(key)) { result.Result = result.Result == CacheInsResult.Success ? CacheInsResult.SuccessOverwrite : CacheInsResult.SuccessOverwriteNearEviction; } // Not enough space, evict and try again. if (result.Result == CacheInsResult.NeedsEviction || result.Result == CacheInsResult.SuccessNearEvicition || result.Result == CacheInsResult.SuccessOverwriteNearEviction) { Evict(); if (result.Result == CacheInsResult.SuccessNearEvicition) result.Result = CacheInsResult.Success; if (result.Result == CacheInsResult.SuccessOverwriteNearEviction) result.Result = CacheInsResult.SuccessOverwrite; } // Operation completed! if (result.Result == CacheInsResult.Success || result.Result == CacheInsResult.SuccessOverwrite) { // commented by muds //remove the old hint from expiry index. if (peExh != null) _context.ExpiryMgr.RemoveFromIndex(key); if (cacheEntry.ExpirationHint != null) { cacheEntry.ExpirationHint.CacheKey = (string)key; if (isUserOperation) { try { _context.ExpiryMgr.ResetHint(peExh, cacheEntry.ExpirationHint); } catch (Exception e) { RemoveInternal(key, ItemRemoveReason.Removed, false, operationContext); throw e; } } else { cacheEntry.ExpirationHint.ReInitializeHint(Context); } _context.ExpiryMgr.UpdateIndex(key, cacheEntry); } if (IsSelfInternal) { _context.PerfStatsColl.IncrementCountStats((long)Count); } } _stats.UpdateCount(this.Count); switch (result.Result) { case CacheInsResult.Success: break; case CacheInsResult.SuccessOverwrite: if (notify) { EventCacheEntry eventCacheEntry = CacheHelper.CreateCacheEventEntry(Runtime.Events.EventDataFilter.DataWithMetadata, cacheEntry); ; EventCacheEntry oldEventCacheEntry = CacheHelper.CreateCacheEventEntry(Runtime.Events.EventDataFilter.DataWithMetadata, pe); if (cbEtnry != null) { if (cbEtnry.ItemUpdateCallbackListener != null && cbEtnry.ItemUpdateCallbackListener.Count > 0) { if (!operationContext.Contains(OperationContextFieldName.EventContext)) //for atomic operations { eventId = EventId.CreateEventId(opId); eventContext = new EventContext(); } else //for bulk { eventId = ((EventContext)operationContext.GetValueByField(OperationContextFieldName.EventContext)).EventID; } eventContext = new EventContext(); eventId.EventType = EventType.ITEM_UPDATED_CALLBACK; eventContext.Add(EventContextFieldName.EventID, eventId); eventContext.Item = eventCacheEntry; eventContext.OldItem = oldEventCacheEntry; NotifyCustomUpdateCallback(key, cbEtnry.ItemUpdateCallbackListener, false, (OperationContext)operationContext.Clone(), eventContext); } } } break; } } finally { } if (_context.PerfStatsColl != null) { _context.PerfStatsColl.SetCacheSize(Size); } return result; }