private ulong AllocatePageNumber() { var pageNumber = (ulong)Interlocked.Increment(ref _highestPageNumber); _pageCache.NewPage(pageNumber); _pageCache.Update(null, new[] { new PageUpdate { PageNumber = _freePageHead.PageNumber, Data = BitConverter.GetBytes(pageNumber) } }); return(pageNumber); }
public PageStore(IPageCache pageCache, IStartupLog startUpLog) { _pageCache = pageCache; _startUpLog = startUpLog; _indexPages = new Dictionary <ushort, ulong>(); // The index master page is always page 0 // This page contains the starting page numbers for other indexes _indexHead = _pageCache.Get(null, 0, CacheHints.None); if (_indexHead == null) { startUpLog.WriteLine("Creating a new page store in a set of empty data files from " + _pageCache); _indexHead = _pageCache.NewPage(0); } else { startUpLog.WriteLine("Opening a page store on " + _pageCache); var offset = 0; ushort objectType; ulong startPage; do { objectType = BitConverter.ToUInt16(_indexHead.Data, offset); startPage = BitConverter.ToUInt64(_indexHead.Data, offset + 2); if (objectType > 0) { startUpLog.WriteLine("- the index for type " + objectType + " objects starts at page " + startPage); _indexPages[objectType] = startPage; } else { break; } offset += 10; } while (offset < _indexHead.Data.Length); } // The free page map is always page 1 // This is the first in a chain of pages used to manage // unused space in the file set _freePageHead = _pageCache.Get(null, 1, CacheHints.None); if (_freePageHead == null) { startUpLog.WriteLine("Initializing a new free page map in this page store"); _freePageHead = _pageCache.NewPage(1); _highestPageNumber = 1; _pageCache.Update(null, new[] { new PageUpdate { PageNumber = _freePageHead.PageNumber, Data = BitConverter.GetBytes((ulong)_highestPageNumber) } }); } else { _highestPageNumber = (long)BitConverter.ToUInt64(_freePageHead.Data, 0); startUpLog.WriteLine("This page store contains " + _highestPageNumber + " pages"); } }