/*************************************************************************** * 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 org.voltdb.catalog.Table; import org.voltdb.types.TimestampType; import edu.brown.benchmark.tpce.TPCEConstants; import edu.brown.benchmark.tpce.util.EGenDate; import edu.brown.benchmark.tpce.util.EGenRandom; public class FinancialGenerator extends TableGenerator { // Multiplier to get the diluted number of shares from outstanding private static final double dilutedSharesMultiplier = 1.1; // Multipliers for previous quarter to get the current quarter data private static final double finDataDownMult = 0.9; private static final double finDataUpMult = 1.15; /* * Parameters to generate random values for companies */ private static final double financialRevenueMin = 100000.0; private static final double financialRevenueMax = 16000000000.0; private static final double financialEarningsMin = -300000000.0; private static final double financialEarningsMax = 3000000000.0; private static final double financialOutBasicMin = 400000.0; private static final double financialOutBasicMax = 9500000000.0; private static final double financialInventMin = 0.0; private static final double financialInventMax = 2000000000.0; private static final double financialAssetsMin = 100000.0; private static final double financialAssetsMax = 65000000000.0; private static final double financialLiabMin = 100000.0; private static final double financialLiabMax = 35000000000.0; private static final int yearsForFins = 5; private static final int quartersInYear = 4; private int finsGeneratedForCompany; private static final int finsPerCompany = yearsForFins * quartersInYear; // 5 years of 4 quarters for each company private long counter; private long coId; private int finYear; private int finQuarter; private double finRev, finEarn, finInvent, finAssets, finLiab, finOutBasic; private final EGenRandom rnd = new EGenRandom(EGenRandom.RNG_SEED_TABLE_DEFAULT); private final CompanyGenerator compGenerator; /* * Number of RNG calls to skip for one row in order * to not use any of the random values from the previous row. */ private static final int rngSkipOneRowFinancial = 6 + finsPerCompany * 6; /** * @param catalog_tbl * @param generator */ public FinancialGenerator(Table catalog_tbl, TPCEGenerator generator) { super(catalog_tbl, generator); compGenerator = (CompanyGenerator)generator.getTableGen(TPCEConstants.TABLENAME_COMPANY, null); finsGeneratedForCompany = finsPerCompany; // the counter depends on the starting company number counter = generator.getCompanyCount(generator.getStartCustomer()) * finsPerCompany; } private void initNextLoadUnit() { rnd.setSeedNth(EGenRandom.RNG_SEED_TABLE_DEFAULT, counter * rngSkipOneRowFinancial); } /* (non-Javadoc) * @see java.util.Iterator#hasNext() */ @Override public boolean hasNext() { return compGenerator.hasNext() || finsGeneratedForCompany < finsPerCompany; } /* (non-Javadoc) * @see java.util.Iterator#next() */ @Override public Object[] next() { Object tuple[] = new Object[columnsNum]; if (finsGeneratedForCompany == finsPerCompany) { // reset the random generator if (counter % (TPCEConstants.DEFAULT_COMPANIES_PER_UNIT * finsPerCompany) == 0) { initNextLoadUnit(); } coId = compGenerator.generateCompId(); finsGeneratedForCompany = 0; finYear = TPCEConstants.dailyMarketBaseYear; finQuarter = TPCEConstants.dailyMarketBaseMonth / 3; /* * Generate basic parameters for the new company */ finRev = rnd.doubleIncrRange(financialRevenueMin, financialRevenueMax, 0.01); finEarn = rnd.doubleIncrRange(financialEarningsMin, finRev < financialEarningsMax ? finRev : financialEarningsMax, 0.01); finOutBasic = rnd.doubleIncrRange(financialOutBasicMin, financialOutBasicMax, 0.01); finInvent = rnd.doubleIncrRange(financialInventMin, financialInventMax, 0.01); finAssets = rnd.doubleIncrRange(financialAssetsMin, financialAssetsMax, 0.01); finLiab = rnd.doubleIncrRange(financialLiabMin, financialLiabMax, 0.01); } tuple[0] = coId; // fi_co_id tuple[1] = finYear; // fi_year tuple[2] = finQuarter + 1; // fi_qtr tuple[3] = new TimestampType(EGenDate.getDateFromYMD(finYear, finQuarter * 3, 1)); // fi_qtr_start_date finRev *= rnd.doubleRange(finDataDownMult, finDataUpMult); // finRev is changed incrementally! tuple[4] = finRev; // fi_revenue finEarn *= rnd.doubleRange(finDataDownMult, finDataUpMult); if (finEarn > finRev) { finEarn = 0.9 * finRev; } tuple[5] = finEarn; // fi_net_earn finOutBasic *= rnd.doubleRange(finDataDownMult, finDataUpMult); tuple[6] = finEarn / finOutBasic; // fi_basic_eps tuple[7] = finEarn / (finOutBasic * dilutedSharesMultiplier); // fi_dilut_eps tuple[8] = finEarn / finRev; // fi_margin finInvent *= rnd.doubleRange(finDataDownMult, finDataUpMult); tuple[9] = finInvent; // fi_inventory finAssets *= rnd.doubleRange(finDataDownMult, finDataUpMult); tuple[10] = finAssets; // fi_assets finLiab *= rnd.doubleRange(finDataDownMult, finDataUpMult); tuple[11] = finLiab; // fi_liability tuple[12] = finOutBasic; // fi_out_basic tuple[13] = finOutBasic * dilutedSharesMultiplier; // fi_out_dilut finQuarter++; if (finQuarter == 4) { finQuarter = 0; finYear++; } counter++; finsGeneratedForCompany++; return tuple; } }