Package edu.brown.optimizer.optimizations

Source Code of edu.brown.optimizer.optimizations.RemoveDistributedReplicatedTableJoinOptimization

package edu.brown.optimizer.optimizations;

import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.voltdb.catalog.Table;
import org.voltdb.plannodes.AbstractJoinPlanNode;
import org.voltdb.plannodes.AbstractPlanNode;
import org.voltdb.plannodes.AbstractScanPlanNode;
import org.voltdb.plannodes.ProjectionPlanNode;
import org.voltdb.plannodes.ReceivePlanNode;
import org.voltdb.plannodes.SendPlanNode;
import org.voltdb.utils.Pair;

import edu.brown.catalog.CatalogUtil;
import edu.brown.logging.LoggerUtil;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.optimizer.PlanOptimizerState;
import edu.brown.plannodes.PlanNodeUtil;
import edu.brown.utils.CollectionUtil;

public class RemoveDistributedReplicatedTableJoinOptimization extends AbstractOptimization {
    private static final Logger LOG = Logger.getLogger(RemoveDistributedReplicatedTableJoinOptimization.class);
    private static final LoggerBoolean debug = new LoggerBoolean();
    private static final LoggerBoolean trace = new LoggerBoolean();
    static {
        LoggerUtil.attachObserver(LOG, debug, trace);
    }

    public RemoveDistributedReplicatedTableJoinOptimization(PlanOptimizerState state) {
        super(state);
    }

    @Override
    public Pair<Boolean, AbstractPlanNode> optimize(final AbstractPlanNode rootNode) {
        // Skip single-partition query plans
        if (PlanNodeUtil.isDistributedQuery(rootNode) == false) {
            if (debug.val)
                LOG.debug("SKIP - Not a distributed query plan");
            return (Pair.of(false, rootNode));
        }

        // Walk through the query plan tree and see if there is a join
        // where the outer table is replicated but it is being
        // scanned in a separate PlanFragment
        boolean modified = false;
        for (AbstractJoinPlanNode join_node : PlanNodeUtil.getPlanNodes(rootNode, AbstractJoinPlanNode.class)) {
            if (debug.val)
                LOG.debug("Examining " + join_node);

            // Check whether the chain below this node is
            // RECIEVE -> SEND -> SCAN
            assert (join_node.getChildPlanNodeCount() >= 1);
            AbstractPlanNode child = join_node.getChild(0);
            if (debug.val)
                LOG.debug(join_node + " -> " + child);
            if (child instanceof ReceivePlanNode) {
                ReceivePlanNode recv_node = (ReceivePlanNode) child;
                SendPlanNode send_node = (SendPlanNode) child.getChild(0);
                List<AbstractPlanNode> children = send_node.getChildren();
                assert (children != null);
                if (children.size() > 1)
                    continue;
                if (children.get(0).getChildPlanNodeCount() > 0)
                    continue;
                if ((children.get(0) instanceof AbstractScanPlanNode) == false)
                    continue;

                AbstractPlanNode leaf_node = children.get(0);
                assert (leaf_node instanceof AbstractScanPlanNode);
                Collection<Table> leaf_tables = CatalogUtil.getReferencedTablesForPlanNode(state.catalog_db, leaf_node);
                assert (leaf_tables.size() == 1);
                Table leaf_tbl = CollectionUtil.first(leaf_tables);

                Collection<Table> join_tables = CatalogUtil.getReferencedTablesForPlanNode(state.catalog_db, join_node);
                Table join_tbl = null;
                for (Table catalog_tbl : join_tables) {
                    if (catalog_tbl.equals(leaf_tbl) == false) {
                        join_tbl = catalog_tbl;
                        break;
                    }
                } // FOR
                assert (join_tbl != null);

                // If either table is replicated, then the leaf scan should be linked
                // directly with the Join PlanNode
                if (join_tbl.getIsreplicated() || leaf_tbl.getIsreplicated()) {
                    AbstractPlanNode parent = join_node.getParent(0);
                    assert (parent != null);
                    parent.clearChildren();
                    parent.addAndLinkChild(recv_node);
                    state.markDirty(parent);
                    state.markDirty(recv_node);

                    join_node.clearParents();
                    join_node.clearChildren();
                    leaf_node.clearParents();

                    join_node.addAndLinkChild(leaf_node);
                    state.markDirty(join_node);
                    state.markDirty(leaf_node);

                    // HACK: If the parent is a ProjectionPlanNode, then we'll want
                    // to duplicate it so that we make sure that our original
                    // SEND/RECIEVE nodes have the right offsets
                    if (parent instanceof ProjectionPlanNode) {
                        AbstractPlanNode parent_clone = null;
                        try {
                            parent_clone = (AbstractPlanNode) parent.clone(false, false);
                        } catch (CloneNotSupportedException ex) {
                            throw new RuntimeException(ex);
                        }
                        assert (parent_clone != null);
                        assert (parent != parent_clone);
                        parent_clone.addAndLinkChild(join_node);
                        send_node.clearChildren();
                        send_node.addAndLinkChild(parent_clone);
                    } else {
                        send_node.clearChildren();
                        send_node.addAndLinkChild(join_node);
                    }
                    state.markDirty(send_node);
                    modified = true;
                }
            }
        } // FOR

        return (Pair.of(modified, rootNode));
    }

}
TOP

Related Classes of edu.brown.optimizer.optimizations.RemoveDistributedReplicatedTableJoinOptimization

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.