/***************************************************************************
* Copyright (C) 2009 by H-Store Project *
* Brown University *
* Massachusetts Institute of Technology *
* Yale University *
* *
* Original Version: *
* Zhe Zhang (zhe@cs.brown.edu) *
* http://www.cs.brown.edu/~zhe/ *
* *
* Modifications by: *
* Andy Pavlo (pavlo@cs.brown.edu) *
* http://www.cs.brown.edu/~pavlo/ *
* *
* 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;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import org.apache.log4j.Logger;
import org.voltdb.SysProcSelector;
import org.voltdb.VoltTable;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.ProcedureCallback;
import edu.brown.api.BenchmarkComponent;
import edu.brown.benchmark.tm1.TM1Client.Transaction;
import edu.brown.benchmark.tpce.TPCEConstants.DriverType;
import edu.brown.benchmark.tpce.generators.*;
import edu.brown.benchmark.tpce.util.RandUtil;
import edu.brown.benchmark.tpce.util.TableStatistics;
/**
* @author pavlo
*/
public class TPCEClient extends BenchmarkComponent {
private static final Logger LOG = Logger.getLogger(TPCEClient.class);
public static final int STATUS_SUCCESS = 0;
private static Transaction XTRANS[] = Transaction.values();
// EGen Drivers
protected final EGenClientDriver egen_clientDriver;
private class TPCECallback implements ProcedureCallback {
private final Transaction t;
public TPCECallback(Transaction t) {
this.t = t;
}
@Override
public void clientCallback(ClientResponse clientResponse) {
incrementTransactionCounter(clientResponse, t.ordinal());
}
}
/**
* @author pavlo
*/
private static class StatsCallback implements ProcedureCallback {
public final CountDownLatch latch = new CountDownLatch(1);
@Override
public void clientCallback(ClientResponse clientResponse) {
LOG.info("Processing statistics callback information");
VoltTable[] results = clientResponse.getResults();
for (VoltTable vt : results) {
//
// [0] SITE_ID
// [1] STAT_TIME
// [2] TABLE_NAME
// [3] TABLE_TYPE
// [4] TABLE_ACTIVE_TUPLE_COUNT
// [5] TABLE_ALLOCATED_TUPLE_COUNT
// [6] TABLE_DELETED_TUPLE_COUNT
//
while (vt.advanceRow()) {
String table_name = vt.getString(2);
long count = vt.getLong(4);
TableStatistics.addTupleCount(table_name, count);
} // WHILE
} // FOR
LOG.info("Finished collecting statistic. Number of tables = " + TableStatistics.getTables().size());
latch.countDown();
}
}
private static enum Transaction {
BROKER_VOLUME("Broker Volume", "BrokerVolume", TPCEConstants.FREQUENCY_BROKER_VOLUME),
CUSTOMER_POSITION("Customer Position", "CustomerPosition", TPCEConstants.FREQUENCY_CUSTOMER_POSITION),
//TODO not supported transaction
// MARKET_FEED("Market Feed", "MarketFeed", TPCEConstants.FREQUENCY_MARKET_FEED),
MARKET_WATCH("Market Watch", "MarketWatch", TPCEConstants.FREQUENCY_MARKET_WATCH),
SECURITY_DETAIL("Security Detail", "SecurityDetail", TPCEConstants.FREQUENCY_SECURITY_DETAIL),
TRADE_LOOKUP("Trade Lookup", "TradeLookup", TPCEConstants.FREQUENCY_TRADE_LOOKUP),
TRADE_ORDER("Trade Order", "TradeOrder", TPCEConstants.FREQUENCY_TRADE_ORDER),
// TRADE_RESULT("Trade Result", "TradeResult", TPCEConstants.FREQUENCY_TRADE_RESULT),
TRADE_STATUS("Trade Status", "TradeStatus", TPCEConstants.FREQUENCY_TRADE_STATUS),
TRADE_UPDATE("Trade Update", "TradeUpdate", TPCEConstants.FREQUENCY_TRADE_UPDATE);
private Transaction(String displayName, String callName, int weight) {
this.displayName = displayName;
this.callName = callName;
this.weight = weight;
}
public final String displayName;
public final String callName;
public final int weight;
}
/**
* Constructor
*
* @param args
*/
public TPCEClient(String[] args) {
super(args);
if (!m_extraParams.containsKey("TPCE_LOADER_FILES")) {
LOG.error("Unable to start benchmark. Missing '" + "TPCE_LOADER_FILES" + "' parameter");
System.exit(1);
}
int total_customers = TPCEConstants.DEFAULT_NUM_CUSTOMERS;
if (m_extraParams.containsKey("TPCE_TOTAL_CUSTOMERS")) {
total_customers = Integer.valueOf(m_extraParams.get("TPCE_TOTAL_CUSTOMERS"));
}
int scale_factor = TPCEConstants.DEFAULT_SCALE_FACTOR;
if (m_extraParams.containsKey("TPCE_SCALE_FACTOR")) {
scale_factor = Integer.valueOf(m_extraParams.get("TPCE_SCALE_FACTOR"));
}
int initial_days = TPCEConstants.DEFAULT_INITIAL_DAYS;
if (m_extraParams.containsKey("TPCE_INITIAL_DAYS")) {
initial_days = Integer.valueOf(m_extraParams.get("TPCE_INITIAL_DAYS"));
}
this.egen_clientDriver = new EGenClientDriver(m_extraParams.get("TPCE_LOADER_FILES"), total_customers, scale_factor, initial_days);
}
@Override
public String[] getTransactionDisplayNames() {
String names[] = new String[XTRANS.length];
int i = 0;
for (Transaction transaction : XTRANS) {
names[i++] = transaction.displayName;
}
return names;
}
protected Transaction selectTransaction() {
int iTxnType = egen_clientDriver.driver_ptr.getCE().getCETxnMixGenerator().generateNextTxnType( );
egen_clientDriver.driver_ptr.getCE().zeroInputBuffer(iTxnType);
// return Transaction.TRADE_UPDATE;
return XTRANS[iTxnType];
}
/**
* Main control loop
*/
@Override
public void runLoop() {
int no_connection = 10000;
try {
final Transaction target = selectTransaction();
LOG.debug("Executing txn " + target);
while (!this.getClientHandle().callProcedure(new TPCECallback(target), target.callName, this.generateClientArgs(target))) {
this.getClientHandle().backpressureBarrier();
}
} catch (NoConnectionsException e) {
if (no_connection % 1000 == 0)
System.err.println("No connections...");
if (no_connection-- <= 0) {
System.err.println("Screw this! I'm leaving! Thanks for nothing!");
return;
}
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
}
@Override
protected boolean runOnce() throws IOException {
boolean ret = false;
try {
final Transaction target = selectTransaction();
LOG.debug("Executing txn " + target);
ret = this.getClientHandle().callProcedure(new TPCECallback(target), target.callName, this.generateClientArgs(target));
} catch (Exception ex) {
ex.printStackTrace();
System.exit(1);
}
return ret;
}
/**
* For a given transaction type, use the EGenClientDriver to generate input
* parameters for execution
*
* @param xact
* @return
*/
private Object[] generateClientArgs(Transaction xact) {
switch (xact) {
case BROKER_VOLUME:
return (this.egen_clientDriver.getBrokerVolumeParams());
case CUSTOMER_POSITION:
return (this.egen_clientDriver.getCustomerPositionParams());
case MARKET_WATCH:
return (this.egen_clientDriver.getMarketWatchParams());
case SECURITY_DETAIL:
return (this.egen_clientDriver.getSecurityDetailParams());
case TRADE_LOOKUP:
return (this.egen_clientDriver.getTradeLookupParams());
case TRADE_ORDER:
return (this.egen_clientDriver.getTradeOrderParams());
case TRADE_STATUS:
return (this.egen_clientDriver.getTradeStatusParams());
case TRADE_UPDATE:
return (this.egen_clientDriver.getTradeUpdateParams());
default:
LOG.error("Unsupported client transaction: " + xact);
} // SWITCH
return (null);
}
/**
* @param args
*/
public static void main(String[] args) {
BenchmarkComponent.main(TPCEClient.class, args, false);
}
}