Search in sources :

Example 26 with Mutable

use of org.apache.commons.lang3.mutable.Mutable in project asterixdb by apache.

the class EnforceStructuralPropertiesRule method physOptimizeOp.

private boolean physOptimizeOp(Mutable<ILogicalOperator> opRef, IPhysicalPropertiesVector required, boolean nestedPlan, IOptimizationContext context) throws AlgebricksException {
    boolean changed = false;
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    optimizeUsingConstraintsAndEquivClasses(op);
    PhysicalRequirements pr = op.getRequiredPhysicalPropertiesForChildren(required, context);
    IPhysicalPropertiesVector[] reqdProperties = null;
    if (pr != null) {
        reqdProperties = pr.getRequiredProperties();
    }
    boolean opIsRedundantSort = false;
    // compute properties and figure out the domain
    INodeDomain childrenDomain = null;
    {
        int j = 0;
        for (Mutable<ILogicalOperator> childRef : op.getInputs()) {
            AbstractLogicalOperator child = (AbstractLogicalOperator) childRef.getValue();
            // recursive call
            if (physOptimizeOp(childRef, reqdProperties[j], nestedPlan, context)) {
                changed = true;
            }
            child.computeDeliveredPhysicalProperties(context);
            IPhysicalPropertiesVector delivered = child.getDeliveredPhysicalProperties();
            if (childrenDomain == null) {
                childrenDomain = delivered.getPartitioningProperty().getNodeDomain();
            } else {
                INodeDomain dom2 = delivered.getPartitioningProperty().getNodeDomain();
                if (!childrenDomain.sameAs(dom2)) {
                    childrenDomain = context.getComputationNodeDomain();
                }
            }
            j++;
        }
    }
    if (reqdProperties != null) {
        for (int k = 0; k < reqdProperties.length; k++) {
            IPhysicalPropertiesVector pv = reqdProperties[k];
            IPartitioningProperty pp = pv.getPartitioningProperty();
            if (pp != null && pp.getNodeDomain() == null) {
                pp.setNodeDomain(childrenDomain);
            }
        }
    }
    // The child index of the child operator to optimize first.
    int startChildIndex = getStartChildIndex(op, pr, nestedPlan, context);
    IPartitioningProperty firstDeliveredPartitioning = null;
    // Enforce data properties in a top-down manner.
    for (int j = 0; j < op.getInputs().size(); j++) {
        // Starts from a partitioning-compatible child if any to loop over all children.
        int childIndex = (j + startChildIndex) % op.getInputs().size();
        IPhysicalPropertiesVector requiredProperty = reqdProperties[childIndex];
        AbstractLogicalOperator child = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
        IPhysicalPropertiesVector delivered = child.getDeliveredPhysicalProperties();
        AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Properties delivered by " + child.getPhysicalOperator() + ": " + delivered + "\n");
        IPartitioningRequirementsCoordinator prc = pr.getPartitioningCoordinator();
        // Coordinates requirements by looking at the firstDeliveredPartitioning.
        Pair<Boolean, IPartitioningProperty> pbpp = prc.coordinateRequirements(requiredProperty.getPartitioningProperty(), firstDeliveredPartitioning, op, context);
        boolean mayExpandPartitioningProperties = pbpp.first;
        IPhysicalPropertiesVector rqd = new StructuralPropertiesVector(pbpp.second, requiredProperty.getLocalProperties());
        AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> Required properties for " + child.getPhysicalOperator() + ": " + rqd + "\n");
        // The partitioning property of reqdProperties[childIndex] could be updated here because
        // rqd.getPartitioningProperty() is the same object instance as requiredProperty.getPartitioningProperty().
        IPhysicalPropertiesVector diff = delivered.getUnsatisfiedPropertiesFrom(rqd, mayExpandPartitioningProperties, context.getEquivalenceClassMap(child), context.getFDList(child));
        if (isRedundantSort(opRef, delivered, diff, context)) {
            opIsRedundantSort = true;
        }
        if (diff != null) {
            changed = true;
            addEnforcers(op, childIndex, diff, rqd, delivered, childrenDomain, nestedPlan, context);
            AbstractLogicalOperator newChild = (AbstractLogicalOperator) op.getInputs().get(childIndex).getValue();
            if (newChild != child) {
                delivered = newChild.getDeliveredPhysicalProperties();
                IPhysicalPropertiesVector newDiff = newPropertiesDiff(newChild, rqd, mayExpandPartitioningProperties, context);
                AlgebricksConfig.ALGEBRICKS_LOGGER.finest(">>>> New properties diff: " + newDiff + "\n");
                if (isRedundantSort(opRef, delivered, newDiff, context)) {
                    opIsRedundantSort = true;
                    break;
                }
            }
        }
        if (firstDeliveredPartitioning == null) {
            firstDeliveredPartitioning = delivered.getPartitioningProperty();
        }
    }
    if (op.hasNestedPlans()) {
        AbstractOperatorWithNestedPlans nested = (AbstractOperatorWithNestedPlans) op;
        for (ILogicalPlan p : nested.getNestedPlans()) {
            if (physOptimizePlan(p, required, true, context)) {
                changed = true;
            }
        }
    }
    if (opIsRedundantSort) {
        if (AlgebricksConfig.DEBUG) {
            AlgebricksConfig.ALGEBRICKS_LOGGER.fine(">>>> Removing redundant SORT operator " + op.getPhysicalOperator() + "\n");
            printOp(op);
        }
        changed = true;
        AbstractLogicalOperator nextOp = (AbstractLogicalOperator) op.getInputs().get(0).getValue();
        if (nextOp.getOperatorTag() == LogicalOperatorTag.PROJECT) {
            nextOp = (AbstractLogicalOperator) nextOp.getInputs().get(0).getValue();
        }
        opRef.setValue(nextOp);
        // Now, transfer annotations from the original sort op. to this one.
        AbstractLogicalOperator transferTo = nextOp;
        if (transferTo.getOperatorTag() == LogicalOperatorTag.EXCHANGE) {
            // remove duplicate exchange operator
            transferTo = (AbstractLogicalOperator) transferTo.getInputs().get(0).getValue();
        }
        transferTo.getAnnotations().putAll(op.getAnnotations());
        physOptimizeOp(opRef, required, nestedPlan, context);
    }
    return changed;
}
Also used : StructuralPropertiesVector(org.apache.hyracks.algebricks.core.algebra.properties.StructuralPropertiesVector) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) INodeDomain(org.apache.hyracks.algebricks.core.algebra.properties.INodeDomain) IPartitioningRequirementsCoordinator(org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningRequirementsCoordinator) IPhysicalPropertiesVector(org.apache.hyracks.algebricks.core.algebra.properties.IPhysicalPropertiesVector) PhysicalRequirements(org.apache.hyracks.algebricks.core.algebra.properties.PhysicalRequirements) IPartitioningProperty(org.apache.hyracks.algebricks.core.algebra.properties.IPartitioningProperty) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) AbstractOperatorWithNestedPlans(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractOperatorWithNestedPlans)

