in tajo-core/tajo-core-backend/src/main/java/org/apache/tajo/engine/planner/physical/BNLJoinExec.java [93:197]
public Tuple next() throws IOException {
if (leftTupleSlots.isEmpty()) {
for (int k = 0; k < TUPLE_SLOT_SIZE; k++) {
Tuple t = leftChild.next();
if (t == null) {
leftEnd = true;
break;
}
leftTupleSlots.add(t);
}
leftIterator = leftTupleSlots.iterator();
leftTuple = leftIterator.next();
}
if (rightTupleSlots.isEmpty()) {
for (int k = 0; k < TUPLE_SLOT_SIZE; k++) {
Tuple t = rightChild.next();
if (t == null) {
rightEnd = true;
break;
}
rightTupleSlots.add(t);
}
rightIterator = rightTupleSlots.iterator();
}
if((rightNext = rightChild.next()) == null){
rightEnd = true;
}
while (true) {
if (!rightIterator.hasNext()) { // if leftIterator ended
if (leftIterator.hasNext()) { // if rightTupleslot remains
leftTuple = leftIterator.next();
rightIterator = rightTupleSlots.iterator();
} else {
if (rightEnd) {
rightChild.rescan();
rightEnd = false;
if (leftEnd) {
return null;
}
leftTupleSlots.clear();
for (int k = 0; k < TUPLE_SLOT_SIZE; k++) {
Tuple t = leftChild.next();
if (t == null) {
leftEnd = true;
break;
}
leftTupleSlots.add(t);
}
if (leftTupleSlots.isEmpty()) {
return null;
}
leftIterator = leftTupleSlots.iterator();
leftTuple = leftIterator.next();
} else {
leftIterator = leftTupleSlots.iterator();
leftTuple = leftIterator.next();
}
rightTupleSlots.clear();
if (rightNext != null) {
rightTupleSlots.add(rightNext);
for (int k = 1; k < TUPLE_SLOT_SIZE; k++) { // fill right
Tuple t = rightChild.next();
if (t == null) {
rightEnd = true;
break;
}
rightTupleSlots.add(t);
}
} else {
for (int k = 0; k < TUPLE_SLOT_SIZE; k++) { // fill right
Tuple t = rightChild.next();
if (t == null) {
rightEnd = true;
break;
}
rightTupleSlots.add(t);
}
}
if ((rightNext = rightChild.next()) == null) {
rightEnd = true;
}
rightIterator = rightTupleSlots.iterator();
}
}
frameTuple.set(leftTuple, rightIterator.next());
if (hasJoinQual) {
if (joinQual.eval(inSchema, frameTuple).isTrue()) {
projector.eval(frameTuple, outputTuple);
return outputTuple;
}
} else {
projector.eval(frameTuple, outputTuple);
return outputTuple;
}
}
}