private List<Byte> joinObject(int[] smallestPos, boolean clear) throws HiveException {
    List<Byte> needFetchList = new ArrayList<Byte>();
    byte index = (byte) (smallestPos.length - 1);
    for (; index >= 0; index--) {
      if (smallestPos[index] > 0 || keyWritables[index] == null) {
        putDummyOrEmpty(index);
        continue;
      }
      storage[index] = candidateStorage[index];
      if (clear) {
        needFetchList.add(index);
      }
      if (smallestPos[index] < 0) {
        break;
      }
    }
    for (index--; index >= 0; index--) {
      putDummyOrEmpty(index);
    }
    checkAndGenObject();
    if (clear) {
      for (Byte pos : needFetchList) {
        this.candidateStorage[pos].clearRows();
        this.keyWritables[pos] = null;
      }
    }
    return needFetchList;
  }
Decides if the actual row must be an unmatched row.

Unmatched rows are those which are not part of the inner-join.
The current implementation has issues processing filtered rows in FOJ conditions.
Putting them in a separate group also reduces processing done for them.
ql/src/java/org/apache/hadoop/hive/ql/exec/CommonMergeJoinOperator.java