public override void GetKeyList(int bucketId, bool startLogging, out ClusteredArrayList keyList) { if (startLogging) _logMgr.StartLogging(bucketId, LogMode.LogBeforeAfterActualOperation); keyList = new ClusteredArrayList(); if (_keyList != null) { if (_keyList.Contains(bucketId)) { HashVector keyTbl = _keyList[bucketId] as HashVector; keyList.AddRange(keyTbl.Keys); } } }
/// <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; }
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; }
public override void GetKeyList(int bucketId, bool startLogging, out ClusteredArrayList keyList) { Sync.AcquireReaderLock(Timeout.Infinite); try { _cache.GetKeyList(bucketId, startLogging, out keyList); } finally { Sync.ReleaseReaderLock(); } }
/// <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; }
public static ClusteredArrayList Synchronized(ClusteredArrayList list) { if (list == null) throw new ArgumentNullException("list"); #if DEBUG Contract.Ensures(Contract.Result<ClusteredArrayList>() != null); Contract.EndContractBlock(); #endif return new SyncArrayList(list); }
// 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; }
// Clones this ArrayList, doing a shallow copy. (A copy is made of all // Object references in the ArrayList, but the Objects pointed to // are not cloned). public virtual Object Clone() { #if DEBUG Contract.Ensures(Contract.Result<Object>() != null); #endif ClusteredArrayList la = new ClusteredArrayList(_size); la._size = _size; la._version = _version; ClusteredArray<object>.Copy(_items, 0, la._items, 0, _size); return la; }
internal ArrayListEnumeratorSimple(ClusteredArrayList list) { this.list = list; this.index = -1; version = list._version; isArrayList = (list.GetType() == typeof(ClusteredArrayList)); currentElement = dummyObject; }
internal Range(ClusteredArrayList list, int index, int count) : base(false) { _baseList = list; _baseIndex = index; _baseSize = count; _baseVersion = list._version; // we also need to update _version field to make Range of Range work _version = list._version; }
private int startIndex; // Save this for Reset. internal ArrayListEnumerator(ClusteredArrayList list, int index, int count) { this.list = list; startIndex = index; this.index = index - 1; endIndex = this.index + count; // last valid index version = list._version; currentElement = null; }
internal ReadOnlyArrayList(ClusteredArrayList l) { _list = l; }
internal FixedSizeArrayList(ClusteredArrayList l) { _list = l; _version = _list._version; }
internal SyncArrayList(ClusteredArrayList list) : base(false) { _list = list; _root = list.SyncRoot; }
public virtual void GetKeyList(int bucketId, bool startLogging, out ClusteredArrayList keyList) { keyList = null; }