Beispiel #1
0
        public MetadataManager(IPageManager pageAllocator, HeapWithOffsets <char[]> stringHeap, IBootPageAllocator bootPageAllocator, ILogManager logManager)
        {
            this.pageAllocator = pageAllocator;
            this.stringHeap    = stringHeap;
            this.logManager    = logManager;

            if (!bootPageAllocator.BootPageInitialized())
            {
                using (ITransaction tran = this.logManager.CreateTransaction(this.pageAllocator, false, "GET_BOOT_PAGE"))
                    using (Releaser releaser = tran.AcquireLock(IBootPageAllocator.BootPageId, LockManager.LockTypeEnum.Exclusive).Result)
                    {
                        bootPageAllocator.AllocatePageBootPage(PageType.MixedPage, this.masterPageColumnDefinition, tran);
                        this.masterMetadataCollection = new PageListCollection(this.pageAllocator, this.masterPageColumnDefinition, IBootPageAllocator.BootPageId);
                        tran.Commit();
                    }

                MetadataInitialSetup();
            }
            else
            {
                using (ITransaction tran = this.logManager.CreateTransaction(this.pageAllocator, false, "GET_BOOT_PAGE"))
                {
                    using Releaser releaser       = tran.AcquireLock(IBootPageAllocator.BootPageId, LockManager.LockTypeEnum.Exclusive).Result;
                    this.masterMetadataCollection = new PageListCollection(this.pageAllocator, this.masterPageColumnDefinition, IBootPageAllocator.BootPageId);
                    tran.Commit();
                }
            }
        }
Beispiel #2
0
        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);
                }
            }
        }
Beispiel #3
0
        public async Task <char[]> Fetch(PagePointerOffsetPair loc, ITransaction tran)
        {
            using Releaser lckReleaser = await tran.AcquireLock((ulong) loc.PageId, LockManager.LockTypeEnum.Shared).ConfigureAwait(false);

            StringOnlyPage page = await allocator.GetPageStr((ulong)loc.PageId, tran).ConfigureAwait(false);

            return(page.FetchWithOffset((uint)loc.OffsetInPage, tran));
        }
Beispiel #4
0
        public async Task <PagePointerOffsetPair> Add(char[] item, ITransaction tran)
        {
            StringOnlyPage currPage = null;
            int            offset;

            for (ulong currPageId = this.lastPageId; currPageId != PageManagerConstants.NullPageId; currPageId = currPage.NextPageId())
            {
                using Releaser lckReleaser = await tran.AcquireLock(currPageId, LockManager.LockTypeEnum.Shared).ConfigureAwait(false);

                currPage = await allocator.GetPageStr(currPageId, tran).ConfigureAwait(false);

                if (currPage.CanFit(item))
                {
                    lckReleaser.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))
                    {
                        offset = currPage.Insert(item, tran);
                        return(new PagePointerOffsetPair((long)currPage.PageId(), (int)offset));
                    }
                }
            }

            {
                using Releaser prevPage = await tran.AcquireLock(currPage.PageId(), LockManager.LockTypeEnum.Exclusive).ConfigureAwait(false);

                if (currPage.NextPageId() != PageManagerConstants.NullPageId)
                {
                    prevPage.Dispose();
                    return(await Add(item, tran).ConfigureAwait(false));
                }
                else
                {
                    currPage = await this.allocator.AllocatePageStr(currPage.PageId(), PageManagerConstants.NullPageId, tran).ConfigureAwait(false);

                    using Releaser lckReleaser = await tran.AcquireLock(currPage.PageId(), LockManager.LockTypeEnum.Exclusive).ConfigureAwait(false);

                    offset          = currPage.Insert(item, tran);
                    this.lastPageId = currPage.PageId();
                    return(new PagePointerOffsetPair((long)currPage.PageId(), (int)offset));
                }
            }
        }
Beispiel #5
0
        public async IAsyncEnumerable <RowHolder> Iterate(ITransaction tran)
        {
            MixedPage currPage;

            for (ulong currPageId = collectionRootPageId; 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);

                foreach (RowHolder rhf in currPage.Fetch(tran))
                {
                    yield return(rhf);
                }
            }
        }
Beispiel #6
0
        public async Task <ulong> Count(ITransaction tran)
        {
            ulong rowCount = 0;

            IPage currPage;

            for (ulong currPageId = collectionRootPageId; 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);

                rowCount += currPage.RowCount();
            }

            return(rowCount);
        }
Beispiel #7
0
        public async Task <U> Max <U>(Func <RowHolder, U> projector, U startMin, ITransaction tran) where U : IComparable
        {
            MixedPage currPage;
            U         max = startMin;

            for (ulong currPageId = collectionRootPageId; 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);

                foreach (RowHolder rhf in currPage.Fetch(tran))
                {
                    U curr = projector(rhf);
                    if (curr.CompareTo(max) == 1)
                    {
                        max = curr;
                    }
                }
            }

            return(max);
        }