/// <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");
     }
 }
Esempio n. 3
0
        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;
             * }
             */
        }