Ejemplo n.º 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;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Removes unfull nodes and shrinks BBoxs along the leafpath.
        /// </summary>
        /// <param name="deletedRecordNode">node with leaf deleted</param>
        /// <param name="leafPath">Path from root to node with deletion</param>
        private void condenseTree(NodeRecord <T> deletedRecordNode, List <NodeRecord <T> > leafPath)
        {
            List <NodeRecord <T> > Q = new List <NodeRecord <T> >();
            NodeRecord <T>         N = deletedRecordNode;

            while (true)
            {
                if (N == root)
                {
                    break;
                }

                int            level = leafPath.IndexOf(N);
                NodeRecord <T> P     = leafPath[level - 1];
                if (N.Node.GetRecordCount() < RTreeNode <T> .m)
                {
                    P.Node.GetRecords().Remove(N);
                    Q.Add(N);
                }
                else
                {
                    N.ResizeBBox();
                }

                N = P;
            }

            // We don't have to worry about doubling down because
            // at each level, we separated the removed node from its
            // parents. So even if an 'ex-parent' is present with its
            // 'ex-child' in the list, we won't double down.
            foreach (var orphan in Q)
            {
                reinsertNode(orphan);
            }
        }