예제 #1
0
        internal Page ModifyPage(long num)
        {
            _env.AssertNoCatastrophicFailure();

            // Check if we can hit the lowest level locality cache.
            Page currentPage = GetPage(num);

            if (_dirtyPages.Contains(num))
            {
                return(currentPage);
            }

            int  pageSize;
            Page newPage;

            if (currentPage.IsOverflow)
            {
                newPage  = AllocateOverflowRawPage(currentPage.OverflowSize, num, currentPage, zeroPage: false);
                pageSize = Environment.Options.PageSize *
                           DataPager.GetNumberOfOverflowPages(currentPage.OverflowSize);
            }
            else
            {
                newPage  = AllocatePage(1, num, currentPage, zeroPage: false); // allocate new page in a log file but with the same number
                pageSize = Environment.Options.PageSize;
            }

            Memory.BulkCopy(newPage.Pointer, currentPage.Pointer, pageSize);

            TrackWritablePage(newPage);

            return(newPage);
        }
예제 #2
0
        public LowLevelTransaction(StorageEnvironment env, long id, TransactionPersistentContext transactionPersistentContext, TransactionFlags flags, IFreeSpaceHandling freeSpaceHandling, ByteStringContext context = null)
        {
            env.AssertNoCatastrophicFailure();

            DataPager          = env.Options.DataPager;
            _env               = env;
            _journal           = env.Journal;
            _id                = id;
            _freeSpaceHandling = freeSpaceHandling;
            _allocator         = context ?? new ByteStringContext();
            _disposeAllocator  = context == null;
            _pagerStates       = new HashSet <PagerState>(ReferenceEqualityComparer <PagerState> .Default);

            PersistentContext = transactionPersistentContext;
            Flags             = flags;

            PageSize = DataPager.PageSize;

            var scratchPagerStates = env.ScratchBufferPool.GetPagerStatesOfAllScratches();

            foreach (var scratchPagerState in scratchPagerStates.Values)
            {
                scratchPagerState.AddRef();
                _pagerStates.Add(scratchPagerState);
            }

            if (flags != TransactionFlags.ReadWrite)
            {
                // for read transactions, we need to keep the pager state frozen
                // for write transactions, we can use the current one (which == null)
                _scratchPagerStates = scratchPagerStates;

                _state = env.State.Clone();

                InitializeRoots();

                JournalSnapshots = _journal.GetSnapshots();

                return;
            }

            EnsureNoDuplicateTransactionId(id);

            _env.WriteTransactionPool.Reset();
            _dirtyOverflowPages  = _env.WriteTransactionPool.DirtyOverflowPagesPool;
            _scratchPagesTable   = _env.WriteTransactionPool.ScratchPagesTablePool;
            _dirtyPages          = _env.WriteTransactionPool.DirtyPagesPool;
            _freedPages          = new HashSet <long>(NumericEqualityComparer.Instance);
            _unusedScratchPages  = new List <PageFromScratchBuffer>();
            _transactionPages    = new HashSet <PageFromScratchBuffer>(PageFromScratchBufferEqualityComparer.Instance);
            _pagesToFreeOnCommit = new Stack <long>();

            _state = env.State.Clone();
            InitializeRoots();
            InitTransactionHeader();
        }