/// <summary> /// Handles notification of page eviction from the page cache /// </summary> /// <param name="sender">The page cache performing the eviction</param> /// <param name="args">The evication event arguments</param> /// <remarks>When the eviction event is for a writeable page, this handler /// ensures that the page is queued with the background page writer. If there /// is no background page writer because the page store was created with the /// disableBackgroundWriter option, then this method cancels an eviction /// for a writeable page.</remarks> private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { if (args.Partition.Equals(_path)) { // Evicting a page from this store if (args.PageId >= _newPageOffset) { // Evicting a writeable page - add the page to the background write queue to ensure it gets written out. if (_backgroundPageWriter == null) { // Do not evict this page args.CancelEviction = true; } else { // Queue the page with the background page writer #if DEBUG_PAGESTORE Logging.LogDebug("Evict {0}", args.PageId); #endif var pageToEvict = _newPages[(int)(args.PageId - _newPageOffset)]; if (pageToEvict.IsAlive) { // Passing 0 for the transaction id is OK because it is not used for writing append-only pages _backgroundPageWriter.QueueWrite(pageToEvict.Target as IPage, 0ul); } // Once the page write is queued, the cache entry can be evicted. // The background page writer will hold on to the page data object until it is written args.CancelEviction = false; } } } }
private void FireAfterEvict(EvictionEventArgs evictionArgs) { if (AfterEvict != null) { AfterEvict(this, evictionArgs); } }
/// <summary> /// Handles notification of page eviction from the page cache /// </summary> /// <param name="sender">The page cache performing the eviction</param> /// <param name="args">The evication event arguments</param> /// <remarks>When the eviction event is for a writeable page, this handler /// ensures that the page is queued with the background page writer. If there /// is no background page writer because the page store was created with the /// disableBackgroundWriter option, then this method cancels an eviction /// for a writeable page.</remarks> private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { if (args.Partition.Equals(_path)) { // Evicting a page from this store if (args.PageId >= _newPageOffset) { // Evicting a writeable page - add the page to the background write queue to ensure it gets written out. if (_backgroundPageWriter == null) { // Do not evict this page args.CancelEviction = true; } else { // Queue the page with the background page writer #if DEBUG_PAGESTORE Logging.LogDebug( "Evict {0}", args.PageId ); #endif var pageToEvict = _newPages[(int) (args.PageId - _newPageOffset)]; if (pageToEvict.IsAlive) { // Passing 0 for the transaction id is OK because it is not used for writing append-only pages _backgroundPageWriter.QueueWrite(pageToEvict.Target as IPage, 0ul); } // Once the page write is queued, the cache entry can be evicted. // The background page writer will hold on to the page data object until it is written args.CancelEviction = false; } } } }
private void FirePostEvict(EvictionEventArgs args) { if (AfterEvict != null) { AfterEvict(this, args); } }
private void FireBeforeEvict(EvictionEventArgs evictionArgs) { if (BeforeEvict != null) { BeforeEvict(this, evictionArgs); } }
private bool FirePreEvict(EvictionEventArgs args) { if (BeforeEvict != null) { BeforeEvict(this, args); } return(!args.CancelEviction); }
private bool FirePreEvict(EvictionEventArgs args) { if (BeforeEvict != null) { BeforeEvict(this, args); } return !args.CancelEviction; }
private void EvictItems() { if (_evictInProgress) { return; } _evictInProgress = true; try { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: START"); #endif var evictPointer = _accessList.Last; while (evictPointer != null && _count > _lowWaterMark) { var partition = evictPointer.Value.Key; var pageId = evictPointer.Value.Value.Id; var evictionArgs = new EvictionEventArgs(partition, pageId); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Selected {0}", pageId); #endif FireBeforeEvict(evictionArgs); if (!evictionArgs.CancelEviction) { var cacheKey = MakeCacheKey(partition, pageId); var tmp = evictPointer.Previous; _accessList.Remove(evictPointer); _cacheItems.Remove(cacheKey); _count--; FireAfterEvict(evictionArgs); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Evicted {0}", pageId); #endif evictPointer = tmp; } else { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Eviction of {0} was cancelled", pageId); #endif evictPointer = evictPointer.Previous; } } #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: END"); #endif } finally { _evictInProgress = false; } }
private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { if (args.Partition.Equals(_filePath)) { Tuple<BinaryFilePage, ulong> bfpTuple; if (_modifiedPages.TryGetValue(args.PageId, out bfpTuple)) { EnsureOutputStream(); bfpTuple.Item1.Write(_outputStream, bfpTuple.Item2); } _modifiedPages.Remove(args.PageId); } }
public void Clear(string partition) { var partitionId = AssertPartitionId(partition); foreach(var k in _pages.Keys.Where(k=>k.PartitionId == partitionId).ToList()) { var eventArgs = new EvictionEventArgs(partition, k.PageId); if (FirePreEvict(eventArgs)) { _pages.Remove(k); FirePostEvict(eventArgs); } } }
private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { if (args.Partition.Equals(_filePath)) { Tuple <BinaryFilePage, ulong> bfpTuple; if (_modifiedPages.TryGetValue(args.PageId, out bfpTuple)) { EnsureOutputStream(); bfpTuple.Item1.Write(_outputStream, bfpTuple.Item2); } _modifiedPages.Remove(args.PageId); } }
public void Clear(string partition) { var partitionId = AssertPartitionId(partition); foreach (var k in _pages.Keys.Where(k => k.PartitionId == partitionId).ToList()) { var eventArgs = new EvictionEventArgs(partition, k.PageId); if (FirePreEvict(eventArgs)) { _pages.Remove(k); FirePostEvict(eventArgs); } } }
private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { args.CancelEviction = _modifiedPages.ContainsKey(args.PageId); return; /* * lock (_restartLock) // Ensure we don't try to process page evictions while restarting the background writer * { * if (_modifiedPages.ContainsKey(args.PageId)) * { * var page = PageCache.Instance.Lookup(_filePath, args.PageId) as BinaryFilePage; * if (page != null) * { * _backgroundPageWriter.QueueWrite(page, _currentReadTxnId + 1); * } * } * // Unmodified pages can just be evicted * } */ }
private void EvictItems() { if (DateTime.Now.Subtract(_cacheBlocked).TotalSeconds < BlockedCacheRetryTimeout) { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: In cache blocked timeout."); #endif return; // Last eviction failed recently so don't repeat until the timeout is exceeded } if (_evictInProgress) return; _evictInProgress = true; try { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: START"); #endif var evictionCount = 0; lock (_updateLock) { var evictPointer = _accessList.Last; while (evictPointer != null && _count > _lowWaterMark) { var partition = evictPointer.Value.Key; var pageId = evictPointer.Value.Value.Id; var evictionArgs = new EvictionEventArgs(partition, pageId); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Selected {0}", pageId); #endif FireBeforeEvict(evictionArgs); if (!evictionArgs.CancelEviction) { var cacheKey = MakeCacheKey(partition, pageId); var tmp = evictPointer.Previous; _accessList.Remove(evictPointer); _cacheItems.Remove(cacheKey); _count--; evictionCount++; FireAfterEvict(evictionArgs); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Evicted {0}", pageId); #endif evictPointer = tmp; } else { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Eviction of {0} was cancelled", pageId); #endif evictPointer = evictPointer.Previous; } } } if (evictionCount == 0) { // The entire cache is blocked with modified pages that cannot be written out // this can happen with large transactions on the BinaryFilePageStore or on // the AppendOnlyFilePageStore with background writes disabled. // To prevent repeated iteration through a blocked cache we will check this timestamp: _cacheBlocked = DateTime.Now; #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Setting cached blocked timeout"); #endif } #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: END"); #endif } finally { try { FireEvictionCompleted(); } finally { _evictInProgress = false; } } }
private void EvictItems() { if (DateTime.Now.Subtract(_cacheBlocked).TotalSeconds < BlockedCacheRetryTimeout) { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: In cache blocked timeout."); #endif return; // Last eviction failed recently so don't repeat until the timeout is exceeded } if (_evictInProgress) { return; } _evictInProgress = true; try { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: START"); #endif var evictionCount = 0; lock (_updateLock) { var evictPointer = _accessList.Last; while (evictPointer != null && _count > _lowWaterMark) { var partition = evictPointer.Value.Key; var pageId = evictPointer.Value.Value.Id; var evictionArgs = new EvictionEventArgs(partition, pageId); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Selected {0}", pageId); #endif FireBeforeEvict(evictionArgs); if (!evictionArgs.CancelEviction) { var cacheKey = MakeCacheKey(partition, pageId); var tmp = evictPointer.Previous; _accessList.Remove(evictPointer); _cacheItems.Remove(cacheKey); _count--; evictionCount++; FireAfterEvict(evictionArgs); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Evicted {0}", pageId); #endif evictPointer = tmp; } else { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Eviction of {0} was cancelled", pageId); #endif evictPointer = evictPointer.Previous; } } } if (evictionCount == 0) { // The entire cache is blocked with modified pages that cannot be written out // this can happen with large transactions on the BinaryFilePageStore or on // the AppendOnlyFilePageStore with background writes disabled. // To prevent repeated iteration through a blocked cache we will check this timestamp: _cacheBlocked = DateTime.Now; #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Setting cached blocked timeout"); #endif } #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: END"); #endif } finally { try { FireEvictionCompleted(); } finally { _evictInProgress = false; } } }
private void EvictItems() { if (_evictInProgress) return; _evictInProgress = true; try { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: START"); #endif var evictPointer = _accessList.Last; while (evictPointer != null && _count > _lowWaterMark) { var partition = evictPointer.Value.Key; var pageId = evictPointer.Value.Value.Id; var evictionArgs = new EvictionEventArgs(partition, pageId); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Selected {0}", pageId); #endif FireBeforeEvict(evictionArgs); if (!evictionArgs.CancelEviction) { var cacheKey = MakeCacheKey(partition, pageId); var tmp = evictPointer.Previous; _accessList.Remove(evictPointer); _cacheItems.Remove(cacheKey); _count--; FireAfterEvict(evictionArgs); #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Evicted {0}", pageId); #endif evictPointer = tmp; } else { #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: Eviction of {0} was cancelled", pageId); #endif evictPointer = evictPointer.Previous; } } #if DEBUG_PAGECACHE Logging.LogDebug("LruPageCache.EvictItems: END"); #endif } finally { _evictInProgress = false; } }
private void FireAfterEvict(EvictionEventArgs evictionArgs) { if (AfterEvict != null) AfterEvict(this, evictionArgs); }
private void FireBeforeEvict(EvictionEventArgs evictionArgs) { if (BeforeEvict != null) BeforeEvict(this, evictionArgs); }
private void BeforePageCacheEvict(object sender, EvictionEventArgs args) { args.CancelEviction = _modifiedPages.ContainsKey(args.PageId); return; /* lock (_restartLock) // Ensure we don't try to process page evictions while restarting the background writer { if (_modifiedPages.ContainsKey(args.PageId)) { var page = PageCache.Instance.Lookup(_filePath, args.PageId) as BinaryFilePage; if (page != null) { _backgroundPageWriter.QueueWrite(page, _currentReadTxnId + 1); } } // Unmodified pages can just be evicted } */ }