private void refresh(RNode part1, RNode part2) throws DimensionalException { if (part1 == root) { if (part2 != null) { // build new root and add children. root = makeRoot(false); root.addChild(part1); part1.setParent(root); root.addChild(part2); part2.setParent(root); } update(root); return; } update(part1); if (part2 != null) { update(part2); if (part1.getParent().getChildren().size() > M_order) { RNode[] splits = makePartition(part1.getParent()); refresh(splits[0], splits[1]); } } if (part1.getParent() != null) { refresh(part1.getParent(), null); } }
private RNode[] makePartition(RNode n) throws DimensionalException { numOfPartitions++; numOfNodes += 2; RNode[] parts = new RNode[] {n, new RNode(n.getMbr(), n.isLeaf(), M_order)}; parts[1].setParent(n.getParent()); if (parts[1].getParent() != null) { parts[1].getParent().children().add(parts[1]); } List<RNode> cpyc = new LinkedList<RNode>(n.children()); n.children().clear(); RNode[] seeds = getSeeds(cpyc); parts[0].children().add(seeds[0]); parts[1].children().add(seeds[1]); update(parts[0]); update(parts[1]); while (!cpyc.isEmpty()) { if (parts[0].missingEntries(m_order) == 0 && parts[1].missingEntries(m_order) + cpyc.size() == m_order) { parts[1].children().addAll(cpyc); cpyc.clear(); update(parts[0]); update(parts[1]); return parts; } else if (parts[1].missingEntries(m_order) == 0 && parts[0].missingEntries(m_order) + cpyc.size() == m_order) { parts[0].children().addAll(cpyc); cpyc.clear(); update(parts[0]); update(parts[1]); return parts; } RNode next = chooseNext(cpyc, seeds), chosen; double enl1 = getEnlargement(parts[0], next); double enl2 = getEnlargement(parts[1], next); if (enl1 < enl2) chosen = parts[0]; else if (enl2 < enl1) chosen = parts[1]; else { double ar1 = parts[0].getMbr().getArea(); double ar2 = parts[1].getMbr().getArea(); if (ar1 < ar2) chosen = parts[0]; else if (ar2 < ar1) chosen = parts[1]; else { if (parts[0].children().size() < parts[1].children().size()) chosen = parts[0]; else if (parts[0].children().size() > parts[1].children().size()) chosen = parts[1]; else chosen = parts[new Random().nextInt(2)]; } } chosen.children().add(next); update(chosen); } return parts; }