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);
            }
        }
Example #2
0
        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));
        }
Example #3
0
        /// <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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }