/// <summary> /// write transaction's raw page data into journal /// </summary> public void Write(LowLevelTransaction tx, CompressedPagesResult pages, LazyTransactionBuffer lazyTransactionScratch, int uncompressedPageCount) { var ptt = new Dictionary <long, PagePosition>(NumericEqualityComparer.Instance); var pageWritePos = _writePage; _unusedPagesHashSetPool.Clear(); UpdatePageTranslationTable(tx, _unusedPagesHashSetPool, ptt); lock (_locker) { _writePage += pages.NumberOfPages; Debug.Assert(!_unusedPages.Any(_unusedPagesHashSetPool.Contains)); _unusedPages.AddRange(_unusedPagesHashSetPool); } _unusedPagesHashSetPool.Clear(); var position = pageWritePos * tx.Environment.Options.PageSize; if (tx.IsLazyTransaction == false && (lazyTransactionScratch == null || lazyTransactionScratch.HasDataInBuffer() == false)) { try { _journalWriter.WritePages(position, pages.Base, pages.NumberOfPages); } catch (Exception e) { _env.CatastrophicFailure = ExceptionDispatchInfo.Capture(e); throw; } } else { if (lazyTransactionScratch == null) { throw new InvalidOperationException("lazyTransactionScratch cannot be null if the transaction is lazy (or a previous one was)"); } lazyTransactionScratch.EnsureSize(_journalWriter.NumberOfAllocatedPages); lazyTransactionScratch.AddToBuffer(position, pages, uncompressedPageCount); // non lazy tx will add itself to the buffer and then flush scratch to journal if (tx.IsLazyTransaction == false || lazyTransactionScratch.NumberOfPages > tx.Environment.ScratchBufferPool.GetAvailablePagesCount() / 2) { try { lazyTransactionScratch.WriteBufferToFile(this, tx); } catch (Exception e) { _env.CatastrophicFailure = ExceptionDispatchInfo.Capture(e); throw; } } else { lazyTransactionScratch.EnsureHasExistingReadTransaction(tx); } } lock (_locker) { _pageTranslationTable.SetItems(tx, ptt); } }