/// <summary> /// Read page from disk (dirty, wal or data) /// </summary> private T ReadPage <T>(uint pageID, out FileOrigin origin, out long position, out int walVersion) where T : BasePage { // if not inside local pages can be a dirty page saved in log file if (_transPages.DirtyPages.TryGetValue(pageID, out var walPosition)) { // read page from log file var buffer = _reader.ReadPage(walPosition.Position, _mode == LockMode.Write, FileOrigin.Log); var dirty = BasePage.ReadPage <T>(buffer); origin = FileOrigin.Log; position = walPosition.Position; walVersion = _readVersion; ENSURE(dirty.TransactionID == _transactionID, "this page must came from same transaction"); return(dirty); } // now, look inside wal-index var pos = _walIndex.GetPageIndex(pageID, _readVersion, out walVersion); if (pos != long.MaxValue) { // read page from log file var buffer = _reader.ReadPage(pos, _mode == LockMode.Write, FileOrigin.Log); var logPage = BasePage.ReadPage <T>(buffer); // clear some data inside this page (will be override when write on log file) logPage.TransactionID = 0; logPage.IsConfirmed = false; origin = FileOrigin.Log; position = pos; return(logPage); } else { // for last chance, look inside original disk data file var pagePosition = BasePage.GetPagePosition(pageID); // read page from data file var buffer = _reader.ReadPage(pagePosition, _mode == LockMode.Write, FileOrigin.Data); var diskpage = BasePage.ReadPage <T>(buffer); origin = FileOrigin.Data; position = pagePosition; ENSURE(diskpage.IsConfirmed == false || diskpage.TransactionID != 0, "page are not header-clear in data file"); return(diskpage); } }
/// <summary> /// Read page from stream - do not use cache system /// </summary> private T ReadPage <T>(uint pageID) where T : BasePage { var position = BasePage.GetPagePosition(pageID); _stream.Position = position; _stream.Read(_buffer, 0, PAGE_SIZE); var buffer = new PageBuffer(_buffer, 0, 0); return(BasePage.ReadPage <T>(buffer)); }
/// <summary> /// Read page from stream - do not use cache system /// </summary> private T ReadPage <T>(uint pageID) where T : BasePage { var position = BasePage.GetPagePosition(pageID); if (_cachedPage?.PageID == pageID) { return((T)_cachedPage); } _stream.Position = position; _stream.Read(_buffer, 0, PAGE_SIZE); var buffer = new PageBuffer(_buffer, 0, 0); return((T)(_cachedPage = BasePage.ReadPage <T>(buffer))); }