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); }
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(); }