Package org.voltdb.planner.microoptimizations

Source Code of org.voltdb.planner.microoptimizations.PushdownReceiveDominators

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.voltdb.planner.microoptimizations;

import java.util.ArrayList;
import java.util.List;

import org.voltdb.planner.CompiledPlan;
import org.voltdb.plannodes.AbstractPlanNode;
import org.voltdb.plannodes.DistinctPlanNode;
import org.voltdb.types.PlanNodeType;

public class PushdownReceiveDominators implements MicroOptimization {

    @Override
    public List<CompiledPlan> apply(CompiledPlan plan) {

        ArrayList<CompiledPlan> retval = new ArrayList<CompiledPlan>();

        AbstractPlanNode planGraph = plan.fragments.get(0).planGraph;
        planGraph.calculateDominators();

        List<AbstractPlanNode> receiveNodes =
            planGraph.findAllNodesOfType(PlanNodeType.RECEIVE);

        for (AbstractPlanNode pn : receiveNodes) {
            if (processReceiveNode(pn)) {

                // could make the graph transformation more complex
                // to avoid this recalculation; however, we expect graphs to
                // be relatively small and the total set of transformations
                // performed to also be small, making the cost of recalculation
                // an okay trade-off v. the complexity of a more efficient
                // implementation
                planGraph.calculateDominators();
            }
        }

        // modified plan in place
        retval.add(plan);
        return retval;
    }

    /**
     * @param receive
     * @return true of a transformation requiring recalculation
     * of the dominator state occurred.
     */
    private boolean processReceiveNode(AbstractPlanNode receive) {
        boolean modifiedGraph = false;

        // walk the dominators for the receive node and move them
        // after the receive/send pair as possible
        for (AbstractPlanNode pn : receive.getDominators()) {
            if (pn.getPlanNodeType() == PlanNodeType.DISTINCT) {
                modifiedGraph = pushdownDistinct(receive, pn) || modifiedGraph;
            }
        }
        return modifiedGraph;
    }


    /**
     * If a RECEIVE is dominated by a DISTINCT, that DISTINCT can be executed
     * by the remote partition. If the DISTINCT includes a unique key, the
     * dominating DISTINCT can be fully removed. Otherwise, it must remain as
     * a post filter on possibly duplicate data from the children.
     *
     * @param receive RECEIVE node being pushed past
     * @param distinct DISTINCT node transformed
     * @return
     */
    private boolean pushdownDistinct(AbstractPlanNode receive, AbstractPlanNode distinct) {
        // distinct must be an immediate parent of receive
        if (distinct.hasChild(receive) == false)
            return false;

        // distinct must have a single parent.
        AbstractPlanNode distinct_parent = distinct.getParent(0);
        if (distinct.getParentPlanNodeCount() > 1)
            return false;

        // receive must have a send child
        AbstractPlanNode send = receive.getChild(0);
        if (send.getPlanNodeType() != PlanNodeType.SEND) {
            assert(false) : "receive without send child?";
            return false;
        }

        // passes requirements to transform!

        // TODO: Determine if distinct.getDistinctColumnIndex() is a uniquely-valued column
        boolean distinct_on_unique_column = false;
        if (distinct_on_unique_column) {
            distinct.removeFromGraph();
            distinct_parent.addAndLinkChild(receive);
            send.addIntermediary(distinct);
        }
        else {
            assert(distinct.isInline() == false);
            DistinctPlanNode new_distinct = ((DistinctPlanNode)distinct).produceCopyForTransformation();
            send.addIntermediary(new_distinct);
        }
        return true;
    }

}
TOP

Related Classes of org.voltdb.planner.microoptimizations.PushdownReceiveDominators

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.