@SuppressWarnings("rawtypes")
  private int compareKeys(byte alias, List<Object> k1, List<Object> k2) {
    final WritableComparator[] comparators = keyComparators[alias];

    // join keys have difference sizes?
    if (k1.size() != k2.size()) {
      return k1.size() - k2.size();
    }

    if (comparators.length == 0) {
      // cross-product - no keys really
      return 0;
    }

    if (comparators.length > 1) {
      // rare case
      return compareKeysMany(comparators, k1, k2);
    } else {
      return compareKey(comparators, 0,
              k1.get(0),
              k2.get(0),
              nullsafes != null ? nullsafes[0]: false);
    }
  }
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