Package edu.brown.designer.generators

Source Code of edu.brown.designer.generators.ReplicationTreeGenerator

/**
*
*/
package edu.brown.designer.generators;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.voltdb.catalog.Table;

import edu.brown.designer.AccessGraph;
import edu.brown.designer.DesignerEdge;
import edu.brown.designer.DesignerInfo;
import edu.brown.designer.DesignerVertex;
import edu.brown.designer.PartitionTree;
import edu.brown.graphs.AbstractDirectedGraph;
import edu.uci.ics.jung.graph.util.EdgeType;

/**
* @author pavlo
*/
public class ReplicationTreeGenerator extends AbstractGenerator<AbstractDirectedGraph<DesignerVertex, DesignerEdge>> {
    private static final Logger LOG = Logger.getLogger(ReplicationTreeGenerator.class);

    private final PartitionTree ptree;
    private final AccessGraph agraph;
    private Set<Table> replication_candidates = new HashSet<Table>();
    private Set<DesignerEdge> conflict_edges = new HashSet<DesignerEdge>();
    private Set<DesignerVertex> conflict_vertices = new HashSet<DesignerVertex>();

    public ReplicationTreeGenerator(DesignerInfo info, AccessGraph agraph, PartitionTree ptree) {
        super(info);
        this.agraph = agraph;
        this.ptree = ptree;
    }

    /**
     * Return the list of replication candidates generated
     *
     * @return
     */
    public Set<Table> getReplicationCandidates() {
        return (this.replication_candidates);
    }

    /**
     * Return the list of edges that were added to the partition tree
     *
     * @return
     */
    public Set<DesignerEdge> getConflictEdges() {
        return (this.conflict_edges);
    }

    /**
     * Return the list of vertices that cause conflict edges to be added to the
     * tree
     *
     * @return
     */
    public Set<DesignerVertex> getConflictVertices() {
        return (this.conflict_vertices);
    }

    @Override
    public void generate(AbstractDirectedGraph<DesignerVertex, DesignerEdge> graph) throws Exception {
        //
        // First clone the original partition tree
        //
        graph.clone(this.ptree);
        for (DesignerVertex vertex : graph.getVertices()) {
            vertex.copyAttributes(this.ptree, graph);
        } // FOR

        //
        // Then for each root we want to traverse their section of the
        // PartitionTree
        // and check to see that for each pair of adjacent vertices in the
        // AccessGraph
        // that there is a path from one vertex to another
        //
        List<DesignerVertex> ptree_vertices = new ArrayList<DesignerVertex>();
        ptree_vertices.addAll(this.ptree.getVertices());

        Set<DesignerVertex> modified = new HashSet<DesignerVertex>();
        for (int ctr0 = 0, cnt = ptree_vertices.size(); ctr0 < cnt; ctr0++) {
            DesignerVertex v0 = ptree_vertices.get(ctr0);
            if (this.ptree.isReplicated(v0))
                continue;

            LOG.debug("v0: " + v0 + "\n");
            for (int ctr1 = ctr0 + 1; ctr1 < cnt; ctr1++) {
                DesignerVertex v1 = ptree_vertices.get(ctr1);
                LOG.debug("  |- v1: " + v1 + "\n");
                DesignerEdge ag_edge = this.agraph.findEdge(v0, v1);

                if (((v0.getCatalogItem().getName().equals("WAREHOUSE") && v1.getCatalogItem().getName().equals("STOCK")) || (v1.getCatalogItem().getName().equals("WAREHOUSE") && v0.getCatalogItem()
                        .getName().equals("STOCK")))
                        && ag_edge == null) {
                    LOG.debug("???????????\n");
                }

                //
                // If this other vertex is already replicated, then we don't
                // care
                //
                if (this.ptree.isReplicated(v1))
                    continue;

                //
                // If there is an edge between these two vertices, then check
                // whether
                // there is a path from the "upper" vertex to the "lower" vertex
                //
                if (ag_edge != null && this.ptree.getPath(v0, v1).isEmpty() && this.ptree.getPath(v1, v0).isEmpty() && graph.getPath(v0, v1).isEmpty() && graph.getPath(v1, v0).isEmpty()) {

                    //
                    // There was no edge in the PartitionTree, so that means we
                    // want to add
                    // an edge in our replication tree. Note that although edges
                    // in the AccessGraph
                    // are undirected, we need to make sure that our edge goes
                    // in the right direction.
                    // Well, that's easy then there is a foreign key but what
                    // about when it's just
                    // some random join?
                    //
                    boolean found = false;
                    for (int ctr = 0; ctr < 2; ctr++) {
                        if (ctr == 1) {
                            DesignerVertex temp = v0;
                            v0 = v1;
                            v1 = temp;
                        }
                        // Edge dg_edge = this.info.dgraph.findEdge(v0, v1);
                        // Edge dg_edge = this.agraph.findEdge(v0, v1);
                        if (this.info.dependencies.getDescendants((Table) v0.getCatalogItem()).contains(v1.getCatalogItem())) {
                            LOG.debug("CREATED EDGE: " + v0 + " -> " + v1 + "\n");
                            DesignerEdge new_edge = new DesignerEdge(graph, ag_edge);
                            graph.addEdge(new_edge, v0, v1, EdgeType.DIRECTED);
                            this.conflict_edges.add(new_edge);
                            this.conflict_vertices.add(v1);
                            found = true;
                            modified.add(v0);
                            modified.add(v1);
                            break;
                        }
                    } // FOR
                    if (!found) {
                        // LOG.warn("Not creating missing edge " + ag_edge +
                        // " because there is no edge in the DependencyGraph");
                    }
                }
            } // FOR
        } // FOR

        //
        // Now for each vertex that was modified, we mark their roots as
        // candidates
        //
        Map<DesignerVertex, Set<DesignerVertex>> descendants = new HashMap<DesignerVertex, Set<DesignerVertex>>();
        for (DesignerVertex root : graph.getRoots()) {
            descendants.put(root, graph.getDescendants(root));
            LOG.debug(root + ": " + descendants.get(root) + "\n");
        } // FOR

        for (DesignerVertex vertex : modified) {
            LOG.debug("Checking: " + vertex + "\n");
            for (DesignerVertex root : descendants.keySet()) {
                if (descendants.get(root).contains(vertex)) {
                    LOG.debug("Found in " + descendants.get(root) + "\n");
                    this.replication_candidates.add((Table) root.getCatalogItem());
                    // break;
                }
            } // FOR
        } // FOR
        LOG.info("Replication Candidates: " + this.replication_candidates);
        return;
    }
}
TOP

Related Classes of edu.brown.designer.generators.ReplicationTreeGenerator

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.