public void UpdateSubnodeEntry(NodeID subnodeID, DataTree dataTree, SubnodeBTree subnodeBTree) { SubnodeLeafEntry entry = GetLeafEntry(subnodeID.Value); if (entry != null) { entry.bidData = new BlockID(0); if (dataTree != null && dataTree.RootBlock != null) { entry.bidData = dataTree.RootBlock.BlockID; } entry.bidSub = new BlockID(0); if (subnodeBTree != null && subnodeBTree.RootBlock != null) { entry.bidSub = subnodeBTree.RootBlock.BlockID; } // We have to store the new leaf block, and cascade the changes up to the root block SubnodeLeafBlock leafBlock = FindLeafBlock(entry.nid.Value); // leafBlock cannot be null int index = leafBlock.IndexOfLeafEntry(subnodeID.Value); leafBlock.rgentries[index] = entry; UpdateBlockAndReferences(leafBlock); } }
public static Subnode GetSubnode(PSTFile file, SubnodeLeafEntry entry) { DataTree dataTree = null; if (entry.bidData.Value != 0) { Block rootDataBlock = file.FindBlockByBlockID(entry.bidData); if (rootDataBlock == null) { throw new Exception("Cannot get subnode: missing data tree root block"); } dataTree = new DataTree(file, rootDataBlock); } SubnodeBTree subnodeBTree = null; if (entry.bidSub.Value != 0) { Block rootSubnodeBlock = file.FindBlockByBlockID(entry.bidSub); if (rootSubnodeBlock == null) { throw new Exception("Missing Subnode BTree Root Block"); } subnodeBTree = new SubnodeBTree(file, rootSubnodeBlock); } return(new Subnode(file, entry.nid, dataTree, subnodeBTree)); }
/// <returns>Insert index</returns> public int InsertSorted(SubnodeLeafEntry entryToInsert) { int insertIndex = GetSortedInsertIndex(entryToInsert); rgentries.Insert(insertIndex, entryToInsert); return(insertIndex); }
public SubnodeLeafEntry Clone() { SubnodeLeafEntry result = new SubnodeLeafEntry(); result.nid = nid.Clone(); result.bidData = bidData.Clone(); result.bidSub = bidSub.Clone(); return(result); }
public Subnode GetSubnode(uint subnodeID) { SubnodeLeafEntry entry = GetLeafEntry(subnodeID); if (entry != null) { Subnode result = Subnode.GetSubnode(this.File, entry); return(result); } return(null); }
public int GetSortedInsertIndex(SubnodeLeafEntry entryToInsert) { uint key = entryToInsert.nid.Value; int insertIndex = 0; while (insertIndex < rgentries.Count && key > rgentries[insertIndex].nid.Value) { insertIndex++; } return(insertIndex); }
public SubnodeLeafBlock(byte[] buffer) : base(buffer) { btype = (BlockType)buffer[0]; cLevel = buffer[1]; ushort cEnt = LittleEndianConverter.ToUInt16(buffer, 2); int offset = 8; for (int index = 0; index < cEnt; index++) { SubnodeLeafEntry entry = new SubnodeLeafEntry(buffer, offset); rgentries.Add(entry); offset += SubnodeLeafEntry.Length; } }
public void InsertSubnodeEntry(SubnodeLeafEntry entry) { if (m_rootBlock == null) { m_rootBlock = new SubnodeLeafBlock(); AddBlock(m_rootBlock); } SubnodeLeafBlock leafBlock = FindLeafBlock(entry.nid.Value); if (leafBlock.rgentries.Count < SubnodeLeafBlock.MaximumNumberOfEntries) { leafBlock.InsertSorted(entry); UpdateBlockAndReferences(leafBlock); } else { // Instead of splitting, it might be better to move entries around so blocks will remain packed SubnodeLeafBlock newLeafBlock = leafBlock.Split(); if (newLeafBlock.BlockKey < entry.nid.Value) { newLeafBlock.InsertSorted(entry); } else { int insertIndex = leafBlock.InsertSorted(entry); if (insertIndex == 0 && m_rootBlock is SubnodeIntermediateBlock) { // block key has been modified, we must update the parent UpdateIntermediateEntry((SubnodeIntermediateBlock)m_rootBlock, leafBlock.BlockID, leafBlock.BlockKey); } } UpdateBlockAndReferences(leafBlock); AddBlock(newLeafBlock); if (m_rootBlock is SubnodeLeafBlock) { // this is a root page and it's full, we have to create a new root CreateNewRoot(); } InsertIntermediateEntry((SubnodeIntermediateBlock)m_rootBlock, newLeafBlock.BlockKey, newLeafBlock.BlockID); } }
public void InsertSubnodeEntry(NodeID subnodeID, DataTree dataTree, SubnodeBTree subnodeBTree) { SubnodeLeafEntry entry = new SubnodeLeafEntry(); entry.nid = subnodeID; entry.bidData = new BlockID(0); if (dataTree != null && dataTree.RootBlock != null) { entry.bidData = dataTree.RootBlock.BlockID; } entry.bidSub = new BlockID(0); if (subnodeBTree != null && subnodeBTree.RootBlock != null) { entry.bidSub = subnodeBTree.RootBlock.BlockID; } InsertSubnodeEntry(entry); }