public async Task Add(RowHolder item, ITransaction tran) { MixedPage currPage = null; for (ulong currPageId = this.lastPageId; currPageId != PageManagerConstants.NullPageId; currPageId = currPage.NextPageId()) { using Releaser lck = await tran.AcquireLock(currPageId, LockManager.LockTypeEnum.Shared).ConfigureAwait(false); currPage = await pageAllocator.GetMixedPage(currPageId, tran, this.columnTypes).ConfigureAwait(false); if (currPage.CanFit(item, tran)) { lck.Dispose(); using Releaser writeLock = await tran.AcquireLock(currPageId, LockManager.LockTypeEnum.Exclusive).ConfigureAwait(false); // Need to check can fit one more time. if (currPage.CanFit(item, tran)) { currPage.Insert(item, tran); return; } } } { using Releaser prevPageLck = await tran.AcquireLock(currPage.PageId(), LockManager.LockTypeEnum.Exclusive).ConfigureAwait(false); if (currPage.NextPageId() != PageManagerConstants.NullPageId) { // TODO: it would be good if caller had ability to control this lock. // This dispose doesn't mean anything in current implementation of read committed. prevPageLck.Dispose(); await Add(item, tran).ConfigureAwait(false); } else { currPage = await this.pageAllocator.AllocateMixedPage(this.columnTypes, currPage.PageId(), PageManagerConstants.NullPageId, tran).ConfigureAwait(false); using Releaser currPageLck = await tran.AcquireLock(currPage.PageId(), LockManager.LockTypeEnum.Exclusive).ConfigureAwait(false); this.lastPageId = currPage.PageId(); currPage.Insert(item, tran); } } }
public static void NullifyMixedPage(MixedPage page, ITransaction tran) { for (int i = 0; i < page.MaxRowCount(); i++) { RowHolder rhf = new RowHolder(new ColumnType[] { ColumnType.Int }); rhf.SetField <int>(0, 0); page.Insert(rhf, tran); } }