Skip to content

Commit

Permalink
implement tpcc response time distribution statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
t-horikawa committed Oct 9, 2024
1 parent 379bd39 commit 761e351
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public void run() {
wId = (int) delivery.warehouseId();
if (!doingDelivery.getAndSet(wId - 1, true)) {
delivery.transaction(stop);
profile.time.delivery += (System.nanoTime() - transactionStart);
profile.addTimeDelivery(System.nanoTime() - transactionStart);
doingDelivery.set(wId - 1, false);
pendingDelivery--;
if (pendingDelivery > 0) {
Expand All @@ -81,15 +81,15 @@ public void run() {
if (transactionType <= Percent.KXCT_NEWORDER_PERCENT) {
newOrder.setParams();
newOrder.transaction(stop);
profile.time.newOrder += (System.nanoTime() - transactionStart);
profile.addTimeNewOrder(System.nanoTime() - transactionStart);
} else if (transactionType <= Percent.KXCT_PAYMENT_PERCENT) {
payment.setParams();
payment.transaction(stop);
profile.time.payment += (System.nanoTime() - transactionStart);
profile.addTimePayment(System.nanoTime() - transactionStart);
} else if (transactionType <= Percent.KXCT_ORDERSTATUS_PERCENT) {
orderStatus.setParams();
orderStatus.transaction(stop);
profile.time.orderStatus += (System.nanoTime() - transactionStart);
profile.addTimeOrderStatus(System.nanoTime() - transactionStart);
} else if (transactionType <= Percent.KXCT_DELIEVERY_PERCENT) {
if (pendingDelivery > 0) {
pendingDelivery++;
Expand All @@ -99,15 +99,15 @@ public void run() {
wId = (int) delivery.warehouseId();
if (!doingDelivery.getAndSet(wId - 1, true)) {
delivery.transaction(stop);
profile.time.delivery += (System.nanoTime() - transactionStart);
profile.addTimeDelivery(System.nanoTime() - transactionStart);
doingDelivery.set(wId - 1, false);
} else {
pendingDelivery++;
}
} else {
stockLevel.setParams();
stockLevel.transaction(stop);
profile.time.stockLevel += (System.nanoTime() - transactionStart);
profile.addTimeStockLevel(System.nanoTime() - transactionStart);
}
}
profile.elapsed = System.currentTimeMillis() - start;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void rollback(Transaction transaction) throws IOException, ServerException, Inte

@SuppressWarnings("checkstyle:methodlength")
public void transaction(AtomicBoolean stop) throws IOException, ServerException, InterruptedException {
while (!stop.get()) {
while (!stop.get()) { // placed for transaction reexecution due to failure. If the transaction ends normally, it returns.
try (var transaction = sqlClient.createTransaction().get();) {
profile.invocation.delivery++;
long dId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void rollback(Transaction transaction) throws IOException, ServerException, Inte

@SuppressWarnings("checkstyle:methodlength")
public void transaction(AtomicBoolean stop) throws IOException, ServerException, InterruptedException {
while (!stop.get()) {
while (!stop.get()) { // placed for transaction reexecution due to failure. If the transaction ends normally, it returns.
try (var transaction = sqlClient.createTransaction().get();) {
profile.invocation.newOrder++;
total = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ void rollback(Transaction transaction) throws IOException, ServerException, Inte

@SuppressWarnings("checkstyle:methodlength")
public void transaction(AtomicBoolean stop) throws IOException, ServerException, InterruptedException {
while (!stop.get()) {
while (!stop.get()) { // placed for transaction reexecution due to failure. If the transaction ends normally, it returns.
try (var transaction = sqlClient.createTransaction().get();) {
profile.invocation.orderStatus++;
if (!paramsByName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ void rollback(Transaction transaction) throws IOException, ServerException, Inte

@SuppressWarnings("checkstyle:methodlength")
public void transaction(AtomicBoolean stop) throws IOException, ServerException, InterruptedException {
while (!stop.get()) {
while (!stop.get()) { // placed for transaction reexecution due to failure. If the transaction ends normally, it returns.
try (var transaction = sqlClient.createTransaction().get();) {
profile.invocation.payment++;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,69 @@
package com.tsurugidb.tsubakuro.examples.tpcc;

public class Profile {
static class Counter {
long newOrder;
long payment;
long orderStatus;
long delivery;
long stockLevel;
static final int RESPONSE_TIME_DIV = 101;
static final int DIV = 10;

Counter() {
this.newOrder = 0;
this.payment = 0;
this.orderStatus = 0;
this.delivery = 0;
this.stockLevel = 0;
}
void add(Counter counter) {
newOrder += counter.newOrder;
payment += counter.payment;
orderStatus += counter.orderStatus;
delivery += counter.delivery;
stockLevel += counter.stockLevel;
static class ResponseTimeDistribution {
private String name;
private long[] counters = new long[RESPONSE_TIME_DIV];

ResponseTimeDistribution(String name) {
this.name = name;
}
public void put(long t) {
counters[index(t)]++;
}
private int index(long t) { // ns -> ms
int i = (int) ((t - 500000) / 1000000);
if (i < RESPONSE_TIME_DIV) {
return i;
}
return RESPONSE_TIME_DIV - 1;
}
void print() {
System.out.printf("response time distribution for %s transaction%n", name);
for (int i = 0; i < RESPONSE_TIME_DIV / DIV; i++) {
System.out.printf("%3d-%3d(ms): ", i * RESPONSE_TIME_DIV + 1, i * RESPONSE_TIME_DIV + DIV);
for (int j = 0; j < DIV; j++) {
int idx = i * RESPONSE_TIME_DIV + j;
if (idx >= RESPONSE_TIME_DIV) {
System.out.printf("%n");
return;
}
System.out.printf(" %6d", counters[idx]);
}
System.out.printf("%n");
}
}
}
static class Counter {
long newOrder;
long payment;
long orderStatus;
long delivery;
long stockLevel;

Counter() {
this.newOrder = 0;
this.payment = 0;
this.orderStatus = 0;
this.delivery = 0;
this.stockLevel = 0;
}
void add(Counter counter) {
newOrder += counter.newOrder;
payment += counter.payment;
orderStatus += counter.orderStatus;
delivery += counter.delivery;
stockLevel += counter.stockLevel;
}
}

public long warehouses;
public long threads;
public long index;
public boolean fixThreadMapping;
public Counter time;
public Counter invocation;
public Counter completion;
public Counter retryOnStatement;
Expand All @@ -43,80 +78,101 @@ void add(Counter counter) {
public long elapsed;
public long count;
public long inconsistentIndexCount; // for temporary use

private Counter time;
private ResponseTimeDistribution newOrderDistribution;

public Profile() {
time = new Counter();
invocation = new Counter();
completion = new Counter();
retryOnStatement = new Counter();
retryOnCommit = new Counter();
error = new Counter();
districtTable = new Counter();
warehouseTable = new Counter();
ordersTable = new Counter();
customerTable = new Counter();
stockTable = new Counter();
newOrderIntentionalRollback = 0;
count = 0;
inconsistentIndexCount = 0; // for temporary use
time = new Counter();
invocation = new Counter();
completion = new Counter();
retryOnStatement = new Counter();
retryOnCommit = new Counter();
error = new Counter();
districtTable = new Counter();
warehouseTable = new Counter();
ordersTable = new Counter();
customerTable = new Counter();
stockTable = new Counter();
newOrderDistribution = new ResponseTimeDistribution("new order");
newOrderIntentionalRollback = 0;
count = 0;
inconsistentIndexCount = 0; // for temporary use
}
public void add(Profile profile) {
time.add(profile.time);
invocation.add(profile.invocation);
completion.add(profile.completion);
retryOnStatement.add(profile.retryOnStatement);
retryOnCommit.add(profile.retryOnCommit);
error.add(profile.error);
districtTable.add(profile.districtTable);
warehouseTable.add(profile.warehouseTable);
ordersTable.add(profile.ordersTable);
customerTable.add(profile.customerTable);
stockTable.add(profile.stockTable);
newOrderIntentionalRollback += profile.newOrderIntentionalRollback;
elapsed += profile.elapsed;
count++;
inconsistentIndexCount += profile.inconsistentIndexCount; // for temporary use
time.add(profile.time);
invocation.add(profile.invocation);
completion.add(profile.completion);
retryOnStatement.add(profile.retryOnStatement);
retryOnCommit.add(profile.retryOnCommit);
error.add(profile.error);
districtTable.add(profile.districtTable);
warehouseTable.add(profile.warehouseTable);
ordersTable.add(profile.ordersTable);
customerTable.add(profile.customerTable);
stockTable.add(profile.stockTable);
newOrderIntentionalRollback += profile.newOrderIntentionalRollback;
elapsed += profile.elapsed;
count++;
inconsistentIndexCount += profile.inconsistentIndexCount; // for temporary use
}
long ns2us(long t) {
return (t + 500) / 1000;
return (t + 500) / 1000;
}
long div(long a, long b) {
if (b == 0) {
return a;
if (b == 0) {
return a;
}
return a / b;
}
return a / b;
void addTimeNewOrder(long t) {
time.newOrder += t;
newOrderDistribution.put(t);
}
public void print(int n) {
if (inconsistentIndexCount > 0) { // for temporary use
System.out.printf("retry due to inconsistent_index: %d times%n%n", inconsistentIndexCount);
void addTimePayment(long t) {
time.payment += t;
}
void addTimeOrderStatus(long t) {
time.orderStatus += t;
}
void addTimeDelivery(long t) {
time.delivery += t;
}
System.out.printf("duration(mS): %d%n", elapsed / count);
System.out.println("===============================================================================================");
System.out.printf(" new order: %12d / %8d = %6d (us)%n", ns2us(time.newOrder), completion.newOrder + newOrderIntentionalRollback, ns2us(div(time.newOrder , (completion.newOrder + newOrderIntentionalRollback))));
System.out.printf(" payment: %12d / %8d = %6d (us)%n", ns2us(time.payment), completion.payment, ns2us(div(time.payment, completion.payment)));
System.out.printf("order status: %12d / %8d = %6d (us)%n", ns2us(time.orderStatus), completion.orderStatus, ns2us(div(time.orderStatus, completion.orderStatus)));
System.out.printf(" delivery: %12d / %8d = %6d (us)%n", ns2us(time.delivery), completion.delivery, ns2us(div(time.delivery, completion.delivery)));
System.out.printf(" stock level: %12d / %8d = %6d (us)%n", ns2us(time.stockLevel), completion.stockLevel, ns2us(div(time.stockLevel, completion.stockLevel)));
System.out.println("===============================================================================================");
System.out.println(" tx type: invocation:completion(:intentional rollback) - retry on statement:retry on commit");
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf(" new order: %8d:%8d:%8d - %8d:%8d%n", invocation.newOrder, completion.newOrder, newOrderIntentionalRollback, retryOnStatement.newOrder, retryOnCommit.newOrder);
System.out.printf(" payment: %8d:%8d - %8d:%8d%n", invocation.payment, completion.payment, retryOnStatement.payment, retryOnCommit.payment);
System.out.printf("order status: %8d:%8d - %8d:%8d%n", invocation.orderStatus, completion.orderStatus, retryOnStatement.orderStatus, retryOnCommit.orderStatus);
System.out.printf(" delivery: %8d:%8d - %8d:%8d%n", invocation.delivery, completion.delivery, retryOnStatement.delivery, retryOnCommit.delivery);
System.out.printf(" stock level: %8d:%8d - %8d:%8d%n", invocation.stockLevel, completion.stockLevel, retryOnStatement.stockLevel, retryOnCommit.stockLevel);
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf(" new order: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.newOrder, districtTable.newOrder, warehouseTable.newOrder, customerTable.newOrder, stockTable.newOrder);
System.out.printf(" payment: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.payment, districtTable.payment, warehouseTable.payment, customerTable.payment, stockTable.payment);
System.out.printf("order status: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.orderStatus, districtTable.orderStatus, warehouseTable.orderStatus, customerTable.orderStatus, stockTable.orderStatus);
System.out.printf(" delivery: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.delivery, districtTable.delivery, warehouseTable.delivery, customerTable.delivery, stockTable.delivery);
System.out.printf(" stock level: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.stockLevel, districtTable.stockLevel, warehouseTable.stockLevel, customerTable.stockLevel, stockTable.stockLevel);
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf("##NoTPM=%.2f%n", ((double) completion.newOrder * 60.0 * 1000.0) / ((double) elapsed / (double) n));
void addTimeStockLevel(long t) {
time.stockLevel += t;
}
public void print(int n) {
if (inconsistentIndexCount > 0) { // for temporary use
System.out.printf("retry due to inconsistent_index: %d times%n%n", inconsistentIndexCount);
}
System.out.printf("duration(mS): %d%n", elapsed / count);
System.out.println("===============================================================================================");
System.out.printf(" new order: %12d / %8d = %6d (us)%n", ns2us(time.newOrder), completion.newOrder + newOrderIntentionalRollback, ns2us(div(time.newOrder , (completion.newOrder + newOrderIntentionalRollback))));
System.out.printf(" payment: %12d / %8d = %6d (us)%n", ns2us(time.payment), completion.payment, ns2us(div(time.payment, completion.payment)));
System.out.printf("order status: %12d / %8d = %6d (us)%n", ns2us(time.orderStatus), completion.orderStatus, ns2us(div(time.orderStatus, completion.orderStatus)));
System.out.printf(" delivery: %12d / %8d = %6d (us)%n", ns2us(time.delivery), completion.delivery, ns2us(div(time.delivery, completion.delivery)));
System.out.printf(" stock level: %12d / %8d = %6d (us)%n", ns2us(time.stockLevel), completion.stockLevel, ns2us(div(time.stockLevel, completion.stockLevel)));
System.out.println("===============================================================================================");
System.out.println(" tx type: invocation:completion(:intentional rollback) - retry on statement:retry on commit");
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf(" new order: %8d:%8d:%8d - %8d:%8d%n", invocation.newOrder, completion.newOrder, newOrderIntentionalRollback, retryOnStatement.newOrder, retryOnCommit.newOrder);
System.out.printf(" payment: %8d:%8d - %8d:%8d%n", invocation.payment, completion.payment, retryOnStatement.payment, retryOnCommit.payment);
System.out.printf("order status: %8d:%8d - %8d:%8d%n", invocation.orderStatus, completion.orderStatus, retryOnStatement.orderStatus, retryOnCommit.orderStatus);
System.out.printf(" delivery: %8d:%8d - %8d:%8d%n", invocation.delivery, completion.delivery, retryOnStatement.delivery, retryOnCommit.delivery);
System.out.printf(" stock level: %8d:%8d - %8d:%8d%n", invocation.stockLevel, completion.stockLevel, retryOnStatement.stockLevel, retryOnCommit.stockLevel);
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf(" new order: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.newOrder, districtTable.newOrder, warehouseTable.newOrder, customerTable.newOrder, stockTable.newOrder);
System.out.printf(" payment: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.payment, districtTable.payment, warehouseTable.payment, customerTable.payment, stockTable.payment);
System.out.printf("order status: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.orderStatus, districtTable.orderStatus, warehouseTable.orderStatus, customerTable.orderStatus, stockTable.orderStatus);
System.out.printf(" delivery: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.delivery, districtTable.delivery, warehouseTable.delivery, customerTable.delivery, stockTable.delivery);
System.out.printf(" stock level: ORDERS %6d DISTRICT %6d WAREHOUSE %6d CUSTOMER %6d STOCK %6d%n",
ordersTable.stockLevel, districtTable.stockLevel, warehouseTable.stockLevel, customerTable.stockLevel, stockTable.stockLevel);
System.out.println("-----------------------------------------------------------------------------------------------");
System.out.printf("##NoTPM=%.2f%n", ((double) completion.newOrder * 60.0 * 1000.0) / ((double) elapsed / (double) n));
System.out.printf("\n");
newOrderDistribution.print();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void rollback(Transaction transaction) throws IOException, ServerException, Inte
}

public void transaction(AtomicBoolean stop) throws IOException, ServerException, InterruptedException {
while (!stop.get()) {
while (!stop.get()) { // placed for transaction reexecution due to failure. If the transaction ends normally, it returns.
profile.invocation.stockLevel++;
try (var transaction = sqlClient.createTransaction().get();) {

Expand Down

0 comments on commit 761e351

Please sign in to comment.