/** * Used by delete(). Ensures that all nodes from the passed node * up to the root have the minimum number of entries. * * Note that the parent and parentEntry stacks are expected to * contain the nodeIds of all parents up to the root. */ //private Rectangle oldRectangle = new Rectangle(0, 0, 0, 0, 0, 0); private void condenseTree(Node <T> l) { // CT1 [Initialize] Set n=l. Set the list of eliminated // nodes to be empty. Node <T> n = l; Node <T> parent = null; int parentEntry = 0; Rectangle oldRectangle = new Rectangle(n.mbr.min.Length); // just added. May be lead to error in line oldRectangle.set.... below //TIntStack eliminatedNodeIds = new TIntStack(); Stack <int> eliminatedNodeIds = new Stack <int>(); // CT2 [Find parent entry] If N is the root, go to CT6. Otherwise // let P be the parent of N, and let En be N's entry in P while (n.level != treeHeight) { parent = getNode(parents.Pop()); parentEntry = parentsEntry.Pop(); // CT3 [Eliminiate under-full node] If N has too few entries, // delete En from P and add N to the list of eliminated nodes if (n.entryCount < minNodeEntries) { parent.deleteEntry(parentEntry, minNodeEntries); eliminatedNodeIds.Push(n.nodeId); } else { // CT4 [Adjust covering rectangle] If N has not been eliminated, // adjust EnI to tightly contain all entries in N if (!n.mbr.Equals(parent.entries[parentEntry])) { oldRectangle.set(parent.entries[parentEntry].min, parent.entries[parentEntry].max); parent.entries[parentEntry].set(n.mbr.min, n.mbr.max); parent.recalculateMBR(oldRectangle); } } // CT5 [Move up one level in tree] Set N=P and repeat from CT2 n = parent; } // CT6 [Reinsert orphaned entries] Reinsert all entries of nodes in set Q. // Entries from eliminated leaf nodes are reinserted in tree leaves as in // Insert(), but entries from higher level nodes must be placed higher in // the tree, so that leaves of their dependent subtrees will be on the same // level as leaves of the main tree while (eliminatedNodeIds.Count > 0) { Node <T> e = getNode(eliminatedNodeIds.Pop()); for (int j = 0; j < e.entryCount; j++) { add(e.entries[j], e.ids[j], e.level); e.entries[j] = null; } e.entryCount = 0; deletedNodeIds.Push(e.nodeId); nodeMap.Remove(e.nodeId); } }
// oldRectangle is a rectangle that has just been deleted or made smaller. // Thus, the MBR is only recalculated if the OldRectangle influenced the old MBR internal void recalculateMBR(Rectangle deletedRectangle) { if (mbr.edgeOverlaps(deletedRectangle)) { mbr.set(entries[0].min, entries[0].max); for (int i = 1; i < entryCount; i++) { mbr.add(entries[i]); } } }