/// <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; } } } }
public void Commit(ulong commitId, BrightstarProfiler profiler) { if (CanWrite) { foreach (var pageId in _modifiedPages.Keys) { var page = PageCache.Instance.Lookup(_partitionId, pageId) as BinaryFilePage; if (page != null && page.IsDirty) { _backgroundPageWriter.QueueWrite(page, commitId); } } _backgroundPageWriter.Flush(); lock (_restartLock) { _backgroundPageWriter.Shutdown(); _backgroundPageWriter.Dispose(); PageCache.Instance.Clear(_partitionId); UpdatePartitionId(); _readTxnId = _writeTxnId; _writeTxnId++; _backgroundPageWriter = new BackgroundPageWriter(_persistenceManager.GetOutputStream(_filePath, FileMode.Open)); } } else { throw new InvalidOperationException("Attempt to Commit on a read-only store instance"); } }
public void Commit(ulong commitId, BrightstarProfiler profiler) { using (profiler.Step("PageStore.Commit")) { if (_backgroundPageWriter != null) { foreach (var p in _newPages) { _backgroundPageWriter.QueueWrite(p, commitId); } _backgroundPageWriter.Flush(); RestartBackgroundWriter(); foreach (var p in _newPages) { PageCache.Instance.InsertOrUpdate(_path, p); } } else { using (var outputStream = _peristenceManager.GetOutputStream(_path, FileMode.Open)) { foreach (var p in _newPages) { p.Write(outputStream, commitId); PageCache.Instance.InsertOrUpdate(_path, p); } } } _newPages.Clear(); _newPageOffset = _nextPageId; } /* * using (var writeStream = _peristenceManager.GetOutputStream(_path, FileMode.Open)) * { * writeStream.Seek((long) ((_newPageOffset - 1)*(ulong) _pageSize), SeekOrigin.Begin); * foreach (var p in _newPages) * { * writeStream.Write(p.Data, 0, _pageSize); * } * writeStream.Flush(); * _newPages.Clear(); * _newPageOffset = _nextPageId; * } */ }