package edu.brown.designer.partitioners;
import java.util.List;
import java.util.Set;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.ProcParameter;
import org.voltdb.catalog.Procedure;
import org.voltdb.catalog.Table;
import edu.brown.benchmark.tm1.TM1Constants;
import edu.brown.benchmark.tm1.procedures.GetNewDestination;
import edu.brown.catalog.CatalogKey;
import edu.brown.catalog.CatalogUtil;
import edu.brown.catalog.special.ReplicatedColumn;
import edu.brown.costmodel.SingleSitedCostModel;
import edu.brown.costmodel.TimeIntervalCostModel;
import edu.brown.designer.AccessGraph;
import edu.brown.designer.Designer;
import edu.brown.designer.DesignerEdge;
import edu.brown.designer.DesignerVertex;
import edu.brown.designer.generators.AccessGraphGenerator;
import edu.brown.designer.partitioners.TestAbstractPartitioner.MockPartitioner;
import edu.brown.utils.CollectionUtil;
import edu.brown.utils.ProjectType;
public class TestPartitionerUtil extends BasePartitionerTestCase {
private MockPartitioner partitioner;
private AccessGraph agraph;
@Override
protected void setUp() throws Exception {
super.setUp(ProjectType.TM1, true);
// BasePartitionerTestCase will setup most of what we need
this.info.setCostModel(new TimeIntervalCostModel<SingleSitedCostModel>(catalogContext, SingleSitedCostModel.class, info.getNumIntervals()));
this.info.setPartitionerClass(MockPartitioner.class);
assertNotNull(info.getStats());
this.designer = new Designer(this.info, this.hints, this.info.getArgs());
this.partitioner = (MockPartitioner) this.designer.getPartitioner();
assertNotNull(this.partitioner);
this.agraph = AccessGraphGenerator.convertToSingleColumnEdges(catalog_db, this.partitioner.generateAccessGraph());
assertNotNull(this.agraph);
}
/**
* testGenerateTableOrder
*/
public void testGenerateTableOrder() throws Exception {
// Insert an artificial edge between SUBSCRIBER and ACCESS_INFO with a
// high weight so that we can anticipate the ordering
Table expected[] = {
this.getTable(TM1Constants.TABLENAME_SUBSCRIBER),
this.getTable(TM1Constants.TABLENAME_ACCESS_INFO),
this.getTable(TM1Constants.TABLENAME_SPECIAL_FACILITY),
this.getTable(TM1Constants.TABLENAME_CALL_FORWARDING),
};
DesignerVertex v0 = agraph.getVertex(expected[0]);
assertNotNull("Missing vertex: " + expected[0], v0);
DesignerVertex v1 = agraph.getVertex(expected[1]);
assertNotNull("Missing vertex: " + expected[1], v1);
assert (agraph.addEdge(new DesignerEdge(agraph), v0, v1));
for (DesignerEdge e : agraph.findEdgeSet(v0, v1)) {
e.addToWeight(0, 10000000);
} // FOR
// for (Edge e : agraph.getEdges()) {
// System.err.println(e + " [" + e.getTotalWeight() + "]");
// }
// Fire away!!
List<Table> ordered = PartitionerUtil.generateTableOrder(this.info, agraph, this.hints);
assertNotNull(ordered);
assertFalse(ordered.isEmpty());
assertEquals(expected.length, ordered.size());
// System.err.println("Visit Order: " + ordered);
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i], ordered.get(i));
} // FOR
}
/**
* testGenerateTableOrderMissingVertex
*/
public void testGenerateTableOrderMissingVertex() throws Exception {
// Remove one of the vertices from the graph and make sure that it's not included
// in our search table order
Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SPECIAL_FACILITY);
DesignerVertex v = agraph.getVertex(catalog_tbl);
assertNotNull(v);
boolean ret = agraph.removeVertex(v);
assert(ret);
int expected = catalog_db.getTables().size()-catalogContext.getSysTables().size()-1;
assertEquals(expected, agraph.getVertexCount());
// System.err.println("GRAPH: " + FileUtil.writeStringToTempFile(GraphvizExport.export(agraph, "tm1"), "dot"));
// Fire away!!
List<Table> ordered = PartitionerUtil.generateTableOrder(this.info, agraph, this.hints);
assertNotNull(ordered);
assertFalse(ordered.isEmpty());
assertEquals(expected, ordered.size());
// System.err.println("Visit Order: " + ordered);
}
/**
* testGenerateColumnOrder
*/
public void testGenerateColumnOrder() throws Exception {
AccessGraph agraph = this.partitioner.generateAccessGraph();
assertNotNull(agraph);
Table catalog_tbl = this.getTable(TM1Constants.TABLENAME_SUBSCRIBER);
Column expected[] = {
this.getColumn(catalog_tbl, "S_ID"),
this.getColumn(catalog_tbl, "SUB_NBR"),
this.getColumn(catalog_tbl, "VLR_LOCATION"),
this.getColumn(catalog_tbl, "BIT_1"),
ReplicatedColumn.get(catalog_tbl),
};
for (int i = 0; i < expected.length; i++)
assertNotNull("Null column [" + i + "]", expected[i]);
// Bombs away!!!
List<Column> ordered = PartitionerUtil.generateColumnOrder(this.info, agraph, catalog_tbl, this.hints);
assertNotNull(ordered);
assertFalse(ordered.isEmpty());
assertEquals(expected.length, ordered.size());
// System.err.println("Visit Order: " + ordered);
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i], ordered.get(i));
} // FOR
}
/**
* testGenerateProcParameterOrder
*/
public void testGenerateProcParameterOrder() throws Exception {
Procedure catalog_proc = this.getProcedure(GetNewDestination.class);
Set<String> param_order = PartitionerUtil.generateProcParameterOrder(this.info, catalog_db, catalog_proc, hints);
assertNotNull(param_order);
assertFalse(param_order.isEmpty());
// We should get back the first ProcParameter for each Procedure, since that maps to S_ID
ProcParameter catalog_proc_param = CatalogKey.getFromKey(catalog_db, CollectionUtil.first(param_order), ProcParameter.class);
assertNotNull(catalog_proc_param);
assertEquals(0, catalog_proc_param.getIndex());
}
}