Beispiel #1
0
        public void WriteToJournal(Transaction tx, int pageCount)
        {
            var pages = CompressPages(tx, pageCount, _compressionPager, Shipper.PreviousTransactionCrc);

            if (CurrentFile == null || CurrentFile.AvailablePages < pages.Length)
            {
                CurrentFile = NextFile(pages.Length);
            }

            CurrentFile.Write(tx, pages);

            var transactionHeader = *(TransactionHeader *)pages[0];

            var onTransactionCommit = OnTransactionCommit;

            if (onTransactionCommit != null)
            {
                var transactionToShip = new TransactionToShip(transactionHeader)
                {
                    CompressedPages = pages
                };

                onTransactionCommit(transactionToShip);
            }

            Shipper.SetPreviousTransaction(transactionHeader.TransactionId, transactionHeader.Crc);

            if (CurrentFile.AvailablePages == 0)
            {
                CurrentFile = null;
            }
        }
Beispiel #2
0
        protected bool ReadOneTransactionForShipping(StorageEnvironmentOptions options, out TransactionToShip transactionToShipRecord)
        {
            transactionToShipRecord = null;
            if (_readingPage >= _pager.NumberOfAllocatedPages)
            {
                return(false);
            }

            TransactionHeader *current;

            if (!TryReadAndValidateHeader(options, out current))
            {
                return(false);
            }

            var compressedPageCount = (current->CompressedSize / AbstractPager.PageSize) + (current->CompressedSize % AbstractPager.PageSize == 0 ? 0 : 1);

            if (current->TransactionId <= _lastSyncedTransactionId)
            {
                LastTransactionHeader = current;
                _readingPage         += compressedPageCount;
                return(true);                // skipping
            }

            if (!ValidatePagesCrc(options, compressedPageCount, current))
            {
                return(false);
            }

            var compressedPagesRaw = new byte[compressedPageCount * AbstractPager.PageSize];

            fixed(byte *compressedDataPtr = compressedPagesRaw)
            NativeMethods.memcpy(compressedDataPtr, _pager.AcquirePagePointer(_readingPage), compressedPageCount * AbstractPager.PageSize);

            transactionToShipRecord = new TransactionToShip(*current)
            {
                CompressedData         = new MemoryStream(compressedPagesRaw),         //no need to compress the pages --> after being written to Journal they are already compressed
                PreviousTransactionCrc = _previousTransactionCrc
            };

            _previousTransactionCrc = current->Crc;

            _readingPage += compressedPageCount;
            return(true);
        }
Beispiel #3
0
        protected void ReadFromShippedTransaction(TransactionToShip transaction)
        {
            var compressedPages      = (transaction.Header.CompressedSize / AbstractPager.PageSize) + (transaction.Header.CompressedSize % AbstractPager.PageSize == 0 ? 0 : 1);
            var compressedDataBuffer = new byte[compressedPages * AbstractPager.PageSize];

            transaction.CompressedData.Read(compressedDataBuffer, 0, compressedPages * AbstractPager.PageSize);

            fixed(byte *compressedDataBufferPtr = compressedDataBuffer)
            {
                var crc = Crc.Value(compressedDataBufferPtr, 0, compressedPages * AbstractPager.PageSize);

                if (transaction.Header.Crc != crc || _previousTransactionCrc != transaction.PreviousTransactionCrc)
                {
                    throw new InvalidDataException("Invalid CRC signature for transaction " + transaction.Header.TransactionId);
                }

                _previousTransactionCrc = crc;
                var totalPages = transaction.Header.PageCount + transaction.Header.OverflowPageCount;

                _pager.EnsureContinuous(null, currentPage, totalPages + 1);
                try
                {
                    LZ4.Decode64(compressedDataBufferPtr, transaction.Header.CompressedSize, _pager.AcquirePagePointer(currentPage), transaction.Header.UncompressedSize, true);
                }
                catch (Exception e)
                {
                    throw new InvalidDataException("Could not de-compress, invalid data", e);
                }
            }

            var lastAddedPage = currentPage + transaction.Header.PageCount;

            for (int pageNumber = currentPage; pageNumber < lastAddedPage; pageNumber++)
            {
                _pageNumbers.Add(pageNumber);
            }

            if (LastTransactionHeader.HasValue && LastTransactionHeader.Value.TransactionId < transaction.Header.TransactionId)
            {
                LastTransactionHeader = transaction.Header;
            }

            currentPage = lastAddedPage;
        }
        public void WriteToJournal(Transaction tx, int pageCount)
        {
            var pages = CompressPages(tx, pageCount, _compressionPager);

            if (CurrentFile == null || CurrentFile.AvailablePages < pages.Length)
            {
                CurrentFile = NextFile(pages.Length);
            }

            var transactionHeader = *(TransactionHeader *)pages[0];

            var writePage = CurrentFile.Write(tx, pages);

            var onTransactionCommit = OnTransactionCommit;

            if (onTransactionCommit != null)
            {
                var bufferSize = pages.Length * AbstractPager.PageSize;
                var buffer     = new byte[bufferSize];

                fixed(byte *bp = buffer)
                CurrentFile.JournalWriter.Read(writePage, bp, bufferSize);

                var stream            = new MemoryStream(buffer, AbstractPager.PageSize, (pages.Length - 1) * AbstractPager.PageSize);
                var transactionToShip = new TransactionToShip(transactionHeader)
                {
                    CompressedData         = stream,
                    PreviousTransactionCrc = _previousTransactionCrc
                };

                _previousTransactionCrc = transactionHeader.Crc;
                onTransactionCommit(transactionToShip);
            }

            if (CurrentFile.AvailablePages == 0)
            {
                CurrentFile = null;
            }
        }
Beispiel #5
0
		public void WriteToJournal(Transaction tx, int pageCount)
		{
			var pages = CompressPages(tx, pageCount, _compressionPager, Shipper.PreviousTransactionCrc);

			if (CurrentFile == null || CurrentFile.AvailablePages < pages.Length)
			{
				CurrentFile = NextFile(pages.Length);
			}

			CurrentFile.Write(tx, pages);

			var transactionHeader = *(TransactionHeader*)pages[0];

			var onTransactionCommit = OnTransactionCommit;
			if (onTransactionCommit != null)
			{
				var transactionToShip = new TransactionToShip(transactionHeader)
				{
					CompressedPages = pages
				};

				onTransactionCommit(transactionToShip);
			}

			Shipper.SetPreviousTransaction(transactionHeader.TransactionId, transactionHeader.Crc);

			if (CurrentFile.AvailablePages == 0)
				CurrentFile = null;
		}