예제 #1
0
        /// <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);
            }
        }