示例#1
0
        /// <summary>
        /// Create a new index and returns head page address (skip list)
        /// </summary>
        public CollectionIndex CreateIndex(CollectionIndex index)
        {
            // get a new index page for first index page
            var page = _pager.NewPage <IndexPage>();

            // create a empty node with full max level
            var node = new IndexNode(IndexNode.MAX_LEVEL_LENGTH)
            {
                Key = new IndexKey(null), Page = page
            };

            node.Position = new PageAddress(page.PageID, 0);

            // add as first node
            page.Nodes.Add(node.Position.Index, node);

            // add indexPage on freelist if has space
            _pager.AddOrRemoveToFreeList(true, page, index.Page, ref index.FreeIndexPageID);

            // point the head node to this new node position
            index.HeadNode = node.Position;

            index.Page.IsDirty = true;
            page.IsDirty       = true;

            return(index);
        }
示例#2
0
        /// <summary>
        /// Insert data inside a datapage. Returns dataPageID that indicates the first page
        /// </summary>
        public DataBlock Insert(CollectionPage col, byte[] data)
        {
            // need to extend (data is bigger than 1 page)
            var extend = (data.Length + DataBlock.DATA_BLOCK_FIXED_SIZE) > BasePage.PAGE_AVAILABLE_BYTES;

            // if extend, just search for a page with BLOCK_SIZE available
            var dataPage = _pager.GetFreePage <DataPage>(col.FreeDataPageID, extend ? DataBlock.DATA_BLOCK_FIXED_SIZE : data.Length + DataBlock.DATA_BLOCK_FIXED_SIZE);

            // create a new block with first empty index on DataPage
            var block = new DataBlock {
                Position = new PageAddress(dataPage.PageID, dataPage.DataBlocks.NextIndex()), Page = dataPage
            };

            // if extend, store all bytes on extended page.
            if (extend)
            {
                var extendPage = _pager.NewPage <ExtendPage>();
                block.ExtendPageID = extendPage.PageID;
                this.StoreExtendData(extendPage, data);
            }
            else
            {
                block.Data = data;
            }

            // add dataBlock to this page
            dataPage.DataBlocks.Add(block.Position.Index, block);

            // update freebytes + items count
            dataPage.UpdateItemCount();

            // set page as dirty
            _pager.SetDirty(dataPage);

            // add/remove dataPage on freelist if has space
            _pager.AddOrRemoveToFreeList(dataPage.FreeBytes > DataPage.DATA_RESERVED_BYTES, dataPage, col, ref col.FreeDataPageID);

            // increase document count in collection
            col.DocumentCount++;

            // set collection page as dirty
            _pager.SetDirty(col);

            return(block);
        }
示例#3
0
        /// <summary>
        /// Create a new index and returns head page address (skip list)
        /// </summary>
        public CollectionIndex CreateIndex(CollectionPage col)
        {
            // get index slot
            var index = col.GetFreeIndex();

            // get a new index page for first index page
            var page = _pager.NewPage <IndexPage>();

            // create a empty node with full max level
            var head = new IndexNode(IndexNode.MAX_LEVEL_LENGTH)
            {
                Key       = BsonValue.MinValue,
                KeyLength = (ushort)BsonValue.MinValue.GetBytesCount(false),
                Slot      = (byte)index.Slot,
                Page      = page,
                Position  = new PageAddress(page.PageID, 0)
            };

            // add as first node
            page.Nodes.Add(head.Position.Index, head);

            // update freebytes + item count (for head)
            page.UpdateItemCount();

            // set index page as dirty
            _pager.SetDirty(index.Page);

            // add indexPage on freelist if has space
            _pager.AddOrRemoveToFreeList(true, page, index.Page, ref index.FreeIndexPageID);

            // point the head/tail node to this new node position
            index.HeadNode = head.Position;

            // insert tail node
            var tail = this.AddNode(index, BsonValue.MaxValue, IndexNode.MAX_LEVEL_LENGTH, null);

            index.TailNode = tail.Position;

            return(index);
        }
示例#4
0
        /// <summary>
        /// Insert data inside a datapage. Returns dataPageID that idicates the first page
        /// </summary>
        public DataBlock Insert(CollectionPage col, IndexKey key, byte[] data)
        {
            // need to extend (data is bigger than 1 page)
            var extend = (data.Length + key.Length + DataBlock.DATA_BLOCK_FIXED_SIZE) > BasePage.PAGE_AVAILABLE_BYTES;

            // if extend, just search for a page with BLOCK_SIZE avaiable
            var dataPage = _pager.GetFreePage <DataPage>(col.FreeDataPageID, extend ? DataBlock.DATA_BLOCK_FIXED_SIZE : key.Length + data.Length + DataBlock.DATA_BLOCK_FIXED_SIZE);

            // create a new block with first empty index on DataPage
            var block = new DataBlock {
                Position = new PageAddress(dataPage.PageID, dataPage.DataBlocks.NextIndex()), Page = dataPage, Key = key
            };

            // if extend, store all bytes on extended page.
            if (extend)
            {
                var extendPage = _pager.NewPage <ExtendPage>();
                block.ExtendPageID = extendPage.PageID;
                this.StoreExtendData(extendPage, data);
            }
            else
            {
                block.Data = data;
            }

            // add dataBlock to this page
            dataPage.DataBlocks.Add(block.Position.Index, block);

            dataPage.IsDirty = true;

            // add/remove dataPage on freelist if has space
            _pager.AddOrRemoveToFreeList(dataPage.FreeBytes > BasePage.RESERVED_BYTES, dataPage, col, ref col.FreeDataPageID);

            col.DocumentCount++;

            col.IsDirty = true;

            return(block);
        }
示例#5
0
        /// <summary>
        /// Add a new collection. Check if name the not exists
        /// </summary>
        public CollectionPage Add(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }
            if (!CollectionPage.NamePattern.IsMatch(name))
            {
                throw LiteException.InvalidFormat("CollectionName", name);
            }

            // test collection limit
            var pages = _pager.GetSeqPages <CollectionPage>(_cache.Header.FirstCollectionPageID);

            if (pages.Count() >= CollectionPage.MAX_COLLECTIONS)
            {
                throw LiteException.CollectionLimitExceeded(CollectionPage.MAX_COLLECTIONS);
            }

            var col = _pager.NewPage <CollectionPage>();

            // add page in collection list
            _pager.AddOrRemoveToFreeList(true, col, _cache.Header, ref _cache.Header.FirstCollectionPageID);

            col.CollectionName = name;
            col.IsDirty        = true;

            // create PK index
            var pk = _indexer.CreateIndex(col);

            pk.Field   = "_id";
            pk.Options = new IndexOptions {
                Unique = true
            };

            return(col);
        }