Set<SignedConnection> joinOwners = exprOwnerMap.remove(iter.next());
while (iter.hasNext()) {
joinOwners.retainAll(exprOwnerMap.remove(iter.next()));
}
Join localJoin = new Join(joinArgs);
exprOwnerMap.put(localJoin, joinOwners);
}
// Join any join arguments that have the same, unique owner
for (Set<TupleExpr> joinArgs : getColocatedJoins(exprOwnerMap)) {
// FIXME: handle args that are not connected
Set<SignedConnection> owners = null;
for (TupleExpr joinArg : joinArgs) {
owners = exprOwnerMap.remove(joinArg);
assert owners.size() == 1;
}
Join localJoin = new Join(joinArgs);
exprOwnerMap.put(localJoin, owners);
}
Join replacement = new Join();
for (Map.Entry<TupleExpr, Set<SignedConnection>> entry : exprOwnerMap.entrySet()) {
TupleExpr joinArg = entry.getKey();
Set<SignedConnection> owners = entry.getValue();
if (owners.isEmpty()) {
// No results for this expression and thus for the entire join
join.replaceWith(new EmptySet());
return;
}
else if (owners.size() == 1) {
SignedConnection owner = owners.iterator().next();
replacement.addArg(new OwnedTupleExpr(owner, joinArg));
}
else if (joinArg instanceof Join || distinct) {
// Local join with multiple owners or distinct federation members
Union union = new Union();
for (SignedConnection owner : owners) {
union.addArg(new OwnedTupleExpr(owner, joinArg.clone()));
}
replacement.addArg(union);
}
else {
replacement.addArg(joinArg);
}
}
join.replaceWith(replacement);
// addOwners(join, exprOwnerMap, localExprs);