public void RemoveFromIndex(object key) { lock (_status_mutex) { int removeSize = 0; if (!IsInProgress) { ExpiryIndexEntry expEntry = _mainIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; } _mainIndex.Remove(key); } else { //Adding a with null value indicates that this key has been //removed so we should remove it from the main index. ExpiryIndexEntry expEntry = _transitoryIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; } _transitoryIndex[key] = null; } _expirationManagerSize -= removeSize; } }
/// <summary> /// Aplica o logs do gerenciador. /// </summary> private void ApplyLoggs() { lock (_status_mutex) { this.IsInProgress = false; if (_indexCleared) { _mainIndex.Clear(); _indexCleared = false; } var enumerator = _transitoryIndex.GetEnumerator(); while (enumerator.MoveNext()) { object key = enumerator.Key; ExpiryIndexEntry entry = enumerator.Value as ExpiryIndexEntry; if (entry != null) { _mainIndex[key] = entry; } else { _mainIndex.Remove(key); } } } }
/// <summary> /// We log all the operations in a transitory index when we are iterating on /// the main index to determine the expired items. StopLogging should be called /// after selection of item is completd. We apply all the logs from transitory /// index to the main index. A null value in transitory index against a key /// indicates that this item is removed during logging, so we should remove /// it from the main log as well. /// </summary> private void ApplyLoggs() { lock (_status_mutex) { IsInProgress = false; if (_indexCleared) { //_mainIndex.Clear(); _mainIndex = new Hashtable(25000, 0.7f); _mainIndexMaxCount = 0; _indexCleared = false; } IDictionaryEnumerator ide = _transitoryIndex.GetEnumerator(); object key; ExpiryIndexEntry expEntry; while (ide.MoveNext()) { key = ide.Key; expEntry = ide.Value as ExpiryIndexEntry; ExpiryIndexEntry oldEntry = (ExpiryIndexEntry)_mainIndex[key]; if (expEntry != null) { _mainIndex[key] = expEntry; } else { //it means this item has been removed; _mainIndex.Remove(key); } if (oldEntry != null) { _expirationManagerSize -= oldEntry.InMemorySize; } } } }
public void UpdateIndex(object key, ExpirationHint hint, bool hasDependentKeys) { if ((key != null) && (hint != null)) { lock (_status_mutex) { if (!this.IsInProgress) { if (!_mainIndex.Contains(key)) { _mainIndex[key] = new ExpiryIndexEntry(hint, hasDependentKeys); } else { ExpiryIndexEntry entry = _mainIndex[key] as ExpiryIndexEntry; if (entry != null) { entry.Hint = hint; entry.HasDependentKeys = hasDependentKeys; } } } else if (_transitoryIndex[key] == null) { _transitoryIndex[key] = new ExpiryIndexEntry(hint, hasDependentKeys); } else { ExpiryIndexEntry entry2 = _transitoryIndex[key] as ExpiryIndexEntry; if (entry2 != null) { entry2.Hint = hint; entry2.HasDependentKeys = hasDependentKeys; } } } } }
public void UpdateIndex(object key, ExpirationHint hint) { if (key == null || hint == null) { return; } lock (_status_mutex) { int addSize = 0; int removeSize = 0; if (!IsInProgress) { if (!_mainIndex.Contains(key)) { ExpiryIndexEntry entry = new ExpiryIndexEntry(hint); _mainIndex[key] = entry; addSize = entry.InMemorySize; if (_mainIndex.Count > _mainIndexMaxCount) { _mainIndexMaxCount = _mainIndex.Count; } } else { ExpiryIndexEntry expEntry = _mainIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; expEntry.Hint = hint; addSize = expEntry.InMemorySize; } } } else { if (_transitoryIndex[key] == null) { ExpiryIndexEntry entry = new ExpiryIndexEntry(hint); _transitoryIndex[key] = entry; addSize = entry.InMemorySize; if (_transitoryIndex.Count > _transitoryIndexMaxCount) { _transitoryIndexMaxCount = _transitoryIndex.Count; } } else { ExpiryIndexEntry expEntry = _transitoryIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; expEntry.Hint = hint; addSize = expEntry.InMemorySize; } } } _expirationManagerSize -= removeSize; _expirationManagerSize += addSize; } }
/// <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; ulong currentRun = 0; lock (this) { currentRun = _runCount++; } //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); } ArrayList selectedKeys = new System.Collections.ArrayList(); int oldItemsCount = 0; Hashtable 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 Hashtable(); } } lock (_mainIndex.SyncRoot) { IDictionaryEnumerator em = _mainIndex.GetEnumerator(); if (em != null) { while (em.MoveNext()) { ExpiryIndexEntry expirtyEntry = em.Value as ExpiryIndexEntry; ExpirationHint hint = expirtyEntry.Hint; 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(); ArrayList dependentItems = new ArrayList(); ArrayList removedItems = null; DateTime startTime = DateTime.Now; Hashtable expiredItemTable = new Hashtable(); expiredItemTable.Add(ItemRemoveReason.Expired, selectedKeys);//Time based expiration try { IDictionaryEnumerator ide = expiredItemTable.GetEnumerator(); while (ide.MoveNext()) { selectedKeys = ide.Value as ArrayList; ItemRemoveReason removedReason = (ItemRemoveReason)ide.Key; if (selectedKeys.Count > 0) { //new architectural changes begins from here. ArrayList keysTobeRemoved = new ArrayList(); 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); removedItems = cache.RemoveSync(keysTobeRemoved.ToArray(), removedReason, false, operationContext) as ArrayList; //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 occured 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); removedItems = cache.RemoveSync(keysTobeRemoved.ToArray(), removedReason, false, operationContext) as ArrayList; //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 occured 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 void UpdateIndex(object key, ExpirationHint hint) { if (key == null || hint == null) return; lock (_status_mutex) { int addSize = 0; int removeSize = 0; if (!IsInProgress) { if (!_mainIndex.Contains(key)) { ExpiryIndexEntry entry = new ExpiryIndexEntry(hint); _mainIndex[key] = entry; addSize = entry.InMemorySize; if (_mainIndex.Count > _mainIndexMaxCount) _mainIndexMaxCount = _mainIndex.Count; } else { ExpiryIndexEntry expEntry = _mainIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; expEntry.Hint = hint; addSize = expEntry.InMemorySize; } } } else { if (_transitoryIndex[key] == null) { ExpiryIndexEntry entry = new ExpiryIndexEntry(hint); _transitoryIndex[key] = entry; addSize = entry.InMemorySize; if (_transitoryIndex.Count > _transitoryIndexMaxCount) _transitoryIndexMaxCount = _transitoryIndex.Count; } else { ExpiryIndexEntry expEntry = _transitoryIndex[key] as ExpiryIndexEntry; if (expEntry != null) { removeSize = expEntry.InMemorySize; expEntry.Hint = hint; addSize = expEntry.InMemorySize; } } } _expirationManagerSize -= removeSize; _expirationManagerSize += addSize; } }