Ejemplo n.º 1
0
        public void AddToBuffer(long position, CompressedPagesResult pages)
        {
            NumberOfPages += pages.NumberOfUncompressedPages;
            if (_firstPositionInJournalFile == null)
            {
                _firstPositionInJournalFile = position; // first lazy tx saves position to all lazy tx that comes afterwards
            }
            using (var writer = _lazyTransactionPager.BatchWriter())
            {
                writer.Write(_lastUsed4Kbs,
                             pages.NumberOf4Kbs,
                             pages.Base);
            }

            _lastUsed4Kbs += pages.NumberOf4Kbs;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// write transaction's raw page data into journal
        /// </summary>
        public UpdatePageTranslationTableAndUnusedPagesAction Write(LowLevelTransaction tx, CompressedPagesResult pages, LazyTransactionBuffer lazyTransactionScratch)
        {
            var ptt       = new Dictionary <long, PagePosition>(NumericEqualityComparer.BoxedInstanceInt64);
            var cur4KbPos = _writePosIn4Kb;

            Debug.Assert(pages.NumberOf4Kbs > 0);

            UpdatePageTranslationTable(tx, _unusedPagesHashSetPool, ptt);

            if (tx.IsLazyTransaction == false && (lazyTransactionScratch == null || lazyTransactionScratch.HasDataInBuffer() == false))
            {
                try
                {
                    Write(cur4KbPos, pages.Base, pages.NumberOf4Kbs);
                }
                catch (Exception e)
                {
                    _env.Options.SetCatastrophicFailure(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)");
                }

                var sizeInBytes = _journalWriter.NumberOfAllocated4Kb * 4 * Constants.Size.Kilobyte;

                int sizeInPages = checked (sizeInBytes / Constants.Storage.PageSize +
                                           sizeInBytes % Constants.Storage.PageSize == 0 ? 0 : 1);

                lazyTransactionScratch.EnsureSize(sizeInPages);
                lazyTransactionScratch.AddToBuffer(cur4KbPos, pages);

                // 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.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e));
                        throw;
                    }
                }
                else
                {
                    lazyTransactionScratch.EnsureHasExistingReadTransaction(tx);
                }
            }

            return(new UpdatePageTranslationTableAndUnusedPagesAction(this, tx, ptt, pages.NumberOf4Kbs));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// write transaction's raw page data into journal
        /// </summary>
        public void Write(LowLevelTransaction tx, CompressedPagesResult pages, LazyTransactionBuffer lazyTransactionScratch)
        {
            var ptt       = new Dictionary <long, PagePosition>(NumericEqualityComparer.Instance);
            var cur4KbPos = _writePosIn4Kb;

            Debug.Assert(pages.NumberOf4Kbs > 0);

            UpdatePageTranslationTable(tx, _unusedPagesHashSetPool, ptt);

            using (_locker2.Lock())
            {
                _writePosIn4Kb += pages.NumberOf4Kbs;

                Debug.Assert(!_unusedPages.Any(_unusedPagesHashSetPool.Contains)); // We ensure there cannot be duplicates here (disjoint sets).

                foreach (var item in _unusedPagesHashSetPool)
                {
                    _unusedPages.Add(item);
                }
            }
            _unusedPagesHashSetPool.Clear();

            if (tx.IsLazyTransaction == false && (lazyTransactionScratch == null || lazyTransactionScratch.HasDataInBuffer() == false))
            {
                try
                {
                    _journalWriter.Write(cur4KbPos, pages.Base, pages.NumberOf4Kbs);
                }
                catch (Exception e)
                {
                    _env.Options.SetCatastrophicFailure(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.NumberOfAllocated4Kb);
                lazyTransactionScratch.AddToBuffer(cur4KbPos, pages);

                // 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.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e));
                        throw;
                    }
                }
                else
                {
                    lazyTransactionScratch.EnsureHasExistingReadTransaction(tx);
                }
            }

            using (_locker2.Lock())
            {
                _pageTranslationTable.SetItems(tx, ptt);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// write transaction's raw page data into journal
        /// </summary>
        public void Write(LowLevelTransaction tx, CompressedPagesResult pages, LazyTransactionBuffer lazyTransactionScratch)
        {
            var ptt       = new Dictionary <long, PagePosition>(NumericEqualityComparer.BoxedInstanceInt64);
            var cur4KbPos = _writePosIn4Kb;

            Debug.Assert(pages.NumberOf4Kbs > 0);

            UpdatePageTranslationTable(tx, _unusedPagesHashSetPool, ptt);

            using (_locker2.Lock())
            {
                Debug.Assert(!_unusedPages.Any(_unusedPagesHashSetPool.Contains)); // We ensure there cannot be duplicates here (disjoint sets).

                foreach (var item in _unusedPagesHashSetPool)
                {
                    _unusedPages.Add(item);
                }
            }
            _unusedPagesHashSetPool.Clear();

            if (tx.IsLazyTransaction == false && (lazyTransactionScratch == null || lazyTransactionScratch.HasDataInBuffer() == false))
            {
                try
                {
                    _journalWriter.Write(cur4KbPos, pages.Base, pages.NumberOf4Kbs);
                }
                catch (Exception e)
                {
                    _env.Options.SetCatastrophicFailure(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.NumberOfAllocated4Kb);
                lazyTransactionScratch.AddToBuffer(cur4KbPos, pages);

                // 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.Options.SetCatastrophicFailure(ExceptionDispatchInfo.Capture(e));
                        throw;
                    }
                }
                else
                {
                    lazyTransactionScratch.EnsureHasExistingReadTransaction(tx);
                }
            }

            using (_locker2.Lock())
            {
                _pageTranslationTable.SetItems(tx, ptt);
                // it is important that the last write position will be set
                // _after_ the PTT update, because a flush that is concurrent
                // with the write will first get the WritePosIn4KB and then
                // do the flush based on the PTT. Worst case, we'll flush
                // more then we need, but won't get into a position where we
                // think we flushed, and then realize that we didn't.
                Interlocked.Add(ref _writePosIn4Kb, pages.NumberOf4Kbs);
            }
        }
Ejemplo n.º 5
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);
            }
        }