@Override public SingleInputPlanNode instantiate(Channel in, SingleInputNode node) { if (in.getShipStrategy() == ShipStrategyType.FORWARD) { // adjust a sort (changes grouping, so it must be for this driver to combining sort if (in.getLocalStrategy() == LocalStrategy.SORT) { if (!in.getLocalStrategyKeys().isValidUnorderedPrefix(this.keys)) { throw new RuntimeException("Bug: Inconsistent sort for group strategy."); } in.setLocalStrategy( LocalStrategy.COMBININGSORT, in.getLocalStrategyKeys(), in.getLocalStrategySortOrder()); } return new SingleInputPlanNode( node, "Reduce(" + node.getOperator().getName() + ")", in, DriverStrategy.SORTED_GROUP_REDUCE, this.keyList); } else { // non forward case. all local properties are killed anyways, so we can safely plug in a // combiner Channel toCombiner = new Channel(in.getSource()); toCombiner.setShipStrategy(ShipStrategyType.FORWARD, DataExchangeMode.PIPELINED); // create an input node for combine with same parallelism as input node GroupReduceNode combinerNode = ((GroupReduceNode) node).getCombinerUtilityNode(); combinerNode.setParallelism(in.getSource().getParallelism()); SingleInputPlanNode combiner = new SingleInputPlanNode( combinerNode, "Combine(" + node.getOperator().getName() + ")", toCombiner, DriverStrategy.SORTED_GROUP_COMBINE); combiner.setCosts(new Costs(0, 0)); combiner.initProperties(toCombiner.getGlobalProperties(), toCombiner.getLocalProperties()); // set sorting comparator key info combiner.setDriverKeyInfo(in.getLocalStrategyKeys(), in.getLocalStrategySortOrder(), 0); // set grouping comparator key info combiner.setDriverKeyInfo(this.keyList, 1); Channel toReducer = new Channel(combiner); toReducer.setShipStrategy( in.getShipStrategy(), in.getShipStrategyKeys(), in.getShipStrategySortOrder(), in.getDataExchangeMode()); if (in.getShipStrategy() == ShipStrategyType.PARTITION_RANGE) { toReducer.setDataDistribution(in.getDataDistribution()); } toReducer.setLocalStrategy( LocalStrategy.COMBININGSORT, in.getLocalStrategyKeys(), in.getLocalStrategySortOrder()); return new SingleInputPlanNode( node, "Reduce (" + node.getOperator().getName() + ")", toReducer, DriverStrategy.SORTED_GROUP_REDUCE, this.keyList); } }