use of org.apache.calcite.rel.RelNode in project drill by apache.
the class SingleMergeExchangePrel method computeSelfCost.
/**
* A SingleMergeExchange processes a total of M rows coming from N
* sorted input streams (from N senders) and merges them into a single
* output sorted stream. For costing purposes we can assume each sender
* is sending M/N rows to a single receiver.
* (See DrillCostBase for symbol notations)
* C = CPU cost of SV remover for M/N rows
* + Network cost of sending M/N rows to 1 destination.
* So, C = (s * M/N) + (w * M/N)
* Cost of merging M rows coming from N senders = (M log2 N) * c
* Total cost = N * C + (M log2 N) * c
*/
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
return super.computeSelfCost(planner, mq).multiplyBy(.1);
}
RelNode child = this.getInput();
double inputRows = mq.getRowCount(child);
int rowWidth = child.getRowType().getFieldCount() * DrillCostBase.AVG_FIELD_WIDTH;
double svrCpuCost = DrillCostBase.SVR_CPU_COST * inputRows;
double networkCost = DrillCostBase.BYTE_NETWORK_COST * inputRows * rowWidth;
int numEndPoints = PrelUtil.getSettings(getCluster()).numEndPoints();
double mergeCpuCost = DrillCostBase.COMPARE_CPU_COST * inputRows * (Math.log(numEndPoints) / Math.log(2));
DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
return costFactory.makeCost(inputRows, svrCpuCost + mergeCpuCost, 0, networkCost);
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class SortPrel method computeSelfCost.
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
//We use multiplier 0.05 for TopN operator, and 0.1 for Sort, to make TopN a preferred choice.
return super.computeSelfCost(planner, mq).multiplyBy(.1);
}
RelNode child = this.getInput();
double inputRows = mq.getRowCount(child);
// int rowWidth = child.getRowType().getPrecision();
int numSortFields = this.collation.getFieldCollations().size();
double cpuCost = DrillCostBase.COMPARE_CPU_COST * numSortFields * inputRows * (Math.log(inputRows) / Math.log(2));
// assume in-memory for now until we enforce operator-level memory constraints
double diskIOCost = 0;
// TODO: use rowWidth instead of avgFieldWidth * numFields
// avgFieldWidth * numFields * inputRows
double numFields = this.getRowType().getFieldCount();
long fieldWidth = PrelUtil.getPlannerSettings(planner).getOptions().getOption(ExecConstants.AVERAGE_FIELD_WIDTH_KEY).num_val;
double memCost = fieldWidth * numFields * inputRows;
DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
return costFactory.makeCost(inputRows, cpuCost, diskIOCost, 0, memCost);
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class ProjectPrule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final DrillProjectRel project = (DrillProjectRel) call.rel(0);
final RelNode input = project.getInput();
RelTraitSet traits = input.getTraitSet().plus(Prel.DRILL_PHYSICAL);
RelNode convertedInput = convert(input, traits);
// Maintain two different map for distribution trait and collation trait.
// For now, the only difference comes from the way how cast function impacts propagating trait.
final Map<Integer, Integer> distributionMap = getDistributionMap(project);
final Map<Integer, Integer> collationMap = getCollationMap(project);
boolean traitPull = new ProjectTraitPull(call, distributionMap, collationMap).go(project, convertedInput);
if (!traitPull) {
call.transformTo(new ProjectPrel(project.getCluster(), convertedInput.getTraitSet(), convertedInput, project.getProjects(), project.getRowType()));
}
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class StreamAggPrel method computeSelfCost.
@Override
public RelOptCost computeSelfCost(RelOptPlanner planner, RelMetadataQuery mq) {
if (PrelUtil.getSettings(getCluster()).useDefaultCosting()) {
return super.computeSelfCost(planner, mq).multiplyBy(.1);
}
RelNode child = this.getInput();
double inputRows = mq.getRowCount(child);
int numGroupByFields = this.getGroupCount();
int numAggrFields = this.aggCalls.size();
double cpuCost = DrillCostBase.COMPARE_CPU_COST * numGroupByFields * inputRows;
// add cpu cost for computing the aggregate functions
cpuCost += DrillCostBase.FUNC_CPU_COST * numAggrFields * inputRows;
DrillCostFactory costFactory = (DrillCostFactory) planner.getCostFactory();
return costFactory.makeCost(inputRows, cpuCost, 0, /* disk i/o cost */
0);
}
use of org.apache.calcite.rel.RelNode in project drill by apache.
the class StreamAggPrule method onMatch.
@Override
public void onMatch(RelOptRuleCall call) {
final DrillAggregateRel aggregate = (DrillAggregateRel) call.rel(0);
RelNode input = aggregate.getInput();
final RelCollation collation = getCollation(aggregate);
RelTraitSet traits = null;
if (aggregate.containsDistinctCall()) {
// currently, don't use StreamingAggregate if any of the logical aggrs contains DISTINCT
return;
}
try {
if (aggregate.getGroupSet().isEmpty()) {
DrillDistributionTrait singleDist = DrillDistributionTrait.SINGLETON;
final RelTraitSet singleDistTrait = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(singleDist);
if (create2PhasePlan(call, aggregate)) {
traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL);
RelNode convertedInput = convert(input, traits);
new SubsetTransformer<DrillAggregateRel, InvalidRelException>(call) {
@Override
public RelNode convertChild(final DrillAggregateRel join, final RelNode rel) throws InvalidRelException {
DrillDistributionTrait toDist = rel.getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE);
RelTraitSet traits = newTraitSet(Prel.DRILL_PHYSICAL, toDist);
RelNode newInput = convert(rel, traits);
StreamAggPrel phase1Agg = new StreamAggPrel(aggregate.getCluster(), traits, newInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of2);
UnionExchangePrel exch = new UnionExchangePrel(phase1Agg.getCluster(), singleDistTrait, phase1Agg);
return new StreamAggPrel(aggregate.getCluster(), singleDistTrait, exch, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), phase1Agg.getPhase2AggCalls(), OperatorPhase.PHASE_2of2);
}
}.go(aggregate, convertedInput);
} else {
createTransformRequest(call, aggregate, input, singleDistTrait);
}
} else {
// hash distribute on all grouping keys
final DrillDistributionTrait distOnAllKeys = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(aggregate, true)));
traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnAllKeys);
createTransformRequest(call, aggregate, input, traits);
// hash distribute on one grouping key
DrillDistributionTrait distOnOneKey = new DrillDistributionTrait(DrillDistributionTrait.DistributionType.HASH_DISTRIBUTED, ImmutableList.copyOf(getDistributionField(aggregate, false)));
traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL).plus(collation).plus(distOnOneKey);
if (create2PhasePlan(call, aggregate)) {
traits = call.getPlanner().emptyTraitSet().plus(Prel.DRILL_PHYSICAL);
RelNode convertedInput = convert(input, traits);
new SubsetTransformer<DrillAggregateRel, InvalidRelException>(call) {
@Override
public RelNode convertChild(final DrillAggregateRel aggregate, final RelNode rel) throws InvalidRelException {
DrillDistributionTrait toDist = rel.getTraitSet().getTrait(DrillDistributionTraitDef.INSTANCE);
RelTraitSet traits = newTraitSet(Prel.DRILL_PHYSICAL, collation, toDist);
RelNode newInput = convert(rel, traits);
StreamAggPrel phase1Agg = new StreamAggPrel(aggregate.getCluster(), traits, newInput, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), aggregate.getAggCallList(), OperatorPhase.PHASE_1of2);
int numEndPoints = PrelUtil.getSettings(phase1Agg.getCluster()).numEndPoints();
HashToMergeExchangePrel exch = new HashToMergeExchangePrel(phase1Agg.getCluster(), phase1Agg.getTraitSet().plus(Prel.DRILL_PHYSICAL).plus(distOnAllKeys), phase1Agg, ImmutableList.copyOf(getDistributionField(aggregate, true)), collation, numEndPoints);
return new StreamAggPrel(aggregate.getCluster(), exch.getTraitSet(), exch, aggregate.indicator, aggregate.getGroupSet(), aggregate.getGroupSets(), phase1Agg.getPhase2AggCalls(), OperatorPhase.PHASE_2of2);
}
}.go(aggregate, convertedInput);
}
}
} catch (InvalidRelException e) {
tracer.warning(e.toString());
}
}
Aggregations