/*************************************************************************** * Copyright (C) 2012 by H-Store Project * * Brown University * * Massachusetts Institute of Technology * * Yale University * * * * Alex Kalinin (akalinin@cs.brown.edu) * * http://www.cs.brown.edu/~akalinin/ * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * ***************************************************************************/ package edu.brown.benchmark.tpce.generators; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.apache.log4j.Logger; import org.voltdb.catalog.Table; import edu.brown.benchmark.tpce.TPCEConstants; public class TPCEGenerator { private static final Logger LOG = Logger.getLogger(TPCEGenerator.class); /* * Input Files */ private static final String AREA_FILE = "AREACODE.txt"; private static final String CHARGE_FILE = "CHARGE.txt"; private static final String COMMRATE_FILE = "COMMISSION_RATE.txt"; private static final String COMPANY_FILE = "COMPANY.txt"; private static final String COMPANYCOMP_FILE = "COMPANY_COMPETITOR.txt"; private static final String COMPANYSP_FILE = "COMPANYSPRATE.txt"; private static final String EXCHANGE_FILE = "EXCHANGE.txt"; private static final String FEMFNAME_FILE = "FEMALEFIRSTNAME.txt"; private static final String INDUSTRY_FILE = "INDUSTRY.txt"; private static final String LNAME_FILE = "LASTNAME.txt"; private static final String MALEFNAME_FILE = "MALEFIRSTNAME.txt"; private static final String NONTAXACC_FILE = "NONTAXABLEACCOUNTNAME.txt"; private static final String SECTOR_FILE = "SECTOR.txt"; private static final String SECURITY_FILE = "SECURITY.txt"; private static final String STATUS_FILE = "STATUS_TYPE.txt"; private static final String STNAME_FILE = "STREETNAME.txt"; private static final String STSUFFIX_FILE = "STREETSUFFIX.txt"; private static final String TAXACC_FILE = "TAXABLEACCOUNTNAME.txt"; private static final String TAXCOUNTRY_FILE = "TAXRATESCOUNTRY.txt"; private static final String TAXDIV_FILE = "TAXRATESDIVISION.txt"; private static final String TRADETYPE_FILE = "TRADE_TYPE.txt"; private static final String ZIPCODE_FILE = "ZIP_CODE.txt"; /* * File Types */ public enum InputFile { AREA, CHARGE, COMMRATE, COMPANY, COMPANYCOMP, COMPANYSP, EXCHANGE, FEMFNAME, INDUSTRY, LNAME, MALEFNAME, NONTAXACC, SECTOR, SECURITY, STATUS, STNAME, STSUFFIX, TAXACC, TAXCOUNTRY, TAXDIV, TRADETYPE, ZIPCODE } /* * Input Files handlers */ private final Map<InputFile, InputFileHandler> inputFiles = new HashMap<InputFile, InputFileHandler>(); /* * Table generators */ private static final Map<String, Class<? extends TableGenerator>> genClasses = new HashMap<String, Class<? extends TableGenerator>>(); static { // Fixed tables genClasses.put(TPCEConstants.TABLENAME_ZIP_CODE, ZipCodeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_CHARGE, ChargeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_EXCHANGE, ExchangeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_COMMISSION_RATE, CommissionRateGenerator.class); genClasses.put(TPCEConstants.TABLENAME_INDUSTRY, IndustryGenerator.class); genClasses.put(TPCEConstants.TABLENAME_SECTOR, SectorGenerator.class); genClasses.put(TPCEConstants.TABLENAME_STATUS_TYPE, StatusTypeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_TRADE_TYPE, TradeTypeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_TAXRATE, TaxRateGenerator.class); // Scaling tables genClasses.put(TPCEConstants.TABLENAME_CUSTOMER, CustomerGenerator.class); genClasses.put(TPCEConstants.TABLENAME_ADDRESS, AddressGenerator.class); genClasses.put(TPCEConstants.TABLENAME_CUSTOMER_ACCOUNT, CustomerAccountsGenerator.class); genClasses.put(TPCEConstants.TABLENAME_ACCOUNT_PERMISSION, AccountPermsGenerator.class); genClasses.put(TPCEConstants.TABLENAME_COMPANY, CompanyGenerator.class); genClasses.put(TPCEConstants.TABLENAME_COMPANY_COMPETITOR, CompanyCompetitorsGenerator.class); genClasses.put(TPCEConstants.TABLENAME_CUSTOMER_TAXRATE, CustomerTaxRatesGenerator.class); genClasses.put(TPCEConstants.TABLENAME_DAILY_MARKET, DailyMarketGenerator.class); genClasses.put(TPCEConstants.TABLENAME_FINANCIAL, FinancialGenerator.class); genClasses.put(TPCEConstants.TABLENAME_LAST_TRADE, LastTradeGenerator.class); genClasses.put(TPCEConstants.TABLENAME_NEWS_ITEM, NewsItemGenerator.class); genClasses.put(TPCEConstants.TABLENAME_NEWS_XREF, NewsXRefGenerator.class); genClasses.put(TPCEConstants.TABLENAME_SECURITY, SecurityGenerator.class); genClasses.put(TPCEConstants.TABLENAME_WATCH_LIST, WatchListGenerator.class); genClasses.put(TPCEConstants.TABLENAME_WATCH_ITEM, WatchItemsGenerator.class); genClasses.put(TPCEConstants.TABLENAME_BROKER, BrokerGenerator.class); } /* private static final Map<String, Class<? extends TableGenerator>> genClassesMixed = new HashMap<String, Class<? extends TableGenerator>>(); static { // Mixed tables genClasses.put(TPCEConstants.TABLENAME_ACCOUNT_PERMISSION, null); genClasses.put(TPCEConstants.TABLENAME_CUSTOMER_ACCOUNT, null); } */ /* * Generator parameters */ private long currentCustomers; private long customerStartId; private final long total_customers; private final int scaling_factor; private final int initial_days; public TPCEGenerator(File inputDir, long total_customers, int scaling_factor, int initial_days) { /* * Create input file handlers */ inputFiles.put(InputFile.AREA, new WeightedFile(new File(inputDir + File.separator + AREA_FILE))); inputFiles.put(InputFile.COMPANYSP, new WeightedFile(new File(inputDir + File.separator + COMPANYSP_FILE))); inputFiles.put(InputFile.FEMFNAME, new WeightedFile(new File(inputDir + File.separator + FEMFNAME_FILE))); inputFiles.put(InputFile.LNAME, new WeightedFile(new File(inputDir + File.separator + LNAME_FILE))); inputFiles.put(InputFile.MALEFNAME, new WeightedFile(new File(inputDir + File.separator + MALEFNAME_FILE))); inputFiles.put(InputFile.STNAME, new WeightedFile(new File(inputDir + File.separator + STNAME_FILE))); inputFiles.put(InputFile.STSUFFIX, new WeightedFile(new File(inputDir + File.separator + STSUFFIX_FILE))); inputFiles.put(InputFile.ZIPCODE, new WeightedFile(new File(inputDir + File.separator + ZIPCODE_FILE))); inputFiles.put(InputFile.CHARGE, new FlatFile(new File(inputDir + File.separator + CHARGE_FILE))); inputFiles.put(InputFile.COMMRATE, new FlatFile(new File(inputDir + File.separator + COMMRATE_FILE))); inputFiles.put(InputFile.COMPANY, new FlatFile(new File(inputDir + File.separator + COMPANY_FILE))); inputFiles.put(InputFile.COMPANYCOMP, new FlatFile(new File(inputDir + File.separator + COMPANYCOMP_FILE))); inputFiles.put(InputFile.EXCHANGE, new FlatFile(new File(inputDir + File.separator + EXCHANGE_FILE))); inputFiles.put(InputFile.INDUSTRY, new FlatFile(new File(inputDir + File.separator + INDUSTRY_FILE))); inputFiles.put(InputFile.NONTAXACC, new FlatFile(new File(inputDir + File.separator + NONTAXACC_FILE))); inputFiles.put(InputFile.SECTOR, new FlatFile(new File(inputDir + File.separator + SECTOR_FILE))); inputFiles.put(InputFile.SECURITY, new FlatFile(new File(inputDir + File.separator + SECURITY_FILE))); inputFiles.put(InputFile.STATUS, new FlatFile(new File(inputDir + File.separator + STATUS_FILE))); inputFiles.put(InputFile.TAXACC, new FlatFile(new File(inputDir + File.separator + TAXACC_FILE))); inputFiles.put(InputFile.TRADETYPE, new FlatFile(new File(inputDir + File.separator + TRADETYPE_FILE))); inputFiles.put(InputFile.TAXCOUNTRY, new ArrayFile(new File(inputDir + File.separator + TAXCOUNTRY_FILE))); inputFiles.put(InputFile.TAXDIV, new ArrayFile(new File(inputDir + File.separator + TAXDIV_FILE))); this.currentCustomers = total_customers; this.customerStartId = TPCEConstants.DEFAULT_START_CUSTOMER_ID; this.total_customers = total_customers; this.scaling_factor = scaling_factor; this.initial_days = initial_days; } /** * This function changes customer parameters for every subsequent table generator created afterwards. * Each generator that depends on the number of customers will use these to generate its tuple. The number * of customers MUST be multiple of the load unit size (i.e., 1000) and the customers should start from * the beginning of the unit. The same table generators can work in parallel. To create generators with different * parameters, this function must be called first and then the generators created. * * @param numCustomers The number of customers * @param startCustomer The starting customer number */ public void changeSessionParams(long numCustomers, long startCustomer) { if (numCustomers <= 0 || numCustomers % TPCEConstants.DEFAULT_LOAD_UNIT != 0) { throw new IllegalArgumentException("The number of customers must be a positive integer multiple of the load unit size"); } if (startCustomer % TPCEConstants.DEFAULT_LOAD_UNIT != 1) { throw new IllegalArgumentException("The customer number must start from the beginning of a unit"); } if (startCustomer + numCustomers - 1 > total_customers) { throw new IllegalArgumentException("The number of customers for a session must not exceed the total number of customers"); } this.currentCustomers = numCustomers; this.customerStartId = startCustomer; } public long getCustomersNum() { return currentCustomers; } public long getStartCustomer() { return customerStartId; } // the number of companies depends on the total number of customers public long getCompanyCount(long customersNum) { return customersNum / TPCEConstants.DEFAULT_LOAD_UNIT * TPCEConstants.DEFAULT_COMPANIES_PER_UNIT; } // the number of company competitors depends on the total number of customers public long getCompanyCompetitorCount(long customersNum) { return customersNum / TPCEConstants.DEFAULT_LOAD_UNIT * TPCEConstants.DEFAULT_COMPANY_COMPETITORS_PER_UNIT; } public void parseInputFiles() { for (InputFileHandler file: inputFiles.values()) { file.parseFile(); } } public TableGenerator getTableGen(String tableName, Table catalogTable) { TableGenerator gen = null; try { Constructor<?> ctor = genClasses.get(tableName).getDeclaredConstructor(Table.class, TPCEGenerator.class); gen = (TableGenerator)ctor.newInstance(catalogTable, this); } catch (NoSuchMethodException e) { LOG.error("Cannot create a generator for: '" + tableName + "' -- no constructor"); System.exit(1); } catch (InvocationTargetException e) { LOG.error("Cannot create a generator for: '" + tableName + "' -- constructor call error"); System.exit(1); } catch (IllegalAccessException e) { LOG.error("Cannot create a generator for: '" + tableName + "'"); System.exit(1); } catch (InstantiationException e) { LOG.error("Cannot create a generator for: '" + tableName + "'"); System.exit(1); } return gen; } public InputFileHandler getInputFile(InputFile file) { return inputFiles.get(file); } public long getTotalCustomers() { return total_customers; } public int getScalingFactor() { return scaling_factor; } public int getInitTradeDays() { return initial_days; } }