Example 27 with Mutable

use of org.apache.commons.lang3.mutable.Mutable in project asterixdb by apache.

the class ComplexUnnestToProductRule method insideSubplan.

/**
     * check whether the operator is inside a sub-plan
     *
     * @param nestedRootRef
     * @return true-if it is; false otherwise.
     */
private boolean insideSubplan(Mutable<ILogicalOperator> nestedRootRef) {
    AbstractLogicalOperator nestedRoot = (AbstractLogicalOperator) nestedRootRef.getValue();
    if (nestedRoot.getOperatorTag() == LogicalOperatorTag.NESTEDTUPLESOURCE) {
        return true;
    }
    List<Mutable<ILogicalOperator>> inputs = nestedRoot.getInputs();
    for (Mutable<ILogicalOperator> input : inputs) {
        if (insideSubplan(input)) {
            return true;
        }
    }
    return false;
}
Also used : Mutable(org.apache.commons.lang3.mutable.Mutable) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)

Example 28 with Mutable

use of org.apache.commons.lang3.mutable.Mutable in project asterixdb by apache.

the class CopyLimitDownRule method rewritePre.

@Override
public boolean rewritePre(Mutable<ILogicalOperator> opRef, IOptimizationContext context) throws AlgebricksException {
    AbstractLogicalOperator op = (AbstractLogicalOperator) opRef.getValue();
    if (op.getOperatorTag() != LogicalOperatorTag.LIMIT) {
        return false;
    }
    LimitOperator limitOp = (LimitOperator) op;
    if (!limitOp.isTopmostLimitOp()) {
        return false;
    }
    List<LogicalVariable> limitUsedVars = new ArrayList<>();
    VariableUtilities.getUsedVariables(limitOp, limitUsedVars);
    Mutable<ILogicalOperator> safeOpRef = null;
    Mutable<ILogicalOperator> candidateOpRef = limitOp.getInputs().get(0);
    List<LogicalVariable> candidateProducedVars = new ArrayList<>();
    while (true) {
        candidateProducedVars.clear();
        ILogicalOperator candidateOp = candidateOpRef.getValue();
        LogicalOperatorTag candidateOpTag = candidateOp.getOperatorTag();
        if (candidateOp.getInputs().size() > 1 || !candidateOp.isMap() || candidateOpTag == LogicalOperatorTag.SELECT || candidateOpTag == LogicalOperatorTag.LIMIT || candidateOpTag == LogicalOperatorTag.UNNEST_MAP || !OperatorPropertiesUtil.disjoint(limitUsedVars, candidateProducedVars)) {
            break;
        }
        safeOpRef = candidateOpRef;
        candidateOpRef = safeOpRef.getValue().getInputs().get(0);
    }
    if (safeOpRef != null) {
        ILogicalOperator safeOp = safeOpRef.getValue();
        Mutable<ILogicalOperator> unsafeOpRef = safeOp.getInputs().get(0);
        ILogicalOperator unsafeOp = unsafeOpRef.getValue();
        LimitOperator limitCloneOp = null;
        if (limitOp.getOffset().getValue() == null) {
            limitCloneOp = new LimitOperator(limitOp.getMaxObjects().getValue(), false);
        } else {
            // Need to add an offset to the given limit value
            // since the original topmost limit will use the offset value.
            // We can't apply the offset multiple times.
            IFunctionInfo finfoAdd = context.getMetadataProvider().lookupFunction(AlgebricksBuiltinFunctions.NUMERIC_ADD);
            List<Mutable<ILogicalExpression>> addArgs = new ArrayList<>();
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getMaxObjects().getValue().cloneExpression()));
            addArgs.add(new MutableObject<ILogicalExpression>(limitOp.getOffset().getValue().cloneExpression()));
            ScalarFunctionCallExpression maxPlusOffset = new ScalarFunctionCallExpression(finfoAdd, addArgs);
            limitCloneOp = new LimitOperator(maxPlusOffset, false);
        }
        limitCloneOp.setPhysicalOperator(new StreamLimitPOperator());
        limitCloneOp.getInputs().add(new MutableObject<ILogicalOperator>(unsafeOp));
        limitCloneOp.setExecutionMode(unsafeOp.getExecutionMode());
        OperatorPropertiesUtil.computeSchemaRecIfNull((AbstractLogicalOperator) unsafeOp);
        limitCloneOp.recomputeSchema();
        unsafeOpRef.setValue(limitCloneOp);
        context.computeAndSetTypeEnvironmentForOperator(limitCloneOp);
        context.addToDontApplySet(this, limitOp);
    }
    return safeOpRef != null;
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) AbstractLogicalOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) LimitOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.LimitOperator) LogicalOperatorTag(org.apache.hyracks.algebricks.core.algebra.base.LogicalOperatorTag) StreamLimitPOperator(org.apache.hyracks.algebricks.core.algebra.operators.physical.StreamLimitPOperator) ScalarFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)

