protected void generateHashMapResultMultiValue(VectorizedRowBatch batch,
      VectorMapJoinHashMapResult hashMapResult, int[] allMatches, int allMatchesIndex,
      int duplicateCount) throws HiveException, IOException {

    if (useOverflowRepeatedThreshold &&
        hashMapResult.isCappedCountAvailable() &&
        hashMapResult.cappedCount() > overflowRepeatedThreshold) {

      // Large cross product: generate the vector optimization using repeating vectorized
      // row batch optimization in the overflow batch.

      generateHashMapResultLargeMultiValue(
                  batch, hashMapResult, allMatches, allMatchesIndex, duplicateCount);
      return;
    }

    // We do the cross product of the N big table equal key row's values against the
    // small table matching key which has M value rows into overflow batch.

    for (int i = 0; i < duplicateCount; i++) {

      final int batchIndex = allMatches[allMatchesIndex + i];

      ByteSegmentRef byteSegmentRef = hashMapResult.first();
      while (byteSegmentRef != null) {

        // Copy the BigTable values into the overflow batch. Since the overflow batch may
        // not get flushed here, we must copy by value.
        //
        if (bigTableRetainedVectorCopy != null) {
          bigTableRetainedVectorCopy.copyByValue(
              batch, batchIndex,
              overflowBatch, overflowBatch.size);
        }

        if (nonOuterSmallTableKeyVectorCopy != null) {

          // For non-[FULL] OUTER MapJoin, copy non-retained Big Table keys to the Big Table area
          // across to overflow batch by value so Small Key projection will see its keys...
          //
          nonOuterSmallTableKeyVectorCopy.copyByValue(
              batch, batchIndex,
              overflowBatch, overflowBatch.size);
        }

        if (outerSmallTableKeyVectorCopy != null) {

          // For [FULL] OUTER MapJoin, copy Big Table keys to Small Table area across
          // to overflow batch by value.
          //
          outerSmallTableKeyVectorCopy.copyByValue(
              batch, batchIndex,
              overflowBatch, overflowBatch.size);
        }

        if (smallTableValueVectorDeserializeRow != null) {

          doSmallTableValueDeserializeRow(overflowBatch, overflowBatch.size,
              byteSegmentRef, hashMapResult);
        }

        overflowBatch.size++;
        if (overflowBatch.size == overflowBatch.DEFAULT_SIZE) {
          forwardOverflow();
        }
        byteSegmentRef = hashMapResult.next();
      }
    }
  }
Generate results for a N x M cross product.

@param batch
         The big table batch.
@param hashMapResult
         The hash map results for the matching key.
@param allMatches
         The all match selected array that contains (physical) batch indices.
@param allMatchesIndex
         The index of the match key.
@param duplicateCount
         Number of equal key rows.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/mapjoin/VectorMapJoinGenerateResultOperator.java