@Override
    public void initialize(Configuration hconf) throws HiveException {
      // hconf is null in unit testing
      if (null != hconf) {
        this.percentEntriesToFlush = HiveConf.getFloatVar(hconf,
          HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_FLUSH_PERCENT);
        this.checkInterval = HiveConf.getIntVar(hconf,
          HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_CHECKINTERVAL);
        this.maxHtEntries = HiveConf.getIntVar(hconf,
          HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_MAXENTRIES);
        this.numRowsCompareHashAggr = HiveConf.getIntVar(hconf,
          HiveConf.ConfVars.HIVE_GROUPBY_MAP_INTERVAL);
      }
      else {
        this.percentEntriesToFlush =
            HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_FLUSH_PERCENT.defaultFloatVal;
        this.checkInterval =
            HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_CHECKINTERVAL.defaultIntVal;
        this.maxHtEntries =
            HiveConf.ConfVars.HIVE_VECTORIZATION_GROUPBY_MAXENTRIES.defaultIntVal;
        this.numRowsCompareHashAggr =
            HiveConf.ConfVars.HIVE_GROUPBY_MAP_INTERVAL.defaultIntVal;
      }

      minReductionHashAggr = getConf().getMinReductionHashAggr();

      sumBatchSize = 0;

      mapKeysAggregationBuffers = new HashMap<KeyWrapper, VectorAggregationBufferRow>();
      /*
       * The grouping sets expand the hash sizes by producing intermediate keys. 3 grouping sets
       * of (),(col1),(col1,col2), will turn 10 rows into 30 rows. If the col1 has an nDV of 2 and
       * col2 has nDV of 5, then this turns into a maximum of 1+3+(2*5) or 14 keys into the
       * hashtable.
       *
       * So you get 10 rows in and 14 rows out, which is a reduction of ~2x vs Streaming mode,
       * but it is an increase if the grouping-set is not accounted for.
       *
       * For performance, it is definitely better to send 14 rows out to shuffle and not 30.
       *
       * Particularly if the same nDVs are repeated for a thousand rows, this would send a
       * thousand rows via streaming to a single reducer which owns the empty grouping set,
       * instead of sending 1 from the hash.
       *
       */
      if (groupingSets != null && groupingSets.length > 0) {
        /**
         * Adjust for grouping sets. For grouping sets, input records are processed 'n' number of times.
         * Ref processBatch(). Ensure that reduction is super effective, otherwise they become
         * memory intensive.
         */
        this.minReductionHashAggr = this.minReductionHashAggr / groupingSets.length;
        LOG.info("New maxHtEntries: {}, groupingSets len: {}, numRowsCompareHashAggr: {}, "
                + "minReductionHashAggr:{} ", maxHtEntries, groupingSets.length,
            numRowsCompareHashAggr, minReductionHashAggr);
      }
      computeMemoryLimits();
      LOG.debug("using hash aggregation processing mode");

      if (keyWrappersBatch.getVectorHashKeyWrappers()[0] instanceof VectorHashKeyWrapperGeneral) {
        reusableKeyWrapperBuffer = new ArrayDeque<>(VectorizedRowBatch.DEFAULT_SIZE);
      }
    }
Number of rows processed between checks for minReductionHashAggr factor
TODO: there is overlap between numRowsCompareHashAggr and checkInterval
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/VectorGroupByOperator.java