Example 29 with Mutable

use of org.apache.commons.lang3.mutable.Mutable in project asterixdb by apache.

the class AbstractDecorrelationRule method buildVarExprList.

protected void buildVarExprList(Collection<LogicalVariable> vars, IOptimizationContext context, GroupByOperator g, List<Pair<LogicalVariable, Mutable<ILogicalExpression>>> outVeList) throws AlgebricksException {
    for (LogicalVariable ov : vars) {
        LogicalVariable newVar = context.newVar();
        ILogicalExpression varExpr = new VariableReferenceExpression(newVar);
        outVeList.add(new Pair<LogicalVariable, Mutable<ILogicalExpression>>(ov, new MutableObject<ILogicalExpression>(varExpr)));
        for (ILogicalPlan p : g.getNestedPlans()) {
            for (Mutable<ILogicalOperator> r : p.getRoots()) {
                OperatorManipulationUtil.substituteVarRec((AbstractLogicalOperator) r.getValue(), ov, newVar, true, context);
            }
        }
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ILogicalPlan(org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan) MutableObject(org.apache.commons.lang3.mutable.MutableObject)

Example 30 with Mutable

use of org.apache.commons.lang3.mutable.Mutable in project asterixdb by apache.

the class AbstractIntroduceCombinerRule method tryToPushAgg.

protected Pair<Boolean, Mutable<ILogicalOperator>> tryToPushAgg(AggregateOperator initAgg, GroupByOperator newGbyOp, Set<SimilarAggregatesInfo> toReplaceSet, IOptimizationContext context) throws AlgebricksException {
    ArrayList<LogicalVariable> pushedVars = new ArrayList<LogicalVariable>();
    ArrayList<Mutable<ILogicalExpression>> pushedExprs = new ArrayList<Mutable<ILogicalExpression>>();
    List<LogicalVariable> initVars = initAgg.getVariables();
    List<Mutable<ILogicalExpression>> initExprs = initAgg.getExpressions();
    int numExprs = initVars.size();
    // First make sure that all agg funcs are two step, otherwise we cannot use local aggs.
    for (int i = 0; i < numExprs; i++) {
        AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) initExprs.get(i).getValue();
        if (!aggFun.isTwoStep()) {
            return new Pair<Boolean, Mutable<ILogicalOperator>>(false, null);
        }
    }
    boolean haveAggToReplace = false;
    for (int i = 0; i < numExprs; i++) {
        Mutable<ILogicalExpression> expRef = initExprs.get(i);
        AggregateFunctionCallExpression aggFun = (AggregateFunctionCallExpression) expRef.getValue();
        IFunctionInfo fi1 = aggFun.getStepOneAggregate();
        // Clone the aggregate's args.
        List<Mutable<ILogicalExpression>> newArgs = new ArrayList<Mutable<ILogicalExpression>>(aggFun.getArguments().size());
        for (Mutable<ILogicalExpression> er : aggFun.getArguments()) {
            newArgs.add(new MutableObject<ILogicalExpression>(er.getValue().cloneExpression()));
        }
        IFunctionInfo fi2 = aggFun.getStepTwoAggregate();
        SimilarAggregatesInfo inf = new SimilarAggregatesInfo();
        LogicalVariable newAggVar = context.newVar();
        pushedVars.add(newAggVar);
        inf.stepOneResult = new VariableReferenceExpression(newAggVar);
        inf.simAggs = new ArrayList<AggregateExprInfo>();
        toReplaceSet.add(inf);
        AggregateFunctionCallExpression aggLocal = new AggregateFunctionCallExpression(fi1, false, newArgs);
        pushedExprs.add(new MutableObject<ILogicalExpression>(aggLocal));
        AggregateExprInfo aei = new AggregateExprInfo();
        aei.aggExprRef = expRef;
        aei.newFunInfo = fi2;
        inf.simAggs.add(aei);
        haveAggToReplace = true;
    }
    if (!pushedVars.isEmpty()) {
        AggregateOperator pushedAgg = new AggregateOperator(pushedVars, pushedExprs);
        pushedAgg.setExecutionMode(ExecutionMode.LOCAL);
        // If newGbyOp is null, then we optimizing an aggregate without group by.
        if (newGbyOp != null) {
            // Cut and paste nested input pipelines of initAgg to pushedAgg's input
            Mutable<ILogicalOperator> inputRef = initAgg.getInputs().get(0);
            Mutable<ILogicalOperator> bottomRef = inputRef;
            while (bottomRef.getValue().getInputs().size() > 0) {
                bottomRef = bottomRef.getValue().getInputs().get(0);
            }
            ILogicalOperator oldNts = bottomRef.getValue();
            initAgg.getInputs().clear();
            initAgg.getInputs().add(new MutableObject<ILogicalOperator>(oldNts));
            // Hook up the nested aggregate op with the outer group by.
            NestedTupleSourceOperator nts = new NestedTupleSourceOperator(new MutableObject<ILogicalOperator>(newGbyOp));
            nts.setExecutionMode(ExecutionMode.LOCAL);
            bottomRef.setValue(nts);
            pushedAgg.getInputs().add(inputRef);
        } else {
            // The local aggregate operator is fed by the input of the original aggregate operator.
            pushedAgg.getInputs().add(new MutableObject<ILogicalOperator>(initAgg.getInputs().get(0).getValue()));
            // Reintroduce assign op for the global agg partitioning var.
            initAgg.getInputs().get(0).setValue(pushedAgg);
            pushedAgg.setGlobal(false);
            context.computeAndSetTypeEnvironmentForOperator(pushedAgg);
        }
        return new Pair<Boolean, Mutable<ILogicalOperator>>(true, new MutableObject<ILogicalOperator>(pushedAgg));
    } else {
        return new Pair<Boolean, Mutable<ILogicalOperator>>(haveAggToReplace, null);
    }
}
Also used : LogicalVariable(org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable) AggregateFunctionCallExpression(org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression) NestedTupleSourceOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.NestedTupleSourceOperator) IFunctionInfo(org.apache.hyracks.algebricks.core.algebra.functions.IFunctionInfo) ILogicalOperator(org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator) ArrayList(java.util.ArrayList) Mutable(org.apache.commons.lang3.mutable.Mutable) ILogicalExpression(org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression) VariableReferenceExpression(org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression) AggregateOperator(org.apache.hyracks.algebricks.core.algebra.operators.logical.AggregateOperator) Pair(org.apache.hyracks.algebricks.common.utils.Pair)

Aggregations

Mutable (org.apache.commons.lang3.mutable.Mutable)213 ILogicalExpression (org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression)167 LogicalVariable (org.apache.hyracks.algebricks.core.algebra.base.LogicalVariable)150 ILogicalOperator (org.apache.hyracks.algebricks.core.algebra.base.ILogicalOperator)139 ArrayList (java.util.ArrayList)123 VariableReferenceExpression (org.apache.hyracks.algebricks.core.algebra.expressions.VariableReferenceExpression)109 MutableObject (org.apache.commons.lang3.mutable.MutableObject)75 AbstractFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression)68 AbstractLogicalOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AbstractLogicalOperator)65 Pair (org.apache.hyracks.algebricks.common.utils.Pair)62 ScalarFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ScalarFunctionCallExpression)58 AssignOperator (org.apache.hyracks.algebricks.core.algebra.operators.logical.AssignOperator)58 ILogicalPlan (org.apache.hyracks.algebricks.core.algebra.base.ILogicalPlan)48 ConstantExpression (org.apache.hyracks.algebricks.core.algebra.expressions.ConstantExpression)39 AlgebricksException (org.apache.hyracks.algebricks.common.exceptions.AlgebricksException)31 HashSet (java.util.HashSet)28 AggregateFunctionCallExpression (org.apache.hyracks.algebricks.core.algebra.expressions.AggregateFunctionCallExpression)28 GbyVariableExpressionPair (org.apache.asterix.lang.common.expression.GbyVariableExpressionPair)27 IAType (org.apache.asterix.om.types.IAType)27 List (java.util.List)25