示例#1
0
        /// <summary>
        /// Propagates resizing of the nodes upwards. Additionally, performs
        /// any splitting of nodes along the way if a node needed to split.
        /// Returns whether the root node was split.
        /// </summary>
        /// <param name="adjustPath">Path along which the nodes need be adjusted</param>
        /// <param name="node">Node above which needs to be adjusted</param>
        /// <param name="splitNode">Node that needs to be inserted.</param>
        /// <returns>True if the root node was split</returns>
        private bool adjustTree(List <NodeRecord <T> > adjustPath,
                                NodeRecord <T> node, ref NodeRecord <T> splitNode)
        {
            // AT1.
            NodeRecord <T> N  = node;
            NodeRecord <T> NN = splitNode;

            while (true)
            {
                // AT2.
                if (N == root)
                {
                    return(NN != null);
                }

                // AT3.
                N.ResizeBBox();

                // AT4.
                // Try to add the extra node to this parent node.
                // If the parent has no more room, split the parent,
                // and propagate the split node upwards to continue
                // looking for an insertion point.
                int            level = adjustPath.IndexOf(N);
                NodeRecord <T> P     = adjustPath[level - 1];

                if (NN != null)
                {
                    if (!P.TryInsert(NN))
                    {
                        NodeRecord <T> PP = P.Split(NN);
                        NN = PP;
                    }
                    else
                    {
                        NN = null;
                    }
                }

                N = P;
            }
        }
示例#2
0
        /// <summary>
        /// Performs the insertion algorithm.
        /// </summary>
        /// <param name="item">Item to insert</param>
        public void Insert(LeafRecord <T> item)
        {
            List <NodeRecord <T> > leafPath = new List <NodeRecord <T> >();

            // I1.
            // Track the nodes traversed to get to the point that we
            // want to add the node. This list of nodes will be used
            // to propagate changes up the tree.
            NodeRecord <T> insertNode = chooseLeaf(item, leafPath);
            NodeRecord <T> splitNode  = null;

            // I2.
            // Attempts to insert the item in the given node.
            // If it fails, we split the node. Store the new
            // node in splitNode, so it can be propagated up
            // later.
            if (!insertNode.TryInsert(item))
            {
                // Split.
                splitNode = insertNode.Split(item);
            }

            // I3.
            // Propagate resizing up the tree. Propagate split node
            // if necessary.
            if (adjustTree(leafPath, insertNode, ref splitNode))
            {
                // I4.
                // Create a new root if the root was split. This new root is not a leaf.
                NodeRecord <T> newRoot = new NodeRecord <T>()
                {
                    Node = new RTreeNode <T>(Leaf: false)
                };
                newRoot.TryInsert(root);
                newRoot.TryInsert(splitNode);
                root = newRoot;
            }
        }