public boolean colocate(LocatedKey treeKey) { List<InnerNode>[] allRoots = new List[this.keys.length]; sleep(); int cutoff = tree.getCutoff(true, tree.cutoffKey); BPlusTree.wrapper.startTransaction(false); tree.applyCutoff(treeKey, cutoff); BPlusTree.wrapper.endTransaction(true); boolean successful = false; while (!successful) { try { BPlusTree.wrapper.startTransaction(false); int i = 0; int s = 0; List<InnerNode> source = null; for (LocatedKey lrKey : this.keys) { allRoots[i] = BPlusTree.getLocalRoots(lrKey); if (allRoots[i] != null && allRoots[i].size() > 0) { source = allRoots[i]; s = i; System.out.println("Found source for local roots with length: " + source.size()); } i++; } int members = allRoots.length; int localRoots = source.size(); int division = (int) Math.floor((localRoots + 0.0) / (members + 0.0)); if (division == 0) { BPlusTree.wrapper.endTransaction(true); System.out.println("Division is zero, not co-locating! Had members: " + members); return false; } int groupFrom = s; int groupTo = -1; InnerNode toMove = null; source = new ArrayList<InnerNode>(source); for (int k = 0; k < allRoots.length; k++) { if (k == s) { continue; } List<InnerNode> otherRoots = allRoots[k]; if (otherRoots == null) { otherRoots = new ArrayList<InnerNode>(); } else { otherRoots = new ArrayList<InnerNode>(otherRoots); } groupTo = k; for (int l = 0; l < division; l++) { toMove = source.remove(source.size() - 1); toMove = toMove.startChangeGroup(this.keys[k].getGroup()); otherRoots.add(toMove); BPlusTree.wrapper.endTransaction(true); System.out.println( "Async ColocationThread moved Root " + toMove + " from " + this.keys[groupFrom].getGroup() + " to " + this.keys[groupTo].getGroup()); BPlusTree.wrapper.startTransaction(false); } BPlusTree.setLocalRoots(this.keys[k], otherRoots); } BPlusTree.setLocalRoots(this.keys[s], source); BPlusTree.wrapper.endTransaction(true); successful = true; } catch (Exception e) { e.printStackTrace(); System.out.println("Colocation should not have exceptions"); System.exit(-1); // try { BPlusTree.wrapper.endTransaction(false); } // catch (Exception e2) { // // } // sleep(); } } return false; }