Merged hyracks master back into VXQuery branch.
diff --git a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java
new file mode 100644
index 0000000..efcc7a8
--- /dev/null
+++ b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablePolicy.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ * 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 edu.uci.ics.hyracks.algebricks.rewriter.rules;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang3.mutable.Mutable;
+
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.ILogicalOperator;
+import edu.uci.ics.hyracks.algebricks.core.algebra.base.LogicalExpressionTag;
+import edu.uci.ics.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator;
+
+/**
+ * Where assign operators only assign a new variable ID for a reference expression,
+ * all references are updated to the first variable ID.
+ */
+public class InlineVariablePolicy implements InlineVariablesRule.IInlineVariablePolicy {
+
+ @Override
+ public boolean isCandidateForInlining(ILogicalExpression expr) {
+ if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public List<Mutable<ILogicalOperator>> descendIntoNextOperator(AbstractLogicalOperator op) {
+ List<Mutable<ILogicalOperator>> descendOp = new ArrayList<Mutable<ILogicalOperator>>();
+ // Descend into children removing projects on the way.
+ for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
+ descendOp.add(inputOpRef);
+ }
+ return descendOp;
+ }
+
+ @Override
+ public boolean isCanidateInlineTarget(AbstractLogicalOperator op) {
+ // Only inline variables in operators that can deal with arbitrary expressions.
+ if (!op.requiresVariableReferenceExpressions()) {
+ return true;
+ }
+ return false;
+ }
+
+}
diff --git a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
index 40b049b..aae74d8 100644
--- a/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
+++ b/algebricks/algebricks-rewriter/src/main/java/edu/uci/ics/hyracks/algebricks/rewriter/rules/InlineVariablesRule.java
@@ -47,19 +47,19 @@
* (e.g., a select may be pushed into a join to enable an efficient physical join operator).
*
* Preconditions/Assumptions:
- * Assumes no projects are in the plan. Only inlines variables whose assigned expression is a function call
- * (i.e., this rule ignores right-hand side constants and other variable references expressions
+ * Assumes no projects are in the plan. Only inlines variables whose assigned expression is a function call
+ * (i.e., this rule ignores right-hand side constants and other variable references expressions
*
* Postconditions/Examples:
* All qualifying variables have been inlined.
- *
+ *
* Example (simplified):
- *
+ *
* Before plan:
* select <- [$$1 < $$2 + $$0]
* assign [$$2] <- [funcZ() + $$0]
* assign [$$0, $$1] <- [funcX(), funcY()]
- *
+ *
* After plan:
* select <- [funcY() < funcZ() + funcX() + funcX()]
* assign [$$2] <- [funcZ() + funcX()]
@@ -73,12 +73,22 @@
// Visitor for replacing variable reference expressions with their originating expression.
protected InlineVariablesVisitor inlineVisitor = new InlineVariablesVisitor(varAssignRhs);
-
+
// Set of FunctionIdentifiers that we should not inline.
protected Set<FunctionIdentifier> doNotInlineFuncs = new HashSet<FunctionIdentifier>();
-
+
protected boolean hasRun = false;
-
+
+ protected IInlineVariablePolicy policy;
+
+ public InlineVariablesRule() {
+ policy = new InlineVariablePolicy();
+ }
+
+ public InlineVariablesRule(IInlineVariablePolicy policy) {
+ this.policy = policy;
+ }
+
@Override
public boolean rewritePost(Mutable<ILogicalOperator> opRef, IOptimizationContext context) {
return false;
@@ -100,15 +110,14 @@
hasRun = true;
return modified;
}
-
+
protected void prepare(IOptimizationContext context) {
varAssignRhs.clear();
inlineVisitor.setContext(context);
}
-
+
protected boolean performBottomUpAction(AbstractLogicalOperator op) throws AlgebricksException {
- // Only inline variables in operators that can deal with arbitrary expressions.
- if (!op.requiresVariableReferenceExpressions()) {
+ if (policy.isCanidateInlineTarget(op)) {
inlineVisitor.setOperator(op);
return op.acceptExpressionTransform(inlineVisitor);
}
@@ -118,41 +127,43 @@
protected boolean performFinalAction() throws AlgebricksException {
return false;
}
-
+
protected boolean inlineVariables(Mutable<ILogicalOperator> opRef, IOptimizationContext context)
throws AlgebricksException {
AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
-
+
// Update mapping from variables to expressions during top-down traversal.
if (op.getOperatorTag() == LogicalOperatorTag.ASSIGN) {
AssignOperator assignOp = (AssignOperator) op;
List<LogicalVariable> vars = assignOp.getVariables();
- List<Mutable<ILogicalExpression>> exprs = assignOp.getExpressions();
+ List<Mutable<ILogicalExpression>> exprs = assignOp.getExpressions();
for (int i = 0; i < vars.size(); i++) {
ILogicalExpression expr = exprs.get(i).getValue();
- // Ignore functions that are in the doNotInline set.
- if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
- AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
- if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier())) {
- continue;
+ if (policy.isCandidateForInlining(expr)) {
+ // Ignore functions that are in the doNotInline set.
+ if (expr.getExpressionTag() == LogicalExpressionTag.FUNCTION_CALL) {
+ AbstractFunctionCallExpression funcExpr = (AbstractFunctionCallExpression) expr;
+ if (doNotInlineFuncs.contains(funcExpr.getFunctionIdentifier())) {
+ continue;
+ }
}
+ varAssignRhs.put(vars.get(i), exprs.get(i).getValue());
}
- varAssignRhs.put(vars.get(i), exprs.get(i).getValue());
}
}
- // Descend into children removing projects on the way.
boolean modified = false;
- for (Mutable<ILogicalOperator> inputOpRef : op.getInputs()) {
+ // Follow all operators from this operator.
+ for (Mutable<ILogicalOperator> inputOpRef : policy.descendIntoNextOperator(op)) {
if (inlineVariables(inputOpRef, context)) {
modified = true;
- }
+ }
}
if (performBottomUpAction(op)) {
modified = true;
}
-
+
if (modified) {
context.computeAndSetTypeEnvironmentForOperator(op);
context.addToDontApplySet(this, op);
@@ -164,23 +175,23 @@
}
protected class InlineVariablesVisitor implements ILogicalExpressionReferenceTransform {
-
+
private final Map<LogicalVariable, ILogicalExpression> varAssignRhs;
private final Set<LogicalVariable> liveVars = new HashSet<LogicalVariable>();
- private final List<LogicalVariable> rhsUsedVars = new ArrayList<LogicalVariable>();
+ private final List<LogicalVariable> rhsUsedVars = new ArrayList<LogicalVariable>();
private ILogicalOperator op;
private IOptimizationContext context;
// If set, only replace this variable reference.
private LogicalVariable targetVar;
-
+
public InlineVariablesVisitor(Map<LogicalVariable, ILogicalExpression> varAssignRhs) {
this.varAssignRhs = varAssignRhs;
}
-
+
public void setTargetVariable(LogicalVariable targetVar) {
this.targetVar = targetVar;
}
-
+
public void setContext(IOptimizationContext context) {
this.context = context;
}
@@ -189,9 +200,9 @@
this.op = op;
liveVars.clear();
}
-
+
@Override
- public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {
+ public boolean transform(Mutable<ILogicalExpression> exprRef) throws AlgebricksException {
ILogicalExpression e = exprRef.getValue();
switch (((AbstractLogicalExpression) e).getExpressionTag()) {
case VARIABLE: {
@@ -209,7 +220,7 @@
// Variable was not produced by an assign.
return false;
}
-
+
// Make sure used variables from rhs are live.
if (liveVars.isEmpty()) {
VariableUtilities.getLiveVariables(op, liveVars);
@@ -221,7 +232,7 @@
return false;
}
}
-
+
// Replace variable reference with a clone of the rhs expr.
exprRef.setValue(rhs.cloneExpression());
return true;
@@ -242,4 +253,15 @@
}
}
}
+
+ public static interface IInlineVariablePolicy {
+
+ public boolean isCandidateForInlining(ILogicalExpression expr);
+
+ public List<Mutable<ILogicalOperator>> descendIntoNextOperator(AbstractLogicalOperator op);
+
+ public boolean isCanidateInlineTarget(AbstractLogicalOperator op);
+
+ }
+
}
diff --git a/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java b/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
index 2ca7ccf..828f2fb 100644
--- a/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
+++ b/hyracks/hyracks-control/hyracks-control-common/src/main/java/edu/uci/ics/hyracks/control/common/application/ApplicationContext.java
@@ -31,7 +31,9 @@
protected IJobSerializerDeserializerContainer jobSerDeContainer = new JobSerializerDeserializerContainer();
protected ThreadFactory threadFactory = new ThreadFactory() {
public Thread newThread(Runnable r) {
- return new Thread(r);
+ Thread t = new Thread(r);
+ t.setDaemon(true);
+ return t;
}
};