/// <summary>
        /// 
        /// </summary>
        /// <param name="cache"></param>
        /// <param name="evictSize"></param>
        /// <returns></returns>
        private IList GetSelectedKeys(CacheBase cache, long evictSize)
        {
            ClusteredArrayList selectedKeys = new ClusteredArrayList(100);

            long sizeCount = 0;
            int prvsSize = 0;
            object key = null;
            bool selectionComplete = false;

            lock (_index.SyncRoot)
            {
                for (int i = 0; i < 5; i++)
                {
                    if (!selectionComplete)
                    {
                        HashVector currentIndex = this._index[i];
                        if (currentIndex != null)
                        {
                            IDictionaryEnumerator ide = currentIndex.GetEnumerator();
                            while (ide.MoveNext())
                            {
                                key = ide.Key;
                                if (key != null)
                                {
                                    int itemSize = cache.GetItemSize(key);
                                    if (sizeCount + itemSize >= evictSize && sizeCount > 0)
                                    {
                                        if (evictSize - sizeCount > (itemSize + sizeCount) - evictSize)
                                            selectedKeys.Add(key);

                                        selectionComplete = true;
                                        break;
                                    }
                                    else
                                    {
                                        selectedKeys.Add(key);
                                        sizeCount += itemSize;
                                        prvsSize = itemSize;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        //break the outer loop. we have already picked up
                        //the keys to be evicited.
                        break; 
                    }
                }
            }
            return selectedKeys;
        }
Example #2
0
        /// <summary>
        /// Called by the scheduler to remove the items that has expired
        /// </summary>
        public bool Expire()
        {
            //indicates whether some items expired during this interval or not...
            bool expired = false;
           
            //muds:

            //if user has updated the file then the new values will be reloaded.
            _sleepInterval = Convert.ToInt32(ServiceConfiguration.ExpirationBulkRemoveDelay);
            _removeThreshhold = Convert.ToInt32(ServiceConfiguration.ExpirationBulkRemoveSize);
           
           
            CacheBase cacheInst = _context.CacheImpl;
            CacheBase cache = _context.CacheInternal;
            Cache rootCache = _context.CacheRoot;
           
            if (cache == null)
                throw new InvalidOperationException("No cache instance defined");

            bool allowExpire = AllowClusteredExpiry;

            //in case of replication, only the coordinator/sub-coordinator is responsible to expire the items.
            if (!allowExpire) return false;
            ClusteredArrayList selectedKeys = new ClusteredArrayList();
            int oldItemsCount = 0;
            HashVector oldeItems = null;

            try
            {
                StartLogging();

                DateTime startTime = DateTime.Now;
                int currentTime = AppUtil.DiffSeconds(startTime);
                int cleanSize = (int)Math.Ceiling(cache.Count * _cleanRatio);

                //set the flag that we are going to expire the items.

                if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval)
                {
                    _cacheLastAccessLoggingInterval = CacheLastAccessLoggingInterval;
                    _cacheLastAccessCountEnabled = IsCacheLastAccessCountEnabled;
                    _cacheLastAccessCountLoggingEnabled = IsCacheLastAccessLoggingEnabled;
                    _cacheLastAccessInterval = CacheLastAccessCountInterval;
                }
                else
                    _cacheLastAccessLoggingIntervalPassed++;


                if (_cacheLastAccessCountEnabled && _cacheLastAccessCountLoggingEnabled)
                {
                    if (_cacheLastAccessLoggingIntervalPassed >= _cacheLastAccessLoggingInterval)
                    {
                        _cacheLastAccessLoggingIntervalPassed = 0;
                        oldeItems = new HashVector();
                    }
                }
                lock (_mainIndex.SyncRoot)
                {
                    IDictionaryEnumerator em = _mainIndex.GetEnumerator(); 

                    if (em != null)
                    {
                        while (em.MoveNext())
                        {
                            ExpirationHint hint = em.Value as ExpirationHint;
                            if (hint != null && _cacheLastAccessCountEnabled && hint is IdleExpiration)
                            {
                                IdleExpiration slidingExpHint = hint as IdleExpiration;
                                TimeSpan diff = AppUtil.GetDateTime(AppUtil.DiffSeconds(DateTime.Now)) - AppUtil.GetDateTime(slidingExpHint.LastAccessTime);
                                if (diff.TotalMinutes >= _cacheLastAccessInterval)
                                {
                                    oldItemsCount++;
                                    if (oldeItems != null)
                                    {
                                        oldeItems.Add(em.Key, null);
                                    }
                                }
                            }
                            if (hint == null || hint.SortKey.CompareTo(currentTime) >= 0)
                                continue;

                            if (hint.DetermineExpiration(_context))
                            {
                                selectedKeys.Add(em.Key);
                                if (cleanSize > 0 && selectedKeys.Count == cleanSize) break;
                            }

                        }
                    }
                }
                if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ExpirationManager.Expire()", String.Format("Expiry time for {0}/{1} Items: " + (DateTime.UtcNow - startTime), selectedKeys.Count, /*_expiryIndex.KeyCount*/cache.Count));
            }
            catch (Exception e)
            {
                NCacheLog.Error("ExpirationManager.Expire(bool)", "LocalCache(Expire): " + e.ToString());
            }
            finally
            {
                _context.PerfStatsColl.IncrementCacheLastAccessCountStats(oldItemsCount);

                ApplyLoggs();
                ClusteredArrayList dependentItems = new ClusteredArrayList();
                DateTime startTime = DateTime.Now;

                HashVector expiredItemTable = new HashVector();

                expiredItemTable.Add(ItemRemoveReason.Expired, selectedKeys);//Time based expiration
                try
                {
                    IDictionaryEnumerator ide = expiredItemTable.GetEnumerator();

                    while (ide.MoveNext())
                    {
                        selectedKeys = ide.Value as ClusteredArrayList;
                        ItemRemoveReason removedReason = (ItemRemoveReason)ide.Key;

                        if (selectedKeys.Count > 0)
                        {
                            //new architectural changes begins from here.

                            ClusteredArrayList keysTobeRemoved = new ClusteredArrayList();

                            for (int i = 0; i < selectedKeys.Count && !_cacheCleared; i++)
                            {
                                keysTobeRemoved.Add(selectedKeys[i]);
                                if (keysTobeRemoved.Count % _removeThreshhold == 0)
                                {
                                    try
                                    {
                                        if (this.IsDisposed) break;

                                        OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                                        object[][] keysExposed = keysTobeRemoved.ToInternalArray();
                                        foreach (object[] collection in keysExposed)
                                        {
                                            cache.RemoveSync(collection, removedReason, false, operationContext);
                                        }
                                        //set the flag that item has expired from cache...
                                        expired = true;

                                        if (_context.PerfStatsColl != null) _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count);
                                    }
                                    catch (Exception e)
                                    {
                                        NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString());
                                    }
                                    keysTobeRemoved.Clear();
                                    //we stop the activity of the current thread so that normal user operation is not affected.
                                    Thread.Sleep(_sleepInterval);
                                }
                            }

                            if (!this.IsDisposed && keysTobeRemoved.Count > 0)
                            {
                                try
                                {
                                    OperationContext operationContext = new OperationContext(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                                    object[][] keysExposed = keysTobeRemoved.ToInternalArray();
                                    foreach (object[] keyCollection in keysExposed)
                                    {
                                        cache.RemoveSync(keyCollection, removedReason, false, operationContext);
                                    }
                                    //set the flag that item has expired from cache...
                                    expired = true;
                                    if (_context.PerfStatsColl != null) _context.PerfStatsColl.IncrementExpiryPerSecStatsBy(keysTobeRemoved.Count);
                                }
                                catch (Exception e)
                                {
                                    NCacheLog.Error("ExpiryManager.Expire", "an error occurred while removing expired items. Error " + e.ToString());
                                }
                            }
                        }
                    }
                }
                finally
                {

                    _transitoryIndex.Clear();
                    lock (this)
                    {
                        _cacheCleared = false;
                    }

                    if (oldeItems != null)
                    {
                        StringBuilder sb = new StringBuilder();
                        IDictionaryEnumerator ide = oldeItems.GetEnumerator();
                        int count = 1;
                        while (ide.MoveNext())
                        {
                            sb.Append(ide.Key + ", ");

                            if (count % 10 == 0)
                            {
                                sb.Append("\r\n");
                                count = 1;
                            }
                            else
                                count++;
                        }

                        NCacheLog.Info(sb.ToString().Trim());

                    }
                }
            }
            return expired;
        }
        void IEvictionPolicy.Execute(CacheBase cache, CacheRuntimeContext context, long evictSize)
        {
          
            ILogger NCacheLog = cache.Context.NCacheLog;
            
            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("LocalCache.Evict()", "Cache Size: {0}" + cache.Count.ToString());

             //if user has updated the values in configuration file then new values will be reloaded.
            _sleepInterval = Convert.ToInt32(ServiceConfiguration.EvictionBulkRemoveDelay);
            _removeThreshhold = Convert.ToInt32(ServiceConfiguration.EvictionBulkRemoveSize);
            DateTime startTime = DateTime.Now;
            IList selectedKeys = this.GetSelectedKeys(cache, (long)Math.Ceiling(evictSize * _ratio));
            DateTime endTime = DateTime.Now;

            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("LocalCache.Evict()", String.Format("Time Span for {0} Items: " + (endTime - startTime), selectedKeys.Count));

            startTime = DateTime.Now;

            Cache rootCache = context.CacheRoot;

            ClusteredArrayList keysTobeRemoved = new ClusteredArrayList();
            ClusteredArrayList dependentItems = new ClusteredArrayList();
            IList removedItems = null;

            IEnumerator e = selectedKeys.GetEnumerator();

            int removedThreshhold = _removeThreshhold/300;
            int remIteration = 0;
            while (e.MoveNext())
            {
                object key = e.Current;
                if (key == null) continue;

                keysTobeRemoved.Add(key);

                if (keysTobeRemoved.Count % 300 == 0)
                {
                    try
                    {
                        OperationContext priorityEvictionOperationContext = new OperationContext();
                        priorityEvictionOperationContext.Add(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                        removedItems = cache.RemoveSync(keysTobeRemoved.ToArray(), ItemRemoveReason.Underused, false, priorityEvictionOperationContext) as ArrayList;

                        context.PerfStatsColl.IncrementEvictPerSecStatsBy(keysTobeRemoved.Count);
                    }
                    catch (Exception ex)
                    {
                        NCacheLog.Error("PriorityEvictionPolicy.Execute", "an error occurred while removing items. Error " + ex.ToString());
                    }
                    keysTobeRemoved.Clear();
                    if (removedItems != null && removedItems.Count > 0)
                    {
                        dependentItems.AddRange(removedItems);
                    }
                    
                    remIteration++;
                    if (remIteration >= removedThreshhold)
                    {
                        //put some delay so that user operations are not affected.
                        System.Threading.Thread.Sleep(_sleepInterval*1000);
                        remIteration = 0;
                    }
                }
            }

            if (keysTobeRemoved.Count > 0)
            {
                try
                {
                    OperationContext priorityEvictionOperationContext = new OperationContext();
                    priorityEvictionOperationContext.Add(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                    removedItems = cache.RemoveSync(keysTobeRemoved.ToArray(), ItemRemoveReason.Underused, false, priorityEvictionOperationContext) as ArrayList;

                    context.PerfStatsColl.IncrementEvictPerSecStatsBy(keysTobeRemoved.Count);
                    if (removedItems != null && removedItems.Count > 0)
                    {
                        dependentItems.AddRange(removedItems);
                    }
                }
                catch (Exception ex)
                {
                    NCacheLog.Error("PriorityEvictionPolicy.Execute", "an error occurred while removing items. Error " + ex.ToString());
                }
            }

            if (dependentItems.Count > 0)
            {
                ArrayList removableList = new ArrayList();
                if (rootCache != null)
                {
                    foreach (object depenentItme in dependentItems)
                    {
                        if (depenentItme == null) continue;
                        removableList.Add(depenentItme);
                        if (removableList.Count % 100 == 0)
                        {
                            try
                            {
                                OperationContext priorityEvictionOperationContext = new OperationContext();
                                priorityEvictionOperationContext.Add(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                                rootCache.CascadedRemove(removableList, ItemRemoveReason.Underused, true, priorityEvictionOperationContext);

                                context.PerfStatsColl.IncrementEvictPerSecStatsBy(removableList.Count);
                            }
                            catch (Exception exc)
                            {
                                NCacheLog.Error("PriorityEvictionPolicy.Execute", "an error occurred while removing dependent items. Error " + exc.ToString());

                            }
                            removableList.Clear();
                        }

                    }
                    if (removableList.Count > 0)
                    {
                        try
                        {
                            OperationContext priorityEvictionOperationContext = new OperationContext();
                            priorityEvictionOperationContext.Add(OperationContextFieldName.OperationType, OperationContextOperationType.CacheOperation);
                            rootCache.CascadedRemove(removableList, ItemRemoveReason.Underused, true, priorityEvictionOperationContext);

                            context.PerfStatsColl.IncrementEvictPerSecStatsBy(removableList.Count);
                        }
                        catch (Exception exc)
                        {
                            NCacheLog.Error("PriorityEvictionPolicy.Execute", "an error occurred while removing dependent items. Error " + exc.ToString());

                        }
                        removableList.Clear();
                    }
                }
            }
            return;

        }
Example #4
0
        // Returns an IList that contains count copies of value.
        //
        public static ClusteredArrayList Repeat(Object value, int count)
        {
            if (count < 0)
                throw new ArgumentOutOfRangeException("count", ResourceHelper.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
#if DEBUG
            Contract.Ensures(Contract.Result<ClusteredArrayList>() != null);
            Contract.EndContractBlock();
#endif
            ClusteredArrayList list = new ClusteredArrayList((count > _defaultCapacity) ? count : _defaultCapacity);
            for (int i = 0; i < count; i++)
                list.Add(value);
            return list;
        }