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 async Task <int> CreateObject(TableCreateDefinition def, ITransaction tran) { if (await this.Exists(def, tran)) { throw new ElementWithSameNameExistsException(); } if (def.ColumnNames.Length != def.ColumnTypes.Length) { throw new ArgumentException(); } int id = 1; if (!(await pageListCollection.IsEmpty(tran))) { int maxId = await pageListCollection.Max <int>(rh => rh.GetField <int>(0), startMin : 0, tran); id = maxId + 1; } MixedPage rootPage = await this.pageAllocator.AllocateMixedPage(def.ColumnTypes, PageManagerConstants.NullPageId, PageManagerConstants.NullPageId, tran); RowHolder rh = new RowHolder(columnDefinitions); PagePointerOffsetPair namePointer = await this.stringHeap.Add(def.TableName.ToCharArray(), tran); rh.SetField <int>(0, id); rh.SetField <PagePointerOffsetPair>(1, namePointer); rh.SetField <long>(2, (long)rootPage.PageId()); await pageListCollection.Add(rh, tran); for (int i = 0; i < def.ColumnNames.Length; i++) { ColumnCreateDefinition ccd = new ColumnCreateDefinition(id, def.ColumnNames[i], def.ColumnTypes[i], i); await columnManager.CreateObject(ccd, tran); } return(id); }
private void MetadataInitialSetup() { using ITransaction tran = this.logManager.CreateTransaction(this.pageAllocator, false, "MetadataSetup"); MixedPage mdColumnsFirstPage = this.pageAllocator.AllocateMixedPage(MetadataColumnsManager.GetSchemaDefinition(), PageManagerConstants.NullPageId, PageManagerConstants.NullPageId, tran).Result; this.columnsManager = new MetadataColumnsManager(this.pageAllocator, mdColumnsFirstPage, this.stringHeap); MixedPage mdTableFirstPage = this.pageAllocator.AllocateMixedPage(MetadataTablesManager.GetSchemaDefinition(), PageManagerConstants.NullPageId, PageManagerConstants.NullPageId, tran).Result; this.tableManager = new MetadataTablesManager(this.pageAllocator, mdTableFirstPage, this.stringHeap, this.columnsManager); RowHolder rhf = new RowHolder(this.masterPageColumnDefinition); rhf.SetField <int>(0, (int)MetadataObjectEnum.MdTableId); rhf.SetField <long>(1, (long)mdTableFirstPage.PageId()); masterMetadataCollection.Add(rhf, tran).Wait(); rhf.SetField <int>(0, (int)MetadataObjectEnum.MdColumnId); rhf.SetField <long>(1, (long)mdColumnsFirstPage.PageId()); masterMetadataCollection.Add(rhf, tran).Wait(); tran.Commit().Wait(); }
public MetadataTablesManager(IAllocateMixedPage pageAllocator, MixedPage firstPage, HeapWithOffsets <char[]> stringHeap, IMetadataObjectManager <MetadataColumn, ColumnCreateDefinition, Tuple <int, int> > columnManager) { if (pageAllocator == null || firstPage == null || columnManager == null) { throw new ArgumentNullException(); } this.pageListCollection = new PageListCollection(pageAllocator, columnDefinitions, firstPage.PageId()); this.stringHeap = stringHeap; this.columnManager = columnManager; this.pageAllocator = pageAllocator; }
public MetadataColumnsManager(IAllocateMixedPage pageAllocator, MixedPage firstPage, HeapWithOffsets <char[]> stringHeap) { if (pageAllocator == null || firstPage == null) { throw new ArgumentNullException(); } this.pageListCollection = new PageListCollection(pageAllocator, columnDefinitions, firstPage.PageId()); this.stringHeap = stringHeap; }