package edu.brown.oltpgenerator.velocity; import java.io.File; import java.io.FileWriter; import java.util.HashMap; import java.util.Map; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.exception.ResourceNotFoundException; import org.voltdb.catalog.Column; import org.voltdb.catalog.ProcParameter; import org.voltdb.catalog.Procedure; import org.voltdb.catalog.Table; import edu.brown.oltpgenerator.AbstractBenchmark.AbstractLoader; import edu.brown.oltpgenerator.AbstractBenchmark.RandomGenerator.AbstractRandomGenerator; import edu.brown.oltpgenerator.env.ProcEnv; import edu.brown.oltpgenerator.env.BenchmarkEnv; import edu.brown.oltpgenerator.env.TableEnv; import edu.brown.oltpgenerator.env.RandomDistribution.RandomDistributionEnv; import edu.brown.oltpgenerator.exception.CycleInDagException; public abstract class CodeGenerator { private static final String VM_PATH = "/Users/zhe/hstore/SVN-Brown/src/tests/frontend/edu/brown/oltpgenerator/velocity"; private static final String KEY_PACKAGE_NAME = "packageName"; private static final String BENCHMARK_PACKAGE_NAME = BenchmarkEnv.getPackageName(); private static final String KEY_CLASS_NAME = "className"; private static final String KEY_BENCHMARK_NAME = "benchmarkName"; private static final String BENCHMARK_NAME = BenchmarkEnv.getBenchmarkName(); private static final String PROC_FOLDER_NAME = "procedures"; private static final String PROC_PACKAGE_NAME = BENCHMARK_PACKAGE_NAME + "." + PROC_FOLDER_NAME; private static final String KEY_PROC_PACKAGE_NAME = "procPackageName"; private static final String KEY_ABSTRACT_BENCHMARK_PACKAGE = "abstractBenchmark"; private static final String KEY_ABSTRACT_BENCHMARK_RANDOM_PACKAGE = "abstractBenchmarkRandom"; private static final String ABSTRACT_BENCHMARK_PACKAGE_NAME = AbstractLoader.class.getPackage() .getName(); private static final String ABSTRACT_BENCHMARK_RANDOM_PACKAGE_NAME = AbstractRandomGenerator.class .getPackage().getName(); private static final String TABLE_FOLDER_NAME = "tables"; private static final VelocityEngine s_expander = initVMEngine(); public static final String NO_CSV_PATH = ""; private static VelocityEngine initVMEngine() { VelocityEngine ret = new VelocityEngine(); ret.setProperty("file.resource.loader.path", VM_PATH); try { ret.init(); } catch (Exception e) { e.printStackTrace(); } return ret; } private static void genCode(String macroName, Map<String, Object> bindings, String outputPath) { // get Macro object Template macro; try { macro = s_expander.getTemplate(macroName); // create bindings VelocityContext env = new VelocityContext(); for (String key : bindings.keySet()) { env.put(key, bindings.get(key)); } // Output FileWriter fw = new FileWriter(outputPath); macro.merge(env, fw); fw.close(); } catch (ResourceNotFoundException e) { e.printStackTrace(); } catch (ParseErrorException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } private static void genLoader() throws CycleInDagException { String macroName = "LoaderMacro.vm"; Map<String, Object> bindings = new HashMap<String, Object>(); bindings.put(KEY_ABSTRACT_BENCHMARK_PACKAGE, ABSTRACT_BENCHMARK_PACKAGE_NAME); bindings.put(KEY_PACKAGE_NAME, BENCHMARK_PACKAGE_NAME); bindings.put("tblNames", TableEnv.getTableNames(TableEnv.sortTables())); bindings.put("schemaFileName", quote(TableEnv.genSchemaFileName())); String outputPath = BenchmarkEnv.getProjectPath() + "/Loader.java"; genCode(macroName, bindings, outputPath); } private static void genClient() { String macroName = "ClientMacro.vm"; String className = BENCHMARK_NAME + "Client"; Map<String, Object> bindings = new HashMap<String, Object>(); bindings.put(KEY_ABSTRACT_BENCHMARK_PACKAGE, ABSTRACT_BENCHMARK_PACKAGE_NAME); bindings.put(KEY_PACKAGE_NAME, BENCHMARK_PACKAGE_NAME); bindings.put(KEY_PROC_PACKAGE_NAME, PROC_PACKAGE_NAME); bindings.put(KEY_CLASS_NAME, className); bindings.put("classFile", className + ".class"); bindings.put("jarFileName", BENCHMARK_NAME + ".jar"); bindings.put("xacts", ProcEnv.getAllProcedures()); String outputPath = BenchmarkEnv.getProjectPath() + "/" + className + ".java"; genCode(macroName, bindings, outputPath); } private static void genProjectBuilder() { String macroName = "ProjectBuilderMacro.vm"; Map<String, Object> bindings = new HashMap<String, Object>(); bindings.put(KEY_PACKAGE_NAME, BENCHMARK_PACKAGE_NAME); bindings.put(KEY_BENCHMARK_NAME, quote(BENCHMARK_NAME)); bindings.put("procs", ProcEnv.getAllProcedures()); bindings.put(KEY_PROC_PACKAGE_NAME, PROC_PACKAGE_NAME); String outputPath = BenchmarkEnv.getProjectPath() + "/ProjectBuilder.java"; genCode(macroName, bindings, outputPath); } private static void genTables() { createSubFolder(TABLE_FOLDER_NAME); Table[] tables = TableEnv.getAllTables(); String macroName = "TableMacro.vm"; for (Table tbl : tables) { Map<String, Object> bindings = new HashMap<String, Object>(); bindings.put(KEY_PACKAGE_NAME, BENCHMARK_PACKAGE_NAME + "." + TABLE_FOLDER_NAME); bindings.put(KEY_ABSTRACT_BENCHMARK_PACKAGE, ABSTRACT_BENCHMARK_PACKAGE_NAME); bindings.put(KEY_ABSTRACT_BENCHMARK_RANDOM_PACKAGE, ABSTRACT_BENCHMARK_RANDOM_PACKAGE_NAME); bindings.put("cardinality", TableEnv.getCardinality(tbl.getName())); bindings.put(KEY_CLASS_NAME, tbl.getName()); bindings.put("tblName", quote(tbl.getName())); bindings.put("colGenStmts", getColGeneratorStatements(tbl)); String csvLinkPath = TableEnv.getTableCsvLink(tbl.getName()); bindings.put("csvLinkPath", csvLinkPath == null ? quote(NO_CSV_PATH) : quote(csvLinkPath)); String outputPath = BenchmarkEnv.getProjectPath() + "/" + TABLE_FOLDER_NAME + "/" + tbl.getName() + ".java"; genCode(macroName, bindings, outputPath); } } private static String quote(String name) { return "\"" + name + "\""; } private static void genTransactions() { createSubFolder(PROC_FOLDER_NAME); Procedure[] procs = ProcEnv.getAllProcedures(); String macroName = "ProcMacro.vm"; int idxXact = 0; for (Procedure proc : procs) { Map<String, Object> bindings = new HashMap<String, Object>(); bindings.put(KEY_ABSTRACT_BENCHMARK_PACKAGE, ABSTRACT_BENCHMARK_PACKAGE_NAME); bindings.put(KEY_ABSTRACT_BENCHMARK_RANDOM_PACKAGE, ABSTRACT_BENCHMARK_RANDOM_PACKAGE_NAME); bindings.put(KEY_PACKAGE_NAME, PROC_PACKAGE_NAME); bindings.put(KEY_CLASS_NAME, proc.getName()); bindings.put("paraList", ProcEnv.buildVmParaList(proc)); bindings.put("idxXact", idxXact++); Integer probability = ProcEnv.getProbability(proc.getName()); bindings.put("probability", probability == null ? 0 : probability); bindings.put("paraGenStmts", getParaGeneratorStatements(proc)); String outputPath = BenchmarkEnv.getProjectPath() + "/" + PROC_FOLDER_NAME + "/" + proc.getName() + ".java"; genCode(macroName, bindings, outputPath); } } private static void createSubFolder(String procFolderName) { File procDir = new File(BenchmarkEnv.getProjectPath() + "/" + procFolderName); procDir.mkdir(); } private static String[] getColGeneratorStatements(Table tbl) { Column[] cols = TableEnv.getAllColumns(tbl); String[] ret = new String[cols.length]; for (Column col : cols) { ret[col.getIndex()] = RandomDistributionEnv.get(col).getRandomGeneratorConstructingStatement(); } return ret; } private static String[] getParaGeneratorStatements(Procedure proc) { ProcParameter[] paras = ProcEnv.getAllParas(proc); String[] ret = new String[paras.length]; for (ProcParameter para : paras) { ret[para.getIndex()] = RandomDistributionEnv.get(para).getRandomGeneratorConstructingStatement(); } return ret; } public static void bigBang() throws CycleInDagException { String projectPath = BenchmarkEnv.createEmptyPackage(BenchmarkEnv.getSourceFolderPath(), BenchmarkEnv .getPackageName()); BenchmarkEnv.setProjectPath(projectPath); TableEnv.genSchemaFile(); genTables(); genLoader(); genTransactions(); genClient(); genProjectBuilder(); } }