Ejemplo n.º 1
0
        /// <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;
        }
Ejemplo n.º 2
0
        /// <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;
        }