@Override public Aggregate copy(RelTraitSet traitSet, RelNode input, boolean indicator, ImmutableBitSet groupSet, List<ImmutableBitSet> groupSets, List<AggregateCall> aggCalls) { try { return new HashAggPrel(getCluster(), traitSet, input, indicator, groupSet, groupSets, aggCalls, this.getOperatorPhase()); } catch (InvalidRelException e) { throw new AssertionError(e); } }
private boolean canVectorize(PhysicalPlanCreator creator, PhysicalOperator child){ if(canVectorize == null){ canVectorize = initialCanVectorize(creator, child); } return canVectorize; }
@Override public RelNode convertChild(AggregateRel aggregate, RelNode input) throws InvalidRelException { RelTraitSet traits = newTraitSet(Prel.PHYSICAL, input.getTraitSet().getTrait(DistributionTraitDef.INSTANCE)); RelNode newInput = convert(input, traits); HashAggPrel phase1Agg = new HashAggPrel( aggregate.getCluster(), traits, newInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of2); HashToRandomExchangePrel exch = new HashToRandomExchangePrel(phase1Agg.getCluster(), phase1Agg.getTraitSet().plus(Prel.PHYSICAL).plus(distOnAllKeys), phase1Agg, ImmutableList.copyOf(getDistributionField(aggregate, true))); HashAggPrel phase2Agg = new HashAggPrel( aggregate.getCluster(), exch.getTraitSet(), exch, aggregate.indicator, phase1Agg.getPhase2GroupSet(), null, phase1Agg.getPhase2AggCalls(), OperatorPhase.PHASE_2of2); return phase2Agg; } }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if(PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner).multiplyBy(.1); } final RelNode child = this.getInput(); double inputRows = mq.getRowCount(child); int numGroupByFields = this.getGroupCount(); int numAggrFields = this.aggCalls.size(); // cpu cost of hashing each grouping key double cpuCost = DremioCost.HASH_CPU_COST * numGroupByFields * inputRows; // add cpu cost for computing the aggregate functions cpuCost += DremioCost.FUNC_CPU_COST * numAggrFields * inputRows; double diskIOCost = 0; // assume in-memory for now until we enforce operator-level memory constraints // TODO: use distinct row count // + hash table template stuff double factor = PrelUtil.getPlannerSettings(planner).getOptions() .getOption(ExecConstants.HASH_AGG_TABLE_FACTOR_KEY).getFloatVal(); long fieldWidth = PrelUtil.getPlannerSettings(planner).getOptions() .getOption(ExecConstants.AVERAGE_FIELD_WIDTH_KEY).getNumVal(); // table + hashValues + links double memCost = ( (fieldWidth * numGroupByFields) + IntHolder.WIDTH + IntHolder.WIDTH ) * inputRows * factor; Factory costFactory = (Factory) planner.getCostFactory(); return costFactory.makeCost(inputRows, cpuCost, diskIOCost, 0 /* network cost */, memCost); }
@Override public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException { PhysicalOperator child = ((Prel) this.getInput()).getPhysicalOperator(creator); HashAggregate g = new HashAggregate(child, keys, aggExprs, canVectorize(creator, child), 1.0f); return creator.addMetadata(this, g); }
private void createTransformRequest(RelOptRuleCall call, AggregateRel aggregate, RelNode input, RelTraitSet traits) throws InvalidRelException { final RelNode convertedInput = convert(input, PrelUtil.fixTraits(call, traits)); HashAggPrel newAgg = new HashAggPrel( aggregate.getCluster(), traits, convertedInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of1); call.transformTo(newAgg); }