private int getReducersBucketing(int totalFiles, int maxReducers) {
    int numFiles = (int)Math.ceil((double)totalFiles / (double)maxReducers);
    while (true) {
      if (totalFiles % numFiles == 0) {
        return totalFiles / numFiles;
      }
      numFiles++;
    }
  }
Generate a Group-By plan using a 2 map-reduce jobs. However, only 1
group-by plan is generated if the query involves no grouping key and no
distincts. In that case, the plan is same as generated by
genGroupByPlanMapAggr1MR. Otherwise, the following plan is generated: First
perform a map side partial aggregation (to reduce the amount of data). Then
spray by the grouping key and distinct key (or a random number, if no
distinct is present) in hope of getting a uniform distribution, and compute
partial aggregates grouped by the reduction key (grouping key + distinct
key). Evaluate partial aggregates first, and spray by the grouping key to
compute actual aggregates in the second phase.

The aggregation evaluation functions are as follows:

No grouping sets:
STAGE 1
Group by Operator:
grouping keys: group by expressions if no DISTINCT
grouping keys: group by expressions + distinct keys if DISTINCT
Mapper: iterate/terminatePartial (mode = HASH)
Partitioning Key: random() if no DISTINCT
grouping + distinct key if DISTINCT
Sorting Key: grouping key if no DISTINCT
grouping + distinct key if DISTINCT
Reducer: iterate/terminatePartial if DISTINCT
merge/terminatePartial if NO DISTINCT (mode = MERGEPARTIAL)
Group by Operator:
grouping keys: group by expressions

STAGE 2
Partitioning Key: grouping key
Sorting Key: grouping key
Reducer: merge/terminate (mode = FINAL)

In the presence of grouping sets, the aggregation evaluation functions are as follows:
STAGE 1
Group by Operator:
grouping keys: group by expressions + grouping id. if no DISTINCT
grouping keys: group by expressions + + grouping id. + distinct keys if DISTINCT
Mapper: iterate/terminatePartial (mode = HASH)
Partitioning Key: random() if no DISTINCT
grouping + grouping id. + distinct key if DISTINCT
Sorting Key: grouping key + grouping id. if no DISTINCT
grouping + grouping id. + distinct key if DISTINCT
Reducer: iterate/terminatePartial if DISTINCT
merge/terminatePartial if NO DISTINCT (mode = MERGEPARTIAL)
Group by Operator:
grouping keys: group by expressions + grouping id.

STAGE 2
Partitioning Key: grouping key
Sorting Key: grouping key + grouping id.
Reducer: merge/terminate (mode = FINAL)
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java