private IntPtr[] CompressPages(Transaction tx, int numberOfPages, IVirtualPager compressionPager, uint previousTransactionCrc) { // numberOfPages include the tx header page, which we don't compress var dataPagesCount = numberOfPages - 1; var sizeInBytes = dataPagesCount * AbstractPager.PageSize; var outputBuffer = LZ4.MaximumOutputLength(sizeInBytes); var outputBufferInPages = outputBuffer / AbstractPager.PageSize + (outputBuffer % AbstractPager.PageSize == 0 ? 0 : 1); var pagesRequired = (dataPagesCount + outputBufferInPages); compressionPager.EnsureContinuous(tx, 0, pagesRequired); var tempBuffer = compressionPager.AcquirePagePointer(0); var compressionBuffer = compressionPager.AcquirePagePointer(dataPagesCount); var write = tempBuffer; var txPages = tx.GetTransactionPages(); foreach (var txPage in txPages) { var scratchPage = tx.Environment.ScratchBufferPool.AcquirePagePointer(txPage.ScratchFileNumber, txPage.PositionInScratchBuffer); var count = txPage.NumberOfPages * AbstractPager.PageSize; MemoryUtils.BulkCopy(write, scratchPage, count); write += count; } var len = DoCompression(tempBuffer, compressionBuffer, sizeInBytes, outputBuffer); var remainder = len % AbstractPager.PageSize; var compressedPages = (len / AbstractPager.PageSize) + (remainder == 0 ? 0 : 1); if (remainder != 0) { // zero the remainder of the page StdLib.memset(compressionBuffer + len, 0, remainder); } var pages = new IntPtr[compressedPages + 1]; var txHeaderPage = tx.GetTransactionHeaderPage(); var txHeaderBase = tx.Environment.ScratchBufferPool.AcquirePagePointer(txHeaderPage.ScratchFileNumber, txHeaderPage.PositionInScratchBuffer); var txHeader = (TransactionHeader *)txHeaderBase; txHeader->Compressed = true; txHeader->CompressedSize = len; txHeader->UncompressedSize = sizeInBytes; txHeader->PreviousTransactionCrc = previousTransactionCrc; pages[0] = new IntPtr(txHeaderBase); for (int index = 0; index < compressedPages; index++) { pages[index + 1] = new IntPtr(compressionBuffer + (index * AbstractPager.PageSize)); } txHeader->Crc = Crc.Value(compressionBuffer, 0, compressedPages * AbstractPager.PageSize); return(pages); }
public override int WriteDirect(Page start, long pagePosition, int pagesToWrite) { ThrowObjectDisposedIfNeeded(); int toCopy = pagesToWrite * PageSize; MemoryUtils.BulkCopy(PagerState.MapBase + pagePosition * PageSize, start.Base, toCopy); return(toCopy); }