internal NodeBase adjustTree(RTree rTree, NodeLeaf nn)
{
// AT1 [Initialize] Set N=L. If L was split previously, set NN to be the resulting second node.
// AT2 [Check if done] If N is the root, stop
while (level != rTree.treeHeight)
{
// AT3 [Adjust covering rectangle in parent entry] Let P be the parent node of N, and let En be N's entry in P. Adjust EnI so that it tightly encloses all entry rectangles in N.
NodeInternal parent = rTree.parents.Pop() as NodeInternal;
int entry = rTree.parentsEntry.Pop();
if (parent.childNodes[entry] != this)
throw new UnexpectedException("Error: entry " + entry + " in node " + parent + " should point to node " + this + "; actually points to node " + parent.childNodes[entry]);
if (parent.entries[entry].Value.MinX != minimumBoundingRectangle.MinX || parent.entries[entry].Value.MinY != minimumBoundingRectangle.MinY ||
parent.entries[entry].Value.MaxX != minimumBoundingRectangle.MaxX || parent.entries[entry].Value.MaxY != minimumBoundingRectangle.MaxY)
{
parent.entries[entry] = minimumBoundingRectangle;
parent.recalculateMBR();
}
// AT4 [Propagate node split upward] If N has a partner NN resulting from an earlier split, create a new entry Enn with Ennp pointing to NN and
// Enni enclosing all rectangles in NN. Add Enn to P if there is room. Otherwise, invoke splitNode to produce P and PP containing Enn and all P's old entries.
NodeInternal newNode = null;
if (nn != null)
{
if (parent.entryCount < rTree.maxNodeEntries)
parent.addEntry(ref nn.minimumBoundingRectangle, nn);
else
newNode = parent.splitNode(rTree, ref nn.minimumBoundingRectangle, nn);
}
// AT5 [Move up to next level] Set N = P and set NN = PP if a split occurred. Repeat from AT2
return parent.adjustTree(rTree, newNode);
}
return nn;
}