@Override public RelNode copy(RelTraitSet traitSet, List<RelNode> inputs) { return new HashToMergeExchangePrel(getCluster(), traitSet, sole(inputs), distFields, this.collation, numEndPoints); }
@Override public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) { if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) { return super.computeSelfCost(planner).multiplyBy(.1); } RelNode child = this.getInput(); double inputRows = mq.getRowCount(child); int rowWidth = child.getRowType().getFieldCount() * DremioCost.AVG_FIELD_WIDTH; double hashCpuCost = DremioCost.HASH_CPU_COST * inputRows * distFields.size(); double svrCpuCost = DremioCost.SVR_CPU_COST * inputRows; double mergeCpuCost = DremioCost.COMPARE_CPU_COST * inputRows * (Math.log(numEndPoints)/Math.log(2)); double networkCost = DremioCost.BYTE_NETWORK_COST * inputRows * rowWidth; Factory costFactory = (Factory)planner.getCostFactory(); return costFactory.makeCost(inputRows, hashCpuCost + svrCpuCost + mergeCpuCost, 0, networkCost); }
new HashToMergeExchangePrel(phase1Agg.getCluster(), phase1Agg.getTraitSet().plus(Prel.PHYSICAL).plus(distOnAllKeys), phase1Agg, ImmutableList.copyOf(getDistributionField(aggregate, true)), getOutputCollation(aggregate), exch.getTraitSet(), exch, aggregate.indicator,
@Override public Prel visitExchange(ExchangePrel prel, Void value) throws RuntimeException { Prel child = ((Prel)prel.getInput()).accept(this, null); // check if the hash expression has already been added for this particular exchange if (!child.getRowType().getFieldNames().contains(HashPrelUtil.HASH_EXPR_NAME)) { if (prel instanceof HashToMergeExchangePrel) { return visit(prel, ((HashToMergeExchangePrel) prel).getDistFields(), child); } if (prel instanceof HashToRandomExchangePrel) { return visit(prel, ((HashToRandomExchangePrel) prel).getFields(), child); } } return (Prel) prel.copy(prel.getTraitSet(), Collections.singletonList(((RelNode)child))); }
public PhysicalOperator getPhysicalOperator(PhysicalPlanCreator creator) throws IOException { Prel child = (Prel) this.getInput(); PhysicalOperator childPOP = child.getPhysicalOperator(creator); HashToMergeExchange g = new HashToMergeExchange(childPOP, HashPrelUtil.getHashExpression(this.distFields, getInput().getRowType()), PrelUtil.getOrdering(this.collation, getInput().getRowType())); return creator.addMetadata(this, g); }
@Override public PrelWithDictionaryInfo visitExchange(ExchangePrel exchangePrel, Void value) throws RuntimeException { assert exchangePrel.getInputs().size() == 1; PrelWithDictionaryInfo newInput = ((Prel)exchangePrel.getInput()).accept(this, value); if (exchangePrel.getInput() == newInput.getPrel()) { return new PrelWithDictionaryInfo(exchangePrel); // none of fields are encoded } if (exchangePrel instanceof HashToMergeExchangePrel || exchangePrel instanceof HashToRandomExchangePrel) { final List<DistributionField> distributionFields; if (exchangePrel instanceof HashToMergeExchangePrel) { distributionFields = ((HashToMergeExchangePrel) exchangePrel).getDistFields(); } else { distributionFields = ((HashToRandomExchangePrel) exchangePrel).getFields(); } // decode used inputs by this filter newInput = newInput.decodeFields(Lists.transform(distributionFields, new Function<DistributionField, Integer>() { @Override public Integer apply(DistributionField input) { return input.getFieldId(); } })); } // pass thr rest of exchanges, exchange uses child input's row data type. return new PrelWithDictionaryInfo( (Prel)exchangePrel.copy(exchangePrel.getTraitSet(), Collections.<RelNode>singletonList(newInput.getPrel())), newInput.getFields()); }