private static VectorBatchPatterns chooseBatchPatterns(
      Random random,
      VectorRandomRowSource vectorRandomRowSource,
      Object[][] randomRows) {

    final boolean allowNull = vectorRandomRowSource.getAllowNull();

    List<VectorBatchPattern> vectorBatchPatternList = new ArrayList<VectorBatchPattern>();
    final int rowCount = randomRows.length;
    int rowIndex = 0;

    if (rowCount > 0) {

      final int columnCount = randomRows[0].length;

      // Choose first up to a full batch with no selection.
      final int regularBatchSize = Math.min(rowCount - rowIndex, VectorizedRowBatch.DEFAULT_SIZE);
      vectorBatchPatternList.add(VectorBatchPattern.createRegularBatch(regularBatchSize));
      rowIndex += regularBatchSize;

      // Have a non-NULL value on hand.
      Object[] nonNullRow = new Object[columnCount];
      for (int c = 0; c < columnCount; c++) {
        for (int r = 0; r < rowCount; r++) {
          Object object = randomRows[r][c];
          if (object != null) {
            nonNullRow[c] = object;
            break;
          }
        }
      }

      int columnPermutationLimit = Math.min(columnCount, Long.SIZE);

      boolean asSelected = false;

      /*
       * Do a round each as physical with no row selection and logical with row selection.
       */
      while (true) {

        long columnPermutation = 1;
        if (allowNull) {

          // Repeated NULL permutations.
          while (true) {
            if (columnPermutation > columnPermutationLimit) {
              break;
            }
            final int maximumRowCount = Math.min(rowCount - rowIndex, VectorizedRowBatch.DEFAULT_SIZE);
            if (maximumRowCount == 0) {
              break;
            }
            int randomRowCount = 1 + random.nextInt(maximumRowCount);
            final int rowLimit = rowIndex + randomRowCount;

            BitSet bitSet = BitSet.valueOf(new long[]{columnPermutation});

            for (int columnNum = bitSet.nextSetBit(0);
                 columnNum >= 0;
                 columnNum = bitSet.nextSetBit(columnNum + 1)) {

              // Repeated NULL fill down column.
              for (int r = rowIndex; r < rowLimit; r++) {
                randomRows[r][columnNum] = null;
              }
            }
            vectorBatchPatternList.add(
                VectorBatchPattern.createRepeatedBatch(
                    random, randomRowCount, bitSet, asSelected));
            columnPermutation++;
            rowIndex = rowLimit;
          }
        }

        // Repeated non-NULL permutations.
        columnPermutation = 1;
        while (true) {
          if (columnPermutation > columnPermutationLimit) {
            break;
          }
          final int maximumRowCount = Math.min(rowCount - rowIndex, VectorizedRowBatch.DEFAULT_SIZE);
          if (maximumRowCount == 0) {
            break;
          }
          int randomRowCount = 1 + random.nextInt(maximumRowCount);
          final int rowLimit = rowIndex + randomRowCount;

          BitSet bitSet = BitSet.valueOf(new long[]{columnPermutation});

          for (int columnNum = bitSet.nextSetBit(0);
               columnNum >= 0;
               columnNum = bitSet.nextSetBit(columnNum + 1)) {

            // Repeated non-NULL fill down column.
            Object repeatedObject = randomRows[rowIndex][columnNum];
            if (repeatedObject == null) {
              repeatedObject = nonNullRow[columnNum];
            }
            for (int r = rowIndex; r < rowLimit; r++) {
              randomRows[r][columnNum] = repeatedObject;
            }
          }
          vectorBatchPatternList.add(
              VectorBatchPattern.createRepeatedBatch(
                  random, randomRowCount, bitSet, asSelected));
          columnPermutation++;
          rowIndex = rowLimit;
        }

        if (asSelected) {
          break;
        }
        asSelected = true;
      }

      // Remaining batches.
      while (true) {
        final int maximumRowCount = Math.min(rowCount - rowIndex, VectorizedRowBatch.DEFAULT_SIZE);
        if (maximumRowCount == 0) {
          break;
        }
        int randomRowCount = 1 + random.nextInt(maximumRowCount);
        asSelected = random.nextBoolean();
        vectorBatchPatternList.add(
            VectorBatchPattern.createRegularBatch(
                random, randomRowCount, asSelected));
        rowIndex += randomRowCount;
      }
    }

    // System.out.println("*DEBUG* vectorBatchPatternList" + vectorBatchPatternList.toString());

    return new VectorBatchPatterns(vectorBatchPatternList);
  }
Generate random batch source from a random Object[] row source (VectorRandomRowSource).
ql/src/test/org/apache/hadoop/hive/ql/exec/vector/VectorRandomBatchSource.java