Package edu.brown.designer.partitioners

Source Code of edu.brown.designer.partitioners.TestConstraintPropagator

package edu.brown.designer.partitioners;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.voltdb.catalog.CatalogType;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.Table;

import edu.brown.benchmark.tm1.TM1Constants;
import edu.brown.catalog.CatalogPair;
import edu.brown.catalog.special.MultiColumn;
import edu.brown.catalog.special.ReplicatedColumn;
import edu.brown.catalog.special.VerticalPartitionColumn;
import edu.brown.designer.AccessGraph;
import edu.brown.designer.DesignerEdge;
import edu.brown.designer.DesignerVertex;
import edu.brown.designer.AccessGraph.EdgeAttributes;
import edu.brown.designer.generators.AccessGraphGenerator;
import edu.brown.utils.PredicatePairs;
import edu.brown.utils.ProjectType;

public class TestConstraintPropagator extends BasePartitionerTestCase {
   
    private static AccessGraph agraph;
    private ConstraintPropagator cp;
   
    @Override
    protected void setUp() throws Exception {
        super.setUp(ProjectType.TM1, true);
       
        if (agraph == null) {
            agraph = AccessGraphGenerator.generateGlobal(this.info);
            agraph = AccessGraphGenerator.convertToSingleColumnEdges(catalog_db, agraph);
            agraph.setVerbose(true);
//            System.err.println("Dumping AccessGraph to " + FileUtil.writeStringToFile("/tmp/tpcc.dot", GraphvizExport.export(agraph, "tpcc")));
        }
        assertNotNull(agraph);
        this.cp = new ConstraintPropagator(info, hints, agraph);
    }
   
    /**
     * testInitialize
     */
    public void testInitialize() throws Exception {
//        System.err.println(this.cp.toString());
       
        for (DesignerVertex v : agraph.getVertices()) {
            assertNotNull(cp.getEdgeColumns(v));
            // System.err.println(v + " => " + cp.getEdgeColumns(v));
        }
       
        boolean has_multi_vertex_edge = false;
        for (DesignerEdge e : agraph.getEdges()) {
            Set<DesignerVertex> vertices = new HashSet<DesignerVertex>(agraph.getIncidentVertices(e));
            assertFalse(vertices.isEmpty());
            has_multi_vertex_edge = has_multi_vertex_edge || (vertices.size() > 1);
//            if (vertices.size() > 1) System.err.println(e);
        } // FOR
        assert(has_multi_vertex_edge);
    }
   
    /**
     * testInitializeVerticalPartitioning
     */
    public void testInitializeVerticalPartitioning() throws Exception {
        hints.enable_vertical_partitioning = true;
        cp = new ConstraintPropagator(info, hints, agraph);
       
        // Check that a vertical partition candidate column for SUBSCRIBER
        Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
        DesignerVertex v = agraph.getVertex(catalog_tbl);
        assertNotNull(v);
        Collection<VerticalPartitionColumn> vp_columns = new HashSet<VerticalPartitionColumn>();
        for (Collection<Column> catalog_cols : cp.getEdgeColumns(v).values()) {
            for (Column catalog_col : catalog_cols) {
                if (catalog_col instanceof VerticalPartitionColumn) {
                    vp_columns.add((VerticalPartitionColumn)catalog_col);
                }
            } // FOR
        } // FOR
        assertFalse(vp_columns.isEmpty());
       
        // Make sure that each of these have a horizontal partition column
        // We expected to at least have a VerticalPartition with SUB_NBR in it
        Column expected_hp = this.getColumn(catalog_tbl, "S_ID");
        Column expected_vp = this.getColumn(catalog_tbl, "SUB_NBR");
        boolean found = false;
        for (VerticalPartitionColumn vp_col : vp_columns) {
            assertNotNull(vp_col);
            assertNotNull(vp_col.toString(), vp_col.getHorizontalColumn());
            assertNotNull(vp_col.toString(), vp_col.getVerticalMultiColumn());
           
            if (vp_col.getVerticalMultiColumn().contains(expected_vp) &&
                vp_col.getHorizontalColumn().equals(expected_hp)) {
                assert(vp_col.getVerticalMultiColumn().contains(expected_hp));
                assert(vp_col.hasOptimizedQueries());
                found = true;
            }
//            System.err.println(vp_col.toString() + "\n");
        } // FOR
        assert(found);
    }
   
    /**
     * testInitializeMultiAttribute
     */
    public void testInitializeMultiAttribute() throws Exception {
        hints.enable_multi_partitioning = true;
        cp = new ConstraintPropagator(info, hints, agraph);
       
        // Check that we have multi-attribute candidates for ACCESS_INFO
        Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_ACCESS_INFO);
        DesignerVertex v = agraph.getVertex(catalog_tbl);
        assertNotNull(v);
        Collection<MultiColumn> multi_columns = new HashSet<MultiColumn>();
        for (Collection<Column> catalog_cols : cp.getEdgeColumns(v).values()) {
            for (Column catalog_col : catalog_cols) {
                if (catalog_col instanceof MultiColumn) {
                    multi_columns.add((MultiColumn)catalog_col);
                }
            } // FOR
        } // FOR
        assertFalse(multi_columns.isEmpty());
    }
   
    /**
     * testUpdateTwice
     */
    public void testUpdateTwice() throws Exception {
        Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
        cp.update(catalog_tbl);
        try {
            cp.update(catalog_tbl);
        } catch (AssertionError ex) {
            return;
        }
        assert(false) : "Was allowed to update twice!";
    }
   
    /**
     * testUpdateTable
     */
    public void testUpdateTable() throws Exception {
        Set<Table> targets = new HashSet<Table>();
        for (String table_name : new String[]{ TM1Constants.TABLENAME_SUBSCRIBER, TM1Constants.TABLENAME_ACCESS_INFO }) {
            Table catalog_tbl = this.getTable(table_name);
            cp.update(catalog_tbl);
            targets.add(catalog_tbl);   
        } // FOR
       
        // Make sure that the columns that remain for the edges to our target tables
        // are only connected through the column that the target tables were partitioned on
        Collection<Column> columns;
        for (Table catalog_tbl : catalog_db.getTables()) {
            if (targets.contains(catalog_tbl) || catalog_tbl.getSystable()) continue;
            DesignerVertex v0 = agraph.getVertex(catalog_tbl);
           
            try {
                columns = cp.getCandidateValues(catalog_tbl, Column.class);
            } catch (IllegalArgumentException ex) {
                continue;
            }
            assertNotNull(columns);
            assertFalse(columns.isEmpty());
           
            System.err.println(String.format("Examining %d columns for %s", columns.size(), catalog_tbl));
           
            // For each column that is still available for this table, check to make sure that:
            //  (1) It does not have an unmarked edge to one of our target tables
            //  (2) If it is does have an edge to one of target tables then that edge uses the column that the table is partitioned on
            for (Column catalog_col : columns) {
                if (catalog_col instanceof ReplicatedColumn) continue;
                Collection<DesignerEdge> edges = agraph.findEdgeSet(v0, catalog_col);
                assertNotNull(catalog_col.fullName(), edges);
                assertFalse(catalog_col.fullName(), edges.isEmpty());
               
                for (DesignerEdge e : edges) {
                    if (cp.isMarked(e)) continue;
                   
                    DesignerVertex v1 = agraph.getOpposite(v0, e);
                    assertNotNull(e.toString(), v1);
                    Table other_tbl = v1.getCatalogItem();
                    assertNotNull(other_tbl);

                    // Skip if not one of our target tables
                    if (targets.contains(other_tbl) == false || other_tbl.getPartitioncolumn() == null) continue;
                   
                    // Get the ColumnSet, which should only have one entry
                    PredicatePairs cset = e.getAttribute(EdgeAttributes.COLUMNSET);
                    assertNotNull(cset);
                    assertEquals(cset.toString(), 1, cset.size());
                    CatalogPair entry = cset.get(0);
                    assertNotNull(entry);
                   
                    // Get the element from the entry that is not our column
                    CatalogType other = entry.getOther(catalog_col);
                    assertNotNull(other);
                    if ((other instanceof Column) == false) continue;
                    Column other_col = (Column)other;
                    System.err.println(String.format("catalog_col=%s, other_tbl=%s, other_col=%s",
                                                     catalog_col.fullName(), other_tbl.fullName(), other_col.fullName()));
                    assertEquals(e.toString(), other_tbl, other_col.getParent());
                   
                    // Make sure that the table's partitioning column matches 
                    assertEquals(String.format("%s<-->%s\n%s", catalog_tbl, other_tbl, e.toString()), other_tbl.getPartitioncolumn(), other_col);
                } // FOR (Edge)
            } // FOR (Column)
        } // FOR
    }
   
  /**
  * testUpdateTableVerticalPartitioning
  */
public void testUpdateTableVerticalPartitioning() throws Exception {
     hints.enable_vertical_partitioning = true;
     cp = new ConstraintPropagator(info, hints, agraph);
    
     // We're going to mark SUBSCRIBER as partitioned on S_ID and get the candidates for ACCESS_INFO 
     Table catalog_tbl0 = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
     Column catalog_col = this.getColumn(catalog_tbl0, "S_ID");
     catalog_tbl0.setPartitioncolumn(catalog_col);
     cp.update(catalog_tbl0);
     Table catalog_tbl1 = this.getTable(TM1Constants.TABLENAME_ACCESS_INFO);
     Collection<Column> expected_cols = cp.getCandidateValues(catalog_tbl1, Column.class);
     assertNotNull(expected_cols);
     assertFalse(expected_cols.isEmpty());
    
     // Get the VerticalPartitionColumn that uses S_ID as the horizontal partitioning Column
     // Make sure that the optimized query plans have not been applied yet
     Collection<VerticalPartitionColumn> vp_columns = cp.getVerticalPartitionColumns(catalog_tbl0);
     assertNotNull(vp_columns);
     VerticalPartitionColumn vp_col = null;
     for (VerticalPartitionColumn c : vp_columns) {
         if (c.getHorizontalColumn().equals(catalog_col)) {
             vp_col = c;
             break;
         }
     } // FOR
     assertNotNull(vp_col);
     assertFalse(vp_col.isUpdateApplied());
    
     // Now partition SUBSCRIBER using its VerticalPartitionColumn
     cp.reset(catalog_tbl0);
     catalog_tbl0.setPartitioncolumn(vp_col);
     cp.update(catalog_tbl0);
    
     // And make sure that we get back the Columns we expect and that the Statements
     // have been updated
     Collection<Column> actual_cols = cp.getCandidateValues(catalog_tbl1, Column.class);
     assertNotNull(actual_cols);
     assertEquals(expected_cols.size(), actual_cols.size());
     assertEquals(expected_cols, actual_cols);
     assertFalse(vp_col.isUpdateApplied());
    
     // Revert
     catalog_tbl0.setPartitioncolumn(catalog_col);
     cp.reset(catalog_tbl0);
}
   
//    /**
//     * testUpdateTableMultiAttribute
//     */
//    public void testUpdateTableMultiAttribute() throws Exception {
//        Database clone_db = CatalogCloner.cloneDatabase(catalog_db);
//        info = this.generateInfo(clone_db);
//        hints.enable_multi_partitioning = true;
//       
//        designer = new Designer(info, hints, info.getArgs());
//        RandomPartitioner partitioner = new RandomPartitioner(designer, info);
//        AccessGraph agraph = AccessGraphGenerator.convertToSingleColumnEdges(clone_db, partitioner.generateAccessGraph());
//        cp = new ConstraintPropagator(info, hints, agraph);
//       
//        Table catalog_tbl0 = this.getTable(clone_db, TM1Constants.TABLENAME_CALL_FORWARDING);
//        Collection<MultiColumn> multi_columns = new HashSet<MultiColumn>();
//        DesignerVertex v = agraph.getVertex(catalog_tbl0);
//        assertNotNull(catalog_tbl0.fullName(), v);
//        for (Collection<Column> catalog_cols : cp.getEdgeColumns(v).values()) {
//            for (Column catalog_col : catalog_cols) {
//                String catalog_key = CatalogKey.createKey(catalog_col);
//                assertNotNull(catalog_key);
//                catalog_col = CatalogKey.getFromKey(clone_db, catalog_key, Column.class);
//                assertNotNull(catalog_col);
//               
//                if (catalog_col instanceof MultiColumn) {
//                    multi_columns.add((MultiColumn)catalog_col);
//                }
//            } // FOR
//        } // FOR
//        assertFalse(multi_columns.isEmpty());
//       
//        // We're going to mark SPECIAL_FACILITY as updated using a particular Column that
//        // should cause all the MultiColumns for CALL_FORWADING to get invalidated
//        Table catalog_tbl1 = this.getTable(clone_db, TM1Constants.TABLENAME_SPECIAL_FACILITY);
//        catalog_tbl0.setPartitioncolumn(this.getColumn(catalog_tbl1, 2));
//        cp.update(catalog_tbl1);
//       
//        // Make sure that the columns that remain for the edges to our target tables
//        // are only connected through the column that the target tables were partitioned on
//        Collection<Column> expected = CollectionUtil.addAll(new HashSet<Column>(),
//                                                            this.getColumn(catalog_tbl0, "S_ID"),
//                                                            this.getColumn(catalog_tbl0, "SF_TYPE"));
//       
//        Collection<Column> columns = cp.getCandidateValues(catalog_tbl0, Column.class);
//        assertNotNull(columns);
//        assertFalse(columns.isEmpty());
//        for (Column catalog_col : columns) {
//            if (catalog_col instanceof MultiColumn) {
//                MultiColumn mc = (MultiColumn)catalog_col;
//                assertTrue(catalog_col.toString(), CollectionUtils.intersection(mc, expected).isEmpty());
//            }
//        } // FOR
//    }
   
    /**
     * testResetTable
     */
    public void testResetTable() throws Exception {
        // First update all of the tables
        for (Table catalog_tbl : catalog_db.getTables()) {
            try {
                cp.update(catalog_tbl);
            } catch (IllegalArgumentException ex) {
                continue;
            }
        } // FOR
       
        // Get the list of columns that we can use for CALL_FORWARDING
        Table catalog_tbl0 = this.getTable(TM1Constants.TABLENAME_CALL_FORWARDING);
        Collection<Column> orig_columns = new HashSet<Column>((Collection<Column>)cp.getCandidateValues(catalog_tbl0, Column.class));
        assertFalse(catalog_tbl0.toString(), orig_columns.isEmpty());
       
        // Reset both ACCESS_INFO and CALL_FORWARDING
        // This should give us more possible columns for CALL_FORWARDING
        Table catalog_tbl1 = this.getTable(TM1Constants.TABLENAME_ACCESS_INFO);
        cp.reset(catalog_tbl0);
        cp.reset(catalog_tbl1);
       
        // Then grab the list of colunms for ORDERS again. It should be larger than our original list
        // And the original list should be a subset
        Collection<Column> new_columns = cp.getCandidateValues(catalog_tbl0, Column.class);
        assert(new_columns.size() > orig_columns.size()) : orig_columns;
        assert(new_columns.containsAll(orig_columns)) : String.format("ORIG: %s\nNEW: %s", orig_columns, new_columns);
    }
   
    /**
     * testResetTwice
     */
    public void testResetTwice() throws Exception {
        Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
        cp.update(catalog_tbl);
        cp.reset(catalog_tbl);
        try {
            cp.reset(catalog_tbl);
        } catch (AssertionError ex) {
            return;
        }
        assert(false) : "Was allowed to reset twice!";
    }
}
TOP

Related Classes of edu.brown.designer.partitioners.TestConstraintPropagator

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.