/// <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; }
/// <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; }
/// <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); }
/// <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; }
public static string Dump(this PageAddress address) { return(address.PageID.Dump() + ":" + address.Index.Dump()); }
/// <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]); }
public void Write(PageAddress value) { Write(value.PageID); Write(value.Index); }
/// <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; }
public static void Write(this BufferSlice buffer, PageAddress value, int offset) { value.PageID.ToBytes(buffer.Array, buffer.Offset + offset); buffer[offset + 4] = value.Index; }
public static void Write(this BinaryWriter writer, PageAddress address) { writer.Write(address.PageID); writer.Write(address.Index); }
/// <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]; }
/// <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]; }
/// <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; }
public void Write(PageAddress value) { this.Write(value.PageID); this.Write(value.Index); }
/// <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); } }