blob: 2a28d2e6d869e19fa34d91cca8f995064685827a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.hyracks.algebricks.core.rewriter.base;
import java.util.List;
import org.apache.commons.lang3.mutable.Mutable;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.common.utils.Pair;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan;
import org.apache.hyracks.algebricks.core.algebra.base.IOptimizationContext;
import org.apache.hyracks.algebricks.core.algebra.base.PhysicalOperatorTag;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
import org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans;
import org.apache.hyracks.algebricks.core.algebra.prettyprint.PlanPrettyPrinter;
import org.apache.hyracks.algebricks.core.config.AlgebricksConfig;
public class HeuristicOptimizer {
public static PhysicalOperatorTag[] hyracksOperators = new PhysicalOperatorTag[] {
PhysicalOperatorTag.DATASOURCE_SCAN, PhysicalOperatorTag.BTREE_SEARCH,
PhysicalOperatorTag.EXTERNAL_GROUP_BY, PhysicalOperatorTag.HASH_GROUP_BY, PhysicalOperatorTag.HDFS_READER,
PhysicalOperatorTag.HYBRID_HASH_JOIN, PhysicalOperatorTag.IN_MEMORY_HASH_JOIN,
PhysicalOperatorTag.NESTED_LOOP, PhysicalOperatorTag.PRE_SORTED_DISTINCT_BY,
PhysicalOperatorTag.PRE_CLUSTERED_GROUP_BY, PhysicalOperatorTag.SPLIT, PhysicalOperatorTag.STABLE_SORT,
PhysicalOperatorTag.UNION_ALL };
public static PhysicalOperatorTag[] hyraxOperatorsBelowWhichJobGenIsDisabled = new PhysicalOperatorTag[] {};
public static boolean isHyracksOp(PhysicalOperatorTag opTag) {
for (PhysicalOperatorTag t : hyracksOperators) {
if (t == opTag) {
return true;
}
}
return false;
}
private IOptimizationContext context;
private List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> logicalRewrites;
private List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> physicalRewrites;
private ILogicalPlan plan;
public HeuristicOptimizer(ILogicalPlan plan,
List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> logicalRewrites,
List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> physicalRewrites,
IOptimizationContext context) {
this.plan = plan;
this.context = context;
this.logicalRewrites = logicalRewrites;
this.physicalRewrites = physicalRewrites;
}
public void optimize() throws AlgebricksException {
if (plan == null) {
return;
}
if (AlgebricksConfig.DEBUG) {
AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Starting logical optimizations.\n");
}
StringBuilder sb = new StringBuilder();
PlanPrettyPrinter.printPlan(plan, sb, context.getPrettyPrintVisitor(), 0);
AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Logical Plan:\n" + sb.toString());
runOptimizationSets(plan, logicalRewrites);
computeSchemaBottomUpForPlan(plan);
runPhysicalOptimizations(plan, physicalRewrites);
StringBuilder sb2 = new StringBuilder();
PlanPrettyPrinter.printPlan(plan, sb2, context.getPrettyPrintVisitor(), 0);
AlgebricksConfig.ALGEBRICKS_LOGGER.info("Optimized Plan:\n" + sb2.toString());
}
private void runOptimizationSets(ILogicalPlan plan,
List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> optimSet) throws AlgebricksException {
for (Pair<AbstractRuleController, List<IAlgebraicRewriteRule>> ruleList : optimSet) {
for (Mutable<ILogicalOperator> r : plan.getRoots()) {
ruleList.first.setContext(context);
ruleList.first.rewriteWithRuleCollection(r, ruleList.second);
}
}
}
private static void computeSchemaBottomUpForPlan(ILogicalPlan p) throws AlgebricksException {
for (Mutable<ILogicalOperator> r : p.getRoots()) {
computeSchemaBottomUpForOp((AbstractLogicalOperator) r.getValue());
}
}
private static void computeSchemaBottomUpForOp(AbstractLogicalOperator op) throws AlgebricksException {
for (Mutable<ILogicalOperator> i : op.getInputs()) {
computeSchemaBottomUpForOp((AbstractLogicalOperator) i.getValue());
}
if (op.hasNestedPlans()) {
AbstractOperatorWithNestedPlans a = (AbstractOperatorWithNestedPlans) op;
for (ILogicalPlan p : a.getNestedPlans()) {
computeSchemaBottomUpForPlan(p);
}
}
op.recomputeSchema();
}
private void runPhysicalOptimizations(ILogicalPlan plan,
List<Pair<AbstractRuleController, List<IAlgebraicRewriteRule>>> physicalRewrites)
throws AlgebricksException {
if (AlgebricksConfig.DEBUG) {
AlgebricksConfig.ALGEBRICKS_LOGGER.fine("Starting physical optimizations.\n");
}
// PhysicalOptimizationsUtil.computeFDsAndEquivalenceClasses(plan);
runOptimizationSets(plan, physicalRewrites);
}
}