예제 #1
0
        /// <summary>
        /// Update data inside a datapage. If new data can be used in same datapage, just update. Otherside, copy content to a new ExtendedPage
        /// </summary>
        public DataBlock Update(CollectionPage col, PageAddress blockAddress, byte[] data)
        {
            var dataPage = _pager.GetPage<DataPage>(blockAddress.PageID);
            var block = dataPage.DataBlocks[blockAddress.Index];
            var extend = dataPage.FreeBytes + block.Data.Length - data.Length <= 0;

            // check if need to extend
            if (extend)
            {
                // clear my block data
                block.Data = new byte[0];
                block.ExtendData = data;

                // create (or get a existed) extendpage and store data there
                ExtendPage extendPage;

                if (block.ExtendPageID == uint.MaxValue)
                {
                    extendPage = _pager.NewPage<ExtendPage>();
                    block.ExtendPageID = extendPage.PageID;
                }
                else
                {
                    extendPage = _pager.GetPage<ExtendPage>(block.ExtendPageID);
                }

                this.StoreExtendData(extendPage, data);
            }
            else
            {
                // if no extends, just update data block
                block.Data = data;

                // if there was a extended bytes, delete
                if (block.ExtendPageID != uint.MaxValue)
                {
                    _pager.DeletePage(block.ExtendPageID, true);
                    block.ExtendPageID = uint.MaxValue;
                }
            }

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

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

            dataPage.IsDirty = true;

            return block;
        }
예제 #2
0
        /// <summary>
        /// Delete indexNode from a Index  ajust Next/Prev nodes
        /// </summary>
        public void Delete(CollectionIndex index, PageAddress nodeAddress)
        {
            var node = this.GetNode(nodeAddress);
            var page = node.Page;

            for (int i = node.Prev.Length - 1; i >= 0; i--)
            {
                // get previus and next nodes (between my deleted node)
                var prev = this.GetNode(node.Prev[i]);
                var next = this.GetNode(node.Next[i]);

                if (prev != null)
                {
                    prev.Next[i]      = node.Next[i];
                    prev.Page.IsDirty = true;
                }
                if (next != null)
                {
                    next.Prev[i]      = node.Prev[i];
                    next.Page.IsDirty = true;
                }
            }

            page.Nodes.Remove(node.Position.Index);

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

            // if there is no more nodes in this page, delete them
            if (page.Nodes.Count == 0)
            {
                // first, remove from free list
                _pager.AddOrRemoveToFreeList(false, page, index.Page, ref index.FreeIndexPageID);

                _pager.DeletePage(page.PageID, false);
            }
            else
            {
                // add or remove page from free list
                _pager.AddOrRemoveToFreeList(page.FreeBytes > IndexPage.INDEX_RESERVED_BYTES, node.Page, index.Page, ref index.FreeIndexPageID);
            }

            page.IsDirty = true;
        }
예제 #3
0
        /// <summary>
        /// Delete one dataBlock
        /// </summary>
        public DataBlock Delete(CollectionPage col, PageAddress blockAddress)
        {
            // get page and mark as dirty
            var page  = _pager.GetPage <DataPage>(blockAddress.PageID);
            var block = page.DataBlocks[blockAddress.Index];

            // if there a extended page, delete all
            if (block.ExtendPageID != uint.MaxValue)
            {
                _pager.DeletePage(block.ExtendPageID, true);
            }

            // delete block inside page
            page.DataBlocks.Remove(block.Position.Index);

            // update freebytes + itemcount
            page.UpdateItemCount();

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

            // if there is no more datablocks, lets delete all page
            if (page.DataBlocks.Count == 0)
            {
                // first, remove from free list
                _pager.AddOrRemoveToFreeList(false, page, col, ref col.FreeDataPageID);

                _pager.DeletePage(page.PageID);
            }
            else
            {
                // add or remove to free list
                _pager.AddOrRemoveToFreeList(page.FreeBytes > DataPage.DATA_RESERVED_BYTES, page, col, ref col.FreeDataPageID);
            }

            col.DocumentCount--;

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

            return(block);
        }
예제 #4
0
파일: DataService.cs 프로젝트: apkd/LiteDB
        /// <summary>
        /// Delete one dataBlock
        /// </summary>
        public DataBlock Delete(CollectionPage col, PageAddress blockAddress)
        {
            // get page and mark as dirty
            var page = _pager.GetPage<DataPage>(blockAddress.PageID);
            var block = page.DataBlocks[blockAddress.Index];

            // if there a extended page, delete all
            if (block.ExtendPageID != uint.MaxValue)
            {
                _pager.DeletePage(block.ExtendPageID, true);
            }

            // delete block inside page
            page.DataBlocks.Remove(block.Position.Index);

            // update freebytes + itemcount
            page.UpdateItemCount();

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

            // if there is no more datablocks, lets delete all page
            if (page.DataBlocks.Count == 0)
            {
                // first, remove from free list
                _pager.AddOrRemoveToFreeList(false, page, col, ref col.FreeDataPageID);

                _pager.DeletePage(page.PageID);
            }
            else
            {
                // add or remove to free list
                _pager.AddOrRemoveToFreeList(page.FreeBytes > DataPage.DATA_RESERVED_BYTES, page, col, ref col.FreeDataPageID);
            }

            col.DocumentCount--;

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

            return block;
        }
예제 #5
0
 public static string Dump(this PageAddress address)
 {
     return(address.PageID.Dump() + ":" + address.Index.Dump());
 }
예제 #6
0
        /// <summary>
        /// Get a data block from a DataPage using address
        /// </summary>
        public DataBlock GetBlock(PageAddress blockAddress)
        {
            var page = _pager.GetPage <DataPage>(blockAddress.PageID);

            return(page.DataBlocks[blockAddress.Index]);
        }
예제 #7
0
 public void Write(PageAddress value)
 {
     Write(value.PageID);
     Write(value.Index);
 }
예제 #8
0
        /// <summary>
        /// Read all data from datafile using a pageID as reference. If data is not in DataPage, read from ExtendPage. If readExtendData = false, do not read extended data
        /// </summary>
        public DataBlock Read(PageAddress blockAddress, bool readExtendData)
        {
            var page = _pager.GetPage<DataPage>(blockAddress.PageID);
            var block = page.DataBlocks[blockAddress.Index];

            // if there is a extend page, read bytes to block.Data
            if (readExtendData && block.ExtendPageID != uint.MaxValue)
            {
                block.ExtendData = this.ReadExtendData(block.ExtendPageID);
            }

            return block;
        }
예제 #9
0
 public static void Write(this BufferSlice buffer, PageAddress value, int offset)
 {
     value.PageID.ToBytes(buffer.Array, buffer.Offset + offset);
     buffer[offset + 4] = value.Index;
 }
예제 #10
0
 public static void Write(this BinaryWriter writer, PageAddress address)
 {
     writer.Write(address.PageID);
     writer.Write(address.Index);
 }
예제 #11
0
파일: IndexService.cs 프로젝트: apkd/LiteDB
 /// <summary>
 /// Get a node inside a page using PageAddress - Returns null if address IsEmpty
 /// </summary>
 public IndexNode GetNode(PageAddress address)
 {
     if (address.IsEmpty) return null;
     var page = _pager.GetPage<IndexPage>(address.PageID);
     return page.Nodes[address.Index];
 }
예제 #12
0
파일: DataService.cs 프로젝트: apkd/LiteDB
 /// <summary>
 /// Get a data block from a DataPage using address
 /// </summary>
 public DataBlock GetBlock(PageAddress blockAddress)
 {
     var page = _pager.GetPage<DataPage>(blockAddress.PageID);
     return page.DataBlocks[blockAddress.Index];
 }
예제 #13
0
파일: DataService.cs 프로젝트: apkd/LiteDB
        /// <summary>
        /// Read all data from datafile using a pageID as reference. If data is not in DataPage, read from ExtendPage.
        /// </summary>
        public byte[] Read(PageAddress blockAddress)
        {
            var block = this.GetBlock(blockAddress);

            // if there is a extend page, read bytes all bytes from extended pages
            if (block.ExtendPageID != uint.MaxValue)
            {
                return this.ReadExtendData(block.ExtendPageID);
            }

            return block.Data;
        }
예제 #14
0
 public void Write(PageAddress value)
 {
     this.Write(value.PageID);
     this.Write(value.Index);
 }
예제 #15
0
 public void Write(PageAddress value)
 {
     this.Write(value.PageID);
     this.Write(value.Index);
 }
예제 #16
0
파일: IndexService.cs 프로젝트: apkd/LiteDB
        /// <summary>
        /// Delete indexNode from a Index  ajust Next/Prev nodes
        /// </summary>
        public void Delete(CollectionIndex index, PageAddress nodeAddress)
        {
            var node = this.GetNode(nodeAddress);
            var page = node.Page;

            // mark page as dirty here because, if deleted, page type will change
            _pager.SetDirty(page);

            for (int i = node.Prev.Length - 1; i >= 0; i--)
            {
                // get previus and next nodes (between my deleted node)
                var prev = this.GetNode(node.Prev[i]);
                var next = this.GetNode(node.Next[i]);

                if (prev != null)
                {
                    prev.Next[i] = node.Next[i];
                    _pager.SetDirty(prev.Page);
                }
                if (next != null)
                {
                    next.Prev[i] = node.Prev[i];
                    _pager.SetDirty(next.Page);
                }
            }

            page.Nodes.Remove(node.Position.Index);

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

            // if there is no more nodes in this page, delete them
            if (page.Nodes.Count == 0)
            {
                // first, remove from free list
                _pager.AddOrRemoveToFreeList(false, page, index.Page, ref index.FreeIndexPageID);

                _pager.DeletePage(page.PageID);
            }
            else
            {
                // add or remove page from free list
                _pager.AddOrRemoveToFreeList(page.FreeBytes > IndexPage.INDEX_RESERVED_BYTES, node.Page, index.Page, ref index.FreeIndexPageID);
            }

            // now remove node from nodelist
            var prevNode = this.GetNode(node.PrevNode);
            var nextNode = this.GetNode(node.NextNode);

            if (prevNode != null)
            {
                prevNode.NextNode = node.NextNode;
                _pager.SetDirty(prevNode.Page);
            }
            if (nextNode != null)
            {
                nextNode.PrevNode = node.PrevNode;
                _pager.SetDirty(nextNode.Page);
            }
        }
예제 #17
0
 public static void Write(this BinaryWriter writer, PageAddress address)
 {
     writer.Write(address.PageID);
     writer.Write(address.Index);
 }