package edu.brown.oltpgenerator.env; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import org.voltdb.CatalogContext; import org.voltdb.VoltTable; import org.voltdb.VoltType; import org.voltdb.catalog.Catalog; import org.voltdb.catalog.CatalogMap; import org.voltdb.catalog.Column; import org.voltdb.catalog.ConstraintRef; import org.voltdb.catalog.Table; import edu.brown.catalog.CatalogUtil; import edu.brown.designer.DependencyGraph; import edu.brown.designer.DesignerVertex; import edu.brown.designer.generators.DependencyGraphGenerator; import edu.brown.oltpgenerator.env.RandomDistribution.RandomDistributionEnv; import edu.brown.oltpgenerator.exception.CycleInDagException; import edu.brown.utils.CompilerUtil; import edu.brown.utils.FileUtil; /** * Environment for table-catalog-related information * * @author Zhe Zhang * */ public abstract class TableEnv { private static final int DEFAULT_CARDINALITY = 1000; private static Map<String, Integer> s_TableCardinality = new HashMap<String, Integer>(); private static Catalog s_cat = null; private static String s_sSchemaPath = null; private static Map<String, String> s_mapTableCsvLink = new HashMap<String, String>(); public static void clear() { s_TableCardinality.clear(); s_cat = null; s_sSchemaPath = null; s_mapTableCsvLink.clear(); } public static Catalog getCatalog() { return s_cat; } public static void setCatalog(Catalog cat) { s_cat = cat; } public static void readSchema() { try { s_cat = CompilerUtil.compileCatalog(s_sSchemaPath); } catch (Exception e) { e.printStackTrace(); } } public static void setSrcSchemaPath(String schemaPath) { s_sSchemaPath = schemaPath; } public static void loadDefaultColumnProperty() { for (Table tbl : getAllTables()) { setCardinality(tbl.getName(), DEFAULT_CARDINALITY); for (Column col : getAllColumns(tbl)) { RandomDistributionEnv.put(col, RandomDistributionEnv.getDefaultProperty(col)); } } } public static Column[] getAllColumns(Table tbl) { Column[] ret = new Column[tbl.getColumns().size()]; Iterator<Column> iter = tbl.getColumns().iterator(); int i = 0; while (iter.hasNext()) { ret[i++] = iter.next(); } return ret; } public static Table getTable(String tableName) { CatalogMap<Table> map = CatalogUtil.getDatabase(s_cat).getTables(); return map.get(tableName); } public static Table[] getAllTables() { if (s_cat == null) throw new RuntimeException("Haven't loaded ddl"); List<Table> tmp = new LinkedList<Table>(); // the last element in itemsArray is null // so filter the array for (Table t : CatalogUtil.getDatabase(s_cat).getTables()) { if (t != null) tmp.add(t); } Table[] ret = new Table[tmp.size()]; tmp.toArray(ret); return ret; } public static String[] getTableNames(Table[] tables) { String[] ret = new String[tables.length]; for (int i = 0; i < tables.length; i++) ret[i] = tables[i].getName(); return ret; } public static Column getReferredColumn(Column c) { CatalogMap<ConstraintRef> crm = c.getConstraints(); if (crm.isEmpty()) return null; ConstraintRef cr = c.getConstraints().get(0); return cr.getConstraint().getForeignkeycols().get(0).getColumn(); } public static void setCardinality(String tblName, int cardinality) { s_TableCardinality.put(tblName, cardinality); } public static Integer getCardinality(String tblName) { return s_TableCardinality.get(tblName); } /** * * @return topologically sorted Vertices of tables in catalog * @throws CycleInDagException */ public static Table[] sortTables() throws CycleInDagException { CatalogContext cc = new CatalogContext(s_cat.getCatalog()); DependencyGraph dgraph = DependencyGraphGenerator.generate(cc); int size = dgraph.getVertexCount(); Table[] ret = new Table[size]; // zero_list: vertices whose in-degree is zero List<DesignerVertex> zero_list = new LinkedList<DesignerVertex>(); List<DesignerVertex> non_zero_list = new LinkedList<DesignerVertex>(); // initialize two lists for (DesignerVertex v : dgraph.getVertices()) { if (dgraph.getPredecessorCount(v) == 0) { zero_list.add(v); // System.out.println("To zero_list: " + v); } else { non_zero_list.add(v); // System.out.println("To non_zero_list: " + v); } } int cnt = 0; while (true) { if (zero_list.isEmpty() && non_zero_list.isEmpty()) break; if (zero_list.isEmpty()) { throw new CycleInDagException(); } DesignerVertex cur = zero_list.remove(0); ret[cnt++] = (Table) (cur.getCatalogItem()); // System.out.println("Next ver: " + cur); Collection<DesignerVertex> successors = dgraph.getSuccessors(cur); dgraph.removeVertex(cur); for (DesignerVertex successor : successors) { if (dgraph.getPredecessorCount(successor) == 0) { non_zero_list.remove(successor); zero_list.add(successor); // System.out.println("Move " + successor + // " from non_zero to zero"); } } } return ret; } public static boolean schemaLoaded() { return s_cat != null; } /** * @param tableName * @return an brand-new empty VoltTable whose corresponds tableName */ public static VoltTable initVoltTable(String tableName) { Table t = getTable(tableName); VoltTable.ColumnInfo[] vtCols = new VoltTable.ColumnInfo[t.getColumns().size()]; Iterator<Column> iCols = t.getColumns().iterator(); while (iCols.hasNext()) { Column c = iCols.next(); vtCols[c.getIndex()] = new VoltTable.ColumnInfo(c.getName(), VoltType.get((byte) c.getType())); } return new VoltTable(vtCols); } public static String genSchemaFileName() { return BenchmarkEnv.getBenchmarkName() + "-ddl.sql"; } public static String genFKSchemaFileName() { return BenchmarkEnv.getBenchmarkName() + "-ddl-fkeys.sql"; } public static void genSchemaFile() { try { String content = FileUtil.readFile(s_sSchemaPath); FileUtil.writeStringToFile(new File(BenchmarkEnv.getProjectPath() + "/" + genSchemaFileName()), content); FileUtil.writeStringToFile(new File(BenchmarkEnv.getProjectPath() + "/" + genFKSchemaFileName()), content); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static void linkTableToCsv(String sTblName, String sCsvPath) { s_mapTableCsvLink.put(sTblName, sCsvPath); } public static void unlinkTalbe(String sTblName) { s_mapTableCsvLink.remove(sTblName); } public static String getTableCsvLink(String sTblName) { return s_mapTableCsvLink.get(sTblName); } }