package edu.brown.benchmark.simple; import java.io.IOException; import java.util.Random; import org.apache.log4j.Logger; import org.voltdb.CatalogContext; import org.voltdb.client.Client; import org.voltdb.client.ClientResponse; import org.voltdb.client.ProcedureCallback; import edu.brown.api.BenchmarkComponent; import edu.brown.logging.LoggerUtil; import edu.brown.logging.LoggerUtil.LoggerBoolean; import edu.brown.rand.RandomDistribution.FlatHistogram; import edu.brown.statistics.Histogram; import edu.brown.statistics.ObjectHistogram; public class SimpleClient extends BenchmarkComponent { private static final Logger LOG = Logger.getLogger(SimpleClient.class); private static final LoggerBoolean debug = new LoggerBoolean(true); static { LoggerUtil.attachObserver(LOG, debug); } public static enum Transaction { GET_DATA("Read Record", 100); // Constant /** * Constructor */ private Transaction(String displayName, int weight) { this.displayName = displayName; this.callName = displayName.replace(" ", ""); this.weight = weight; } public final String displayName; public final String callName; public final int weight; // probability (in terms of percentage) the transaction gets executed } // TRANSCTION ENUM private final long init_record_count; private final FlatHistogram<Transaction> txnWeights; private final Random rand_gen; int run_count = 0; public static void main(String args[]) { BenchmarkComponent.main(SimpleClient.class, args, false); } public SimpleClient(String args[]) { super(args); long size = -1; for (String key : m_extraParams.keySet()) { String value = m_extraParams.get(key); // Fixed Database Size if (key.equalsIgnoreCase("num_records")) { size = Long.valueOf(value); } } // FOR // Figure out the # of records that we need if (size > -1) this.init_record_count = size; else this.init_record_count = 100 ; // Constant this.rand_gen = new Random(); // Initialize the sampling table Histogram<Transaction> txns = new ObjectHistogram<Transaction>(); for (Transaction t : Transaction.values()) { Integer weight = this.getTransactionWeight(t.callName); if (weight == null) weight = t.weight; txns.put(t, weight); } // FOR assert(txns.getSampleCount() == 100) : txns; this.txnWeights = new FlatHistogram<Transaction>(this.rand_gen, txns); } @SuppressWarnings("unused") @Deprecated @Override public void runLoop() { try { Client client = this.getClientHandle(); while (true) { runOnce(); this.run_count++; } } catch (IOException e) { } } public static final Random rand = new Random(); // taken from tpcc.RandomGenerator public static long number(long minimum, long maximum) { assert minimum <= maximum; long value = Math.abs(rand.nextLong()) % (maximum - minimum + 1) + minimum; assert minimum <= value && value <= maximum; return value; } @Override protected boolean runOnce() throws IOException { final Transaction target = this.txnWeights.nextValue(); Object params[]; switch (target) { case GET_DATA: { params = new Object[]{ number(0, init_record_count) }; break; } default: throw new RuntimeException("Unexpected txn '" + target + "'"); } // SWITCH assert(params != null); Callback callback = new Callback(target.ordinal()); if(debug.val) LOG.debug("RUN: " + target.callName + " PARAMS : "+params[0]); return this.getClientHandle().callProcedure(callback, target.callName, params); } private class Callback implements ProcedureCallback { private final int idx; public Callback(int idx) { this.idx = idx; } @Override public void clientCallback(ClientResponse clientResponse) { // Increment the BenchmarkComponent's internal counter on the // number of transactions that have been completed incrementTransactionCounter(clientResponse, this.idx); } } // END CLASS @Override public String[] getTransactionDisplayNames() { // Return an array of transaction names String procNames[] = new String[SimpleProjectBuilder.PROCEDURES.length]; for (int i = 0; i < procNames.length; i++) { procNames[i] = SimpleProjectBuilder.PROCEDURES[i].getSimpleName(); } return (procNames); } }