public Page GetReadOnlyPage(long pageNumber) { Page p; PageFromScratchBuffer value; if (_scratchPagesTable.TryGetValue(pageNumber, out value)) { PagerState state = null; if (_scratchPagerStates != null) { var lastUsed = lastScratchFileUsed; if (lastUsed.FileNumber == value.ScratchFileNumber) { state = lastUsed.State; } else { state = _scratchPagerStates[value.ScratchFileNumber]; lastScratchFileUsed = new PagerStateCacheItem(value.ScratchFileNumber, state); } } p = _env.ScratchBufferPool.ReadPage(value.ScratchFileNumber, value.PositionInScratchBuffer, state); } else { p = _journal.ReadPage(this, pageNumber, _scratchPagerStates) ?? _dataPager.Read(pageNumber); } Debug.Assert(p != null && p.PageNumber == pageNumber, string.Format("Requested ReadOnly page #{0}. Got #{1} from {2}", pageNumber, p.PageNumber, p.Source)); return(p); }
public static Dictionary <long, JournalFile.PagePosition> GetTransactionToPageTranslation(this TransactionHeader current, IVirtualPager pager, ref int currentPage) { var tempTransactionPageTranslaction = new Dictionary <long, JournalFile.PagePosition>(); for (var i = 0; i < current.PageCount; i++) { Debug.Assert(pager.Disposed == false); var page = pager.Read(currentPage); tempTransactionPageTranslaction[page.PageNumber] = new JournalFile.PagePosition { JournalPos = currentPage, TransactionId = current.TransactionId }; if (page.IsOverflow) { var numOfPages = pager.GetNumberOfOverflowPages(page.OverflowSize); currentPage += numOfPages; } else { currentPage++; } } return(tempTransactionPageTranslaction); }
public void ReadTransactions(IEnumerable <TransactionToShip> shippedTransactions) { foreach (var transaction in shippedTransactions.OrderBy(x => x.Header.TransactionId)) { ReadFromShippedTransaction(transaction); } var pageData = new byte *[_pageNumbers.Count]; _pageNumbers.ForEach(pageNumber => pageData[pageNumber] = _pager.Read(pageNumber).Base); RawPageData = pageData; }
public Page GetReadOnlyPage(long pageNumber) { PageFromScratchBuffer value; Page p; if (_scratchPagesTable.TryGetValue(pageNumber, out value)) { p = _env.ScratchBufferPool.ReadPage(value.ScratchFileNumber, value.PositionInScratchBuffer, _scratchPagerStates != null ? _scratchPagerStates[value.ScratchFileNumber] : null); } else { p = _journal.ReadPage(this, pageNumber, _scratchPagerStates) ?? _dataPager.Read(pageNumber); } Debug.Assert(p != null && p.PageNumber == pageNumber, string.Format("Requested ReadOnly page #{0}. Got #{1} from {2}", pageNumber, p.PageNumber, p.Source)); return(p); }
private bool TryReadAndValidateHeader(StorageEnvironmentOptions options, out TransactionHeader *current) { current = (TransactionHeader *)_pager.Read(_readingPage).Base; if (current->HeaderMarker != Constants.TransactionHeaderMarker) { // not a transaction page, // if the header marker is zero, we are probably in the area at the end of the log file, and have no additional log records // to read from it. This can happen if the next transaction was too big to fit in the current log file. We stop reading // this log file and move to the next one. RequireHeaderUpdate = current->HeaderMarker != 0; if (RequireHeaderUpdate) { options.InvokeRecoveryError(this, "Transaction " + current->TransactionId + " header marker was set to garbage value, file is probably corrupted", null); } return(false); } ValidateHeader(current, LastTransactionHeader); if (current->TxMarker.HasFlag(TransactionMarker.Commit) == false) { // uncommitted transaction, probably RequireHeaderUpdate = true; options.InvokeRecoveryError(this, "Transaction " + current->TransactionId + " was not committed", null); return(false); } _readingPage++; return(true); }
public Page ReadPage(long p, PagerState pagerState = null) { return(_scratchPager.Read(p, pagerState)); }
public bool ReadOneTransaction(StorageEnvironmentOptions options, bool checkCrc = true) { if (_readingPage >= _pager.NumberOfAllocatedPages) { return(false); } if (MaxPageToRead != null && _readingPage >= MaxPageToRead.Value) { return(false); } TransactionHeader *current; if (!TryReadAndValidateHeader(options, out current)) { return(false); } var transactionSize = GetNumberOfPagesFromSize(current->Compressed ? current->CompressedSize : current->UncompressedSize); if (current->TransactionId <= _lastSyncedTransactionId) { LastTransactionHeader = current; _readingPage += transactionSize; return(true); // skipping } if (checkCrc && !ValidatePagesCrc(options, transactionSize, current)) { return(false); } _recoveryPager.EnsureContinuous(null, _recoveryPage, (current->PageCount + current->OverflowPageCount) + 1); var dataPage = _recoveryPager.AcquirePagePointer(_recoveryPage); UnmanagedMemory.Set(dataPage, 0, (current->PageCount + current->OverflowPageCount) * AbstractPager.PageSize); if (current->Compressed) { if (TryDecompressTransactionPages(options, current, dataPage) == false) { return(false); } } else { Memory.Copy(dataPage, _pager.AcquirePagePointer(_readingPage), (current->PageCount + current->OverflowPageCount) * AbstractPager.PageSize); } var tempTransactionPageTranslaction = new Dictionary <long, RecoveryPagePosition>(); for (var i = 0; i < current->PageCount; i++) { Debug.Assert(_pager.Disposed == false); Debug.Assert(_recoveryPager.Disposed == false); var page = _recoveryPager.Read(_recoveryPage); var pagePosition = new RecoveryPagePosition { JournalPos = _recoveryPage, TransactionId = current->TransactionId }; if (page.IsOverflow) { var numOfPages = _recoveryPager.GetNumberOfOverflowPages(page.OverflowSize); pagePosition.IsOverflow = true; pagePosition.NumberOfOverflowPages = numOfPages; _recoveryPage += numOfPages; } else { _recoveryPage++; } tempTransactionPageTranslaction[page.PageNumber] = pagePosition; } _readingPage += transactionSize; LastTransactionHeader = current; foreach (var pagePosition in tempTransactionPageTranslaction) { _transactionPageTranslation[pagePosition.Key] = pagePosition.Value; if (pagePosition.Value.IsOverflow) { Debug.Assert(pagePosition.Value.NumberOfOverflowPages != -1); for (int i = 1; i < pagePosition.Value.NumberOfOverflowPages; i++) { _transactionPageTranslation.Remove(pagePosition.Key + i); } } } return(true); }
public Page ReadPage(Transaction tx, long p, PagerState pagerState = null) { return(_scratchPager.Read(tx, p, pagerState)); }
public bool ReadOneTransaction(StorageEnvironmentOptions options, bool checkCrc = true) { if (_readingPage >= _pager.NumberOfAllocatedPages) { return(false); } TransactionHeader *current; if (!TryReadAndValidateHeader(options, out current)) { return(false); } var compressedPages = (current->CompressedSize / AbstractPager.PageSize) + (current->CompressedSize % AbstractPager.PageSize == 0 ? 0 : 1); if (current->TransactionId <= _lastSyncedTransactionId) { LastTransactionHeader = current; _readingPage += compressedPages; return(true); // skipping } if (checkCrc) { uint crc = Crc.Value(_pager.AcquirePagePointer(_readingPage), 0, compressedPages * AbstractPager.PageSize); if (crc != current->Crc) { RequireHeaderUpdate = true; options.InvokeRecoveryError(this, "Invalid CRC signature for transaction " + current->TransactionId, null); return(false); } } _recoveryPager.EnsureContinuous(null, _recoveryPage, (current->PageCount + current->OverflowPageCount) + 1); var dataPage = _recoveryPager.AcquirePagePointer(_recoveryPage); NativeMethods.memset(dataPage, 0, (current->PageCount + current->OverflowPageCount) * AbstractPager.PageSize); try { LZ4.Decode64(_pager.AcquirePagePointer(_readingPage), current->CompressedSize, dataPage, current->UncompressedSize, true); } catch (Exception e) { options.InvokeRecoveryError(this, "Could not de-compress, invalid data", e); RequireHeaderUpdate = true; return(false); } var tempTransactionPageTranslaction = new Dictionary <long, JournalFile.PagePosition>(); for (var i = 0; i < current->PageCount; i++) { Debug.Assert(_pager.Disposed == false); Debug.Assert(_recoveryPager.Disposed == false); var page = _recoveryPager.Read(_recoveryPage); tempTransactionPageTranslaction[page.PageNumber] = new JournalFile.PagePosition { JournalPos = _recoveryPage, TransactionId = current->TransactionId }; if (page.IsOverflow) { var numOfPages = _recoveryPager.GetNumberOfOverflowPages(page.OverflowSize); _recoveryPage += numOfPages; } else { _recoveryPage++; } } _readingPage += compressedPages; LastTransactionHeader = current; foreach (var pagePosition in tempTransactionPageTranslaction) { _transactionPageTranslation[pagePosition.Key] = pagePosition.Value; } return(true); }