double maxX, double minY, double maxY)
{
double med;
Tree t = new Tree();
Join jv = new Join();
PE me = PE.thisPE();
GlobalObject gb;
int leftN, rightN;
if (Aleph.verbosity(Constants.LOQUACIOUS))
System.out.println("n:"+n+" dir:"+dir+" peNo:"+peNo+" numPE:"+numPE);
if (n == 0) return null;
gb = new GlobalObject(t);
t = (Tree) gb.open("w");
leftN = (n-1)/2;
rightN = n-1-leftN;
if (dir == 1) {
dir = 0;
med = median(minX, maxX, n);
if (leftN == 0)
t._left = null;
else {
if (me.equals(PE.getPE(peNo+numPE/2))) { // Local PE
if (Aleph.verbosity(Constants.LOQUACIOUS))
System.out.print("Left ");
t._left = buildTree(leftN, dir, peNo+numPE/2, numPE/2, minX, med, minY, maxY);
} else { // Remote PE
try {
gb.release();
} catch (AlephException ale) {
Aleph.warning("Release failed: " + ale.getMessage());
}
Builder builder = new Builder(gb, leftN, dir, peNo+numPE/2, numPE/2,
minX, med, minY, maxY);
builder.start(PE.getPE(peNo+numPE/2), jv);
jv.waitFor();
t = (Tree) gb.open("w");
}
}
if (rightN == 0)
t._right = null;
else {
if (Aleph.verbosity(Constants.LOQUACIOUS))
System.out.print("Right ");
// Right subtree always in local PE
t._right = buildTree(rightN, dir, peNo, numPE/2, med, maxX, minY, maxY);
}
t._x = med;
t._y = uniform(minY, maxY);
} else {
dir = 1;
med = median(minY, maxY, n);
if (leftN == 0)
t._left = null;
else {
if (me.equals(PE.getPE(peNo+numPE/2))) { // Local PE
if (Aleph.verbosity(Constants.LOQUACIOUS))
System.out.print("Left ");
t._left = buildTree(leftN, dir, peNo+numPE/2, numPE/2, minX, maxX, minY, med);
} else { // Remote PE
try {