/// <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); } }
public void Drop(CollectionPage col) { // delete all index pages for (byte i = 0; i < col.Indexes.Length; i++) { var index = col.Indexes[i]; if (!index.IsEmpty) { _pager.DeletePage(index.HeadNode.PageID); } } // ajust page pointers if (col.PrevPageID != uint.MaxValue) { var prev = _pager.GetPage <BasePage>(col.PrevPageID); prev.NextPageID = col.NextPageID; prev.IsDirty = true; } if (col.NextPageID != uint.MaxValue) { var next = _pager.GetPage <BasePage>(col.NextPageID); next.PrevPageID = col.PrevPageID; next.IsDirty = true; } _pager.DeletePage(col.PageID, false); }
/// <summary> /// Drop a collection - remove all data pages + indexes pages /// </summary> public void Drop(CollectionPage col) { // add all pages to delete var pages = new HashSet <uint>(); // search for all data page and index page foreach (var index in col.GetIndexes(true)) { // get all nodes from index var nodes = _indexer.FindAll(index, Query.Ascending); foreach (var node in nodes) { // if is PK index, add dataPages if (index.Slot == 0) { pages.Add(node.DataBlock.PageID); // read datablock to check if there is any extended page var block = _data.GetBlock(node.DataBlock); if (block.ExtendPageID != uint.MaxValue) { _pager.DeletePage(block.ExtendPageID, true); } } // memory checkpoint _trans.CheckPoint(); // add index page to delete list page pages.Add(node.Position.PageID); } // remove head+tail nodes in all indexes pages.Add(index.HeadNode.PageID); pages.Add(index.TailNode.PageID); } // and now, lets delete all this pages foreach (var pageID in pages) { // delete page _pager.DeletePage(pageID); // memory checkpoint _trans.CheckPoint(); } // get header page to remove from collection list links var header = _pager.GetPage <HeaderPage>(0); header.CollectionPages.Remove(col.CollectionName); // set header as dirty after remove _pager.SetDirty(header); _pager.DeletePage(col.PageID); }
/// <summary> /// Update data inside a datapage. If new data can be used in same datapage, just update. Otherwise, copy content to a new ExtendedPage /// </summary> public DataBlock Update(CollectionPage col, PageAddress blockAddress, byte[] data) { // get datapage and mark as dirty 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]; // 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(); // set DataPage as dirty _pager.SetDirty(dataPage); // 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); return(block); }
/// <summary> /// Drop a collection - remove all data pages + indexes pages /// </summary> public void Drop(CollectionPage col) { // add all pages to delete var pages = new HashSet <uint>(); // search for all data page and index page foreach (var index in col.GetIndexes(true)) { // get all nodes from index var nodes = _indexer.FindAll(index, Query.Ascending); foreach (var node in nodes) { // if is PK index, add dataPages if (index.Slot == 0) { pages.Add(node.DataBlock.PageID); // read datablock to check if there is any extended page var block = _data.Read(node.DataBlock, false); if (block.ExtendPageID != uint.MaxValue) { _pager.DeletePage(block.ExtendPageID, true); } } // add index page to delete list page pages.Add(node.Position.PageID); } } // and now, lets delete all this pages foreach (var pageID in pages) { _pager.DeletePage(pageID); } // remove page from collection list _pager.AddOrRemoveToFreeList(false, col, _cache.Header, ref _cache.Header.FirstCollectionPageID); _pager.DeletePage(col.PageID, false); }
/// <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); // 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.RESERVED_BYTES, node.Page, index.Page, ref index.FreeIndexPageID); } page.IsDirty = true; }