Skip to content

Commit

Permalink
New SendPayment txn for SmallBank benchmark.
Browse files Browse the repository at this point in the history
New config parameters for controlling hotpot and dtxn information.
Fixes for the Amalgamate txn.

Watching baseball with KB. I should probably head upstairs and focus a little bit more so I can graduate and move to Pittsburgh (and KB will get a terrier).

We're finally getting rid of Carleton's cards... #117
  • Loading branch information
apavlo committed May 5, 2013
1 parent 3a3843c commit 1773453
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 25 deletions.
8 changes: 8 additions & 0 deletions properties/benchmarks/smallbank.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,11 @@
## ------------------------------------------------------------

builder = edu.brown.benchmark.smallbank.SmallBankProjectBuilder

# The probability that customer's will be randomly selected from the hotspot accounts
# You can change the hotspot size in SmallBankConstants [0% - 100%]
prob_account_hotspot = 90

# The probability that the multi-account transactions will be guaranteed
# to be multi-partition [0% - 100%].
prob_multiaccount_dtxn = 0
4 changes: 4 additions & 0 deletions src/benchmarks/edu/brown/api/BenchmarkComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -1091,6 +1091,10 @@ protected final Integer getTransactionWeight(String txnName) {
* @return
*/
protected final Integer getTransactionWeight(String txnName, Integer weightIfNull) {
if (debug.val)
LOG.debug(String.format("Looking for txn weight for '%s' [weightIfNull=%s]",
txnName, weightIfNull));

Long val = this.m_txnWeights.get(txnName.toUpperCase());
if (val != null) {
return (val.intValue());
Expand Down
90 changes: 67 additions & 23 deletions src/benchmarks/edu/brown/benchmark/smallbank/SmallBankClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,17 @@
package edu.brown.benchmark.smallbank;

import java.io.IOException;
import java.util.Arrays;
import java.util.Random;

import org.apache.log4j.Logger;
import org.voltdb.TheHashinator;
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;
Expand All @@ -49,6 +53,10 @@
*/
public class SmallBankClient extends BenchmarkComponent {
private static final Logger LOG = Logger.getLogger(SmallBankClient.class);
private static final LoggerBoolean debug = new LoggerBoolean(LOG.isDebugEnabled());
static {
LoggerUtil.attachObserver(LOG, debug);
}

/**
* Each Transaction element provides an ArgGenerator to create the proper
Expand Down Expand Up @@ -91,6 +99,15 @@ public Object[] genArgs(long acct0, long acct1) {
};
}
}),
SEND_PAYMENT(SmallBankConstants.FREQUENCY_SEND_PAYMENT, new ArgGenerator() {
public Object[] genArgs(long acct0, long acct1) {
return new Object[] {
acct0, // sendAcct
acct1, // destAcct
5.00 // amount
};
}
}),
TRANSACT_SAVINGS(SmallBankConstants.FREQUENCY_TRANSACT_SAVINGS, new ArgGenerator() {
public Object[] genArgs(long acct0, long acct1) {
return new Object[] {
Expand Down Expand Up @@ -118,24 +135,35 @@ private Transaction(int weight, ArgGenerator ag) {
this.ag = ag;
}

public Object[] generateParams(Random rand, int numAccounts) {
long acct0, acct1;
public Object[] generateParams(SmallBankClient client) {
long acctIds[] = new long[2];

// Outside the hotspot
if (rand.nextInt(100) < SmallBankConstants.HOTSPOT_PROBABILITY) {
acct0 = rand.nextInt(numAccounts - SmallBankConstants.HOTSPOT_SIZE) + SmallBankConstants.HOTSPOT_SIZE;
acct1 = rand.nextInt(numAccounts - SmallBankConstants.HOTSPOT_SIZE) + SmallBankConstants.HOTSPOT_SIZE;
LOG.debug(String.format("Random number outside hotspot: %s [%d, %d]",
this, acct0, acct1));
}
// Inside the hotspot
else {
acct0 = rand.nextInt(SmallBankConstants.HOTSPOT_SIZE);
acct1 = rand.nextInt(SmallBankConstants.HOTSPOT_SIZE);
LOG.debug(String.format("Random number inside hotspot: %s [%d, %d]",
this, acct0, acct1));
}
return (this.ag.genArgs(acct0, acct1));
boolean is_hotspot = (client.rand.nextInt(100) < client.prob_account_hotspot);
boolean is_dtxn = (client.rand.nextInt(100) < client.prob_multiaccount_dtxn);

for (int i = 0; i < acctIds.length; i++) {
// Outside the hotspot
if (is_hotspot == false) {
acctIds[i] = client.rand.nextInt(client.numAccounts - SmallBankConstants.HOTSPOT_SIZE) + SmallBankConstants.HOTSPOT_SIZE;
}
// Inside the hotspot
else {
acctIds[i] = client.rand.nextInt(SmallBankConstants.HOTSPOT_SIZE);
}

// DTXN
if (i == 1 && is_dtxn) {
if (TheHashinator.hashToPartition(acctIds[0]) == TheHashinator.hashToPartition(acctIds[1])) {
i -= 1;
continue;
}
}
} // FOR
if (debug.val)
LOG.debug(String.format("Accounts: %s [hotspot=%s, dtxn=%s]",
Arrays.toString(acctIds), is_hotspot, is_dtxn));

return (this.ag.genArgs(acctIds[0], acctIds[1]));
}

private final String displayName;
Expand Down Expand Up @@ -165,28 +193,44 @@ public void clientCallback(ClientResponse clientResponse) {
private final SmallBankCallback callbacks[];
private final int numAccounts;
private final Random rand = new Random();
private double prob_account_hotspot = 90d;
private double prob_multiaccount_dtxn = 0.0d;

public static void main(String args[]) {
BenchmarkComponent.main(SmallBankClient.class, args, false);
}

public SmallBankClient(String args[]) {
super(args);
TheHashinator.initialize(this.getCatalogContext().catalog);

this.numAccounts = (int)Math.round(SmallBankConstants.NUM_ACCOUNTS * this.getScaleFactor());

for (String key : m_extraParams.keySet()) {
String value = m_extraParams.get(key);

// Probability that accounts are chosen from the hotspot
if (key.equalsIgnoreCase("prob_account_hotspot")) {
this.prob_account_hotspot = Double.parseDouble(value);
}
// Probability that multi-accounts will be on different partitions
if (key.equalsIgnoreCase("prob_multiaccount_dtxn")) {
this.prob_multiaccount_dtxn = Double.parseDouble(value);
}

} // FOR

// 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;
}
if (weight == null) weight = t.weight;
txns.put(t, weight);
} // FOR
System.err.println(txns);
assert(txns.getSampleCount() == 100) : "Invalid txn percentage total: " + txns.getSampleCount() + "\n" + txns;
this.txnWeights = new FlatHistogram<Transaction>(this.rand, txns);
if (LOG.isDebugEnabled())
if (debug.val)
LOG.debug("Transaction Workload Distribution:\n" + txns);

// Setup callbacks
Expand All @@ -207,12 +251,12 @@ protected boolean runOnce() throws IOException {
Transaction target = this.txnWeights.nextValue();

this.startComputeTime(target.displayName);
Object params[] = target.generateParams(this.rand, this.numAccounts);
Object params[] = target.generateParams(this);
this.stopComputeTime(target.displayName);

ProcedureCallback callback = this.callbacks[target.ordinal()];
boolean ret = this.getClientHandle().callProcedure(callback, target.callName, params);
LOG.debug("Executing txn " + target);
if (debug.val) LOG.debug("Executing txn " + target);
return (ret);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public abstract class SmallBankConstants {
public static final int FREQUENCY_AMALGAMATE = 20;
public static final int FREQUENCY_BALANCE = 20;
public static final int FREQUENCY_DEPOSIT_CHECKING = 20;
public static final int FREQUENCY_SEND_PAYMENT = 0;
public static final int FREQUENCY_TRANSACT_SAVINGS = 20;
public static final int FREQUENCY_WRITE_CHECK = 20;

Expand All @@ -56,7 +57,6 @@ public abstract class SmallBankConstants {
// Default number of customers in bank
public static final int NUM_ACCOUNTS = 1000000;

public static final int HOTSPOT_PROBABILITY = 10;
public static final int HOTSPOT_SIZE = 100;

// ----------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import edu.brown.benchmark.smallbank.procedures.Amalgamate;
import edu.brown.benchmark.smallbank.procedures.Balance;
import edu.brown.benchmark.smallbank.procedures.DepositChecking;
import edu.brown.benchmark.smallbank.procedures.SendPayment;
import edu.brown.benchmark.smallbank.procedures.TransactSavings;
import edu.brown.benchmark.smallbank.procedures.WriteCheck;
import edu.brown.api.BenchmarkComponent;
Expand All @@ -61,6 +62,7 @@ public class SmallBankProjectBuilder extends AbstractProjectBuilder {
Amalgamate.class,
Balance.class,
DepositChecking.class,
SendPayment.class,
TransactSavings.class,
WriteCheck.class
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public VoltTable run(long acctId0, long acctId1) {
balResults[0].advanceRow();
balResults[1].advanceRow();
double total = balResults[0].getDouble(0) + balResults[1].getDouble(0);
assert(total >= 0);
// assert(total >= 0);

// Update Balance Information
voltQueueSQL(ZeroCheckingBalance, acctId0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package edu.brown.benchmark.smallbank.procedures;

import org.voltdb.ProcInfo;
import org.voltdb.SQLStmt;
import org.voltdb.VoltProcedure;
import org.voltdb.VoltTable;

import edu.brown.benchmark.smallbank.SmallBankConstants;

/**
* SendPayment Procedure
* @author pavlo
*/
@ProcInfo (
partitionParam=0
)
public class SendPayment extends VoltProcedure {

public final SQLStmt GetAccount = new SQLStmt(
"SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS +
" WHERE custid = ?"
);

public final SQLStmt GetCheckingBalance = new SQLStmt(
"SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING +
" WHERE custid = ?"
);

public final SQLStmt UpdateCheckingBalance = new SQLStmt(
"UPDATE " + SmallBankConstants.TABLENAME_CHECKING +
" SET bal = bal + ? " +
" WHERE custid = ?"
);

public VoltTable[] run(long sendAcct, long destAcct, double amount) {
// Get Account Information
voltQueueSQL(GetAccount, destAcct);
voltQueueSQL(GetAccount, sendAcct);
final VoltTable acctResults[] = voltExecuteSQL();
if (acctResults[0].getRowCount() != 1) {
String msg = "Invalid sender account '" + sendAcct + "'";
throw new VoltAbortException(msg);
}
else if (acctResults[1].getRowCount() != 1) {
String msg = "Invalid destination account '" + destAcct + "'";
throw new VoltAbortException(msg);
}

// Get the sender's account balance
voltQueueSQL(GetCheckingBalance, sendAcct);
final VoltTable balResults[] = voltExecuteSQL();
if (balResults[0].getRowCount() != 1) {
String msg = String.format("No %s for customer #%d",
SmallBankConstants.TABLENAME_SAVINGS,
sendAcct);
throw new VoltAbortException(msg);
}
balResults[0].advanceRow();
double balance = balResults[0].getDouble(0);

if (balance < 0) {
String msg = String.format("Insufficient %s funds for customer #%d",
SmallBankConstants.TABLENAME_CHECKING, sendAcct);
throw new VoltAbortException(msg);
}

// Debt
voltQueueSQL(UpdateCheckingBalance, amount*-1d, sendAcct);

// Credit
voltQueueSQL(UpdateCheckingBalance, amount, destAcct);

return (voltExecuteSQL(true));
}
}

0 comments on commit 1773453

Please sign in to comment.