From 15e39ecd2036aad8dd92f94b7d96129c6a6da3a5 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Thu, 7 Dec 2023 22:49:07 +0000 Subject: [PATCH 01/41] enable compiler warnings and linting --- pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index 04d1d5877..b7d0c9caa 100644 --- a/pom.xml +++ b/pom.xml @@ -282,6 +282,14 @@ ${maven.compiler.source} ${maven.compiler.target} + true + + + + -Xlint:all,-processing + + -Werror + From d66eaba578ff8dfa437c79cc7754fcd73de9e63e Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Thu, 7 Dec 2023 22:47:53 +0000 Subject: [PATCH 02/41] address some trailing whitespace warnings --- .../tpcc/procedures/OrderStatus.java | 32 +++++++++---------- .../benchmarks/tpcc/procedures/Payment.java | 2 +- .../tpcc/procedures/StockLevel.java | 6 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java index 0dc158b69..7ab943e51 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java @@ -40,17 +40,17 @@ public class OrderStatus extends TPCCProcedure { public SQLStmt ordStatGetNewestOrdSQL = new SQLStmt( """ - SELECT O_ID, O_CARRIER_ID, O_ENTRY_D + SELECT O_ID, O_CARRIER_ID, O_ENTRY_D FROM %s - WHERE O_W_ID = ? - AND O_D_ID = ? - AND O_C_ID = ? + WHERE O_W_ID = ? + AND O_D_ID = ? + AND O_C_ID = ? ORDER BY O_ID DESC LIMIT 1 """.formatted(TPCCConstants.TABLENAME_OPENORDER)); public SQLStmt ordStatGetOrderLinesSQL = new SQLStmt( """ - SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, OL_DELIVERY_D + SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, OL_DELIVERY_D FROM %s WHERE OL_O_ID = ? AND OL_D_ID = ? @@ -59,24 +59,24 @@ public class OrderStatus extends TPCCProcedure { public SQLStmt payGetCustSQL = new SQLStmt( """ - SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2, - C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, - C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE + SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2, + C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, + C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE FROM %s - WHERE C_W_ID = ? - AND C_D_ID = ? + WHERE C_W_ID = ? + AND C_D_ID = ? AND C_ID = ? """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); public SQLStmt customerByNameSQL = new SQLStmt( """ - SELECT C_FIRST, C_MIDDLE, C_ID, C_STREET_1, C_STREET_2, C_CITY, - C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, - C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE + SELECT C_FIRST, C_MIDDLE, C_ID, C_STREET_1, C_STREET_2, C_CITY, + C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, + C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE FROM %s - WHERE C_W_ID = ? - AND C_D_ID = ? - AND C_LAST = ? + WHERE C_W_ID = ? + AND C_D_ID = ? + AND C_LAST = ? ORDER BY C_FIRST """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java index 2a55c6d5c..1531a87eb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java @@ -41,7 +41,7 @@ public class Payment extends TPCCProcedure { """ UPDATE %s SET W_YTD = W_YTD + ? - WHERE W_ID = ? + WHERE W_ID = ? """.formatted(TPCCConstants.TABLENAME_WAREHOUSE)); public SQLStmt payGetWhseSQL = new SQLStmt( diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java index ca5f836b4..307014450 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java @@ -36,15 +36,15 @@ public class StockLevel extends TPCCProcedure { public SQLStmt stockGetDistOrderIdSQL = new SQLStmt( """ - SELECT D_NEXT_O_ID + SELECT D_NEXT_O_ID FROM %s - WHERE D_W_ID = ? + WHERE D_W_ID = ? AND D_ID = ? """.formatted(TPCCConstants.TABLENAME_DISTRICT)); public SQLStmt stockGetCountStockSQL = new SQLStmt( """ - SELECT COUNT(DISTINCT (S_I_ID)) AS STOCK_COUNT + SELECT COUNT(DISTINCT (S_I_ID)) AS STOCK_COUNT FROM %s, %s WHERE OL_W_ID = ? AND OL_D_ID = ? From 3b3906c1065777daebd0f2ff61908dcb6b7490d4 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 16:49:10 +0000 Subject: [PATCH 03/41] compiler fixups --- .../benchmarks/auctionmark/AuctionMarkProfile.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index fb3a38f00..d985f9273 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -108,6 +108,8 @@ public class AuctionMarkProfile { */ protected transient Histogram items_per_category = new Histogram<>(); + class ItemInfoList extends LinkedList {} + /** * Three status types for an item: * (1) Available - The auction of this item is still open @@ -117,13 +119,13 @@ public class AuctionMarkProfile { * (3) Complete (The auction is closed and (There is no bid winner or * the bid winner has already purchased the item) */ - private transient final LinkedList items_available = new LinkedList<>(); - private transient final LinkedList items_endingSoon = new LinkedList<>(); - private transient final LinkedList items_waitingForPurchase = new LinkedList<>(); - private transient final LinkedList items_completed = new LinkedList<>(); + private transient final ItemInfoList items_available = new ItemInfoList(); + private transient final ItemInfoList items_endingSoon = new ItemInfoList(); + private transient final ItemInfoList items_waitingForPurchase = new ItemInfoList(); + private transient final ItemInfoList items_completed = new ItemInfoList(); + - @SuppressWarnings("unchecked") - protected transient final LinkedList[] allItemSets = new LinkedList[]{ + protected transient final ItemInfoList allItemSets[] = new ItemInfoList[]{ this.items_available, this.items_endingSoon, this.items_waitingForPurchase, From 092e06d94572e9cf5297307b2575437b5e194a83 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 16:49:25 +0000 Subject: [PATCH 04/41] compiler fixups --- src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java | 1 + src/main/java/com/oltpbenchmark/catalog/Index.java | 2 ++ src/main/java/com/oltpbenchmark/util/RandomGenerator.java | 1 + 3 files changed, 4 insertions(+) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java index acdd52686..fde832b1e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java @@ -21,6 +21,7 @@ import java.io.Serializable; public class Stock implements Serializable { + static final long serialVersionUID = 0; public int s_i_id; // PRIMARY KEY 2 public int s_w_id; // PRIMARY KEY 1 diff --git a/src/main/java/com/oltpbenchmark/catalog/Index.java b/src/main/java/com/oltpbenchmark/catalog/Index.java index e0b2bc5c0..5fb00d3fd 100644 --- a/src/main/java/com/oltpbenchmark/catalog/Index.java +++ b/src/main/java/com/oltpbenchmark/catalog/Index.java @@ -33,6 +33,8 @@ public class Index extends AbstractCatalogObject { private final boolean unique; static class IndexColumn implements Serializable { + static final long serialVersionUID = 0; + private final String name; private final SortDirectionType dir; diff --git a/src/main/java/com/oltpbenchmark/util/RandomGenerator.java b/src/main/java/com/oltpbenchmark/util/RandomGenerator.java index e25e526b0..3e1fa627f 100644 --- a/src/main/java/com/oltpbenchmark/util/RandomGenerator.java +++ b/src/main/java/com/oltpbenchmark/util/RandomGenerator.java @@ -21,6 +21,7 @@ import java.util.Random; public class RandomGenerator extends Random { + static final long serialVersionUID = 0; /** * Constructor From 803863602da25a3fc92d53d7c48dc615da32875c Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:21:55 +0000 Subject: [PATCH 05/41] add some warning suppressions for unused variables --- .../benchmarks/auctionmark/AuctionMarkBenchmark.java | 5 +---- .../benchmarks/auctionmark/AuctionMarkLoader.java | 1 + .../benchmarks/auctionmark/AuctionMarkWorker.java | 6 ++++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java index 1fbeebf1c..c2aade760 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java @@ -34,10 +34,9 @@ import java.util.List; public class AuctionMarkBenchmark extends BenchmarkModule { - + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkBenchmark.class); - private final RandomGenerator rng = new RandomGenerator((int) System.currentTimeMillis()); public AuctionMarkBenchmark(WorkloadConfiguration workConf) { @@ -70,6 +69,4 @@ protected List> makeWorkersImpl() { protected Loader makeLoaderImpl() { return new AuctionMarkLoader(this); } - - } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java index dae155a5e..6572c1a7c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java @@ -1195,6 +1195,7 @@ protected class ItemBidGenerator extends SubTableGenerator { private LoaderItemInfo.Bid bid = null; private float currentBidPriceAdvanceStep; private long currentCreateDateAdvanceStep; + @SuppressWarnings("unused") // spurious private float currentPrice; private boolean new_item; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 6aa9d6181..604852be5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -404,8 +404,10 @@ protected TransactionStatus executeWork(Connection conn, TransactionType txnType public ItemId processItemRecord(Object[] row) { int col = 0; ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id - String i_u_id = SQLUtil.getString(row[col++]); // i_u_id - String i_name = (String) row[col++]; // i_name + @SuppressWarnings("unused") + String i_u_id = SQLUtil.getString(row[col++]); // i_u_id + @SuppressWarnings("unused") + String i_name = (String) row[col++]; // i_name double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date From 139c95343b3ae8c2729afc6edb7d991e4ee30197 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:22:35 +0000 Subject: [PATCH 06/41] omit those entirely --- .../oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 604852be5..8f14f6044 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -404,10 +404,12 @@ protected TransactionStatus executeWork(Connection conn, TransactionType txnType public ItemId processItemRecord(Object[] row) { int col = 0; ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id + /* @SuppressWarnings("unused") String i_u_id = SQLUtil.getString(row[col++]); // i_u_id @SuppressWarnings("unused") String i_name = (String) row[col++]; // i_name + */ double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date From 259cca6a8467c5deec00ef8542b675fdda5a2f51 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:22:53 +0000 Subject: [PATCH 07/41] fixups --- .../benchmarks/auctionmark/AuctionMarkProfile.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index d985f9273..0190c5305 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -76,6 +76,7 @@ public class AuctionMarkProfile { // ---------------------------------------------------------------- // SERIALIZABLE DATA MEMBERS // ---------------------------------------------------------------- + static final long serialVersionUID = 0; /** * Database Scale Factor @@ -108,7 +109,9 @@ public class AuctionMarkProfile { */ protected transient Histogram items_per_category = new Histogram<>(); - class ItemInfoList extends LinkedList {} + class ItemInfoList extends LinkedList { + static final long serialVersionUID = 0; + } /** * Three status types for an item: From 77c74ae19ee175a7e1dc177f3e7ee89a2abfcd46 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:23:04 +0000 Subject: [PATCH 08/41] whitespace --- .../benchmarks/auctionmark/AuctionMarkProfile.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index 0190c5305..6d2f78f99 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -291,7 +291,7 @@ private AuctionMarkProfile copyProfile(AuctionMarkWorker worker, AuctionMarkProf this.items_per_category = other.items_per_category; this.gag_ids = other.gag_ids; - // Initialize the UserIdGenerator so we can figure out whether our + // Initialize the UserIdGenerator so we can figure out whether our // client should even have these ids this.initializeUserIdGenerator(this.client_id); @@ -866,7 +866,7 @@ private ItemInfo getRandomItem(LinkedList itemSet, boolean needCurrent continue; } - // If they want an item that is ending in the future, then we compare it with + // If they want an item that is ending in the future, then we compare it with // the current timestamp if (needFutureEndDate) { boolean compareTo = (temp.getEndDate().compareTo(currentTime) < 0); From 7abe2e892b126288f0f23422b7a0a6ae3989277e Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:23:13 +0000 Subject: [PATCH 09/41] use autoclose --- .../oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java index 466391c7a..886dd0668 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java @@ -39,7 +39,7 @@ public void run(Connection conn, long s_id, byte ai_type) throws SQLException { stmt.setLong(1, s_id); stmt.setByte(2, ai_type); try (ResultSet results = stmt.executeQuery()) { - + assert results != null; } } } From a3f7fec53eed4009ef3ea95cc8456191d921950b Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 17:24:57 +0000 Subject: [PATCH 10/41] remove more suppressed cast issues --- .../wikipedia/WikipediaBenchmark.java | 19 +++++++++---------- .../util/RandomDistribution.java | 7 +++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java index 18ea0e70c..445c13cc7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java @@ -23,7 +23,7 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.wikipedia.data.RevisionHistograms; import com.oltpbenchmark.benchmarks.wikipedia.procedures.AddWatchList; -import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; +import com.oltpbenchmark.util.RandomDistribution.IntegerFlatHistogram; import com.oltpbenchmark.util.TextGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,22 +34,21 @@ public class WikipediaBenchmark extends BenchmarkModule { private static final Logger LOG = LoggerFactory.getLogger(WikipediaBenchmark.class); - protected final FlatHistogram commentLength; - protected final FlatHistogram minorEdit; - private final FlatHistogram[] revisionDeltas; + protected final IntegerFlatHistogram commentLength; + protected final IntegerFlatHistogram minorEdit; + private final IntegerFlatHistogram[] revisionDeltas; protected final int num_users; protected final int num_pages; - @SuppressWarnings("unchecked") public WikipediaBenchmark(WorkloadConfiguration workConf) { super(workConf); - this.commentLength = new FlatHistogram<>(this.rng(), RevisionHistograms.COMMENT_LENGTH); - this.minorEdit = new FlatHistogram<>(this.rng(), RevisionHistograms.MINOR_EDIT); - this.revisionDeltas = new FlatHistogram[RevisionHistograms.REVISION_DELTA_SIZES.length]; + this.commentLength = new IntegerFlatHistogram(this.rng(), RevisionHistograms.COMMENT_LENGTH); + this.minorEdit = new IntegerFlatHistogram(this.rng(), RevisionHistograms.MINOR_EDIT); + this.revisionDeltas = new IntegerFlatHistogram[RevisionHistograms.REVISION_DELTA_SIZES.length]; for (int i = 0; i < this.revisionDeltas.length; i++) { - this.revisionDeltas[i] = new FlatHistogram<>(this.rng(), RevisionHistograms.REVISION_DELTAS[i]); + this.revisionDeltas[i] = new IntegerFlatHistogram(this.rng(), RevisionHistograms.REVISION_DELTAS[i]); } this.num_users = (int) Math.ceil(WikipediaConstants.USERS * this.getWorkloadConfiguration().getScaleFactor()); @@ -72,7 +71,7 @@ protected char[] generateRevisionText(char[] orig_text) { // Where is your god now? // There is probably some sort of minimal size that we should adhere to, // but it's 12:30am and I simply don't feel like dealing with that now - FlatHistogram h = null; + IntegerFlatHistogram h = null; for (int i = 0; i < this.revisionDeltas.length - 1; i++) { if (orig_text.length <= RevisionHistograms.REVISION_DELTA_SIZES[i]) { h = this.revisionDeltas[i]; diff --git a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java index b77000294..c102dfea5 100644 --- a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java +++ b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java @@ -240,6 +240,13 @@ protected long nextLongImpl() { } } + public static class IntegerFlatHistogram extends FlatHistogram { + private static final long serialVersionUID = 1L; + public IntegerFlatHistogram(Random random, Histogram histogram) { + super(random, histogram); + } + } + /** * Gaussian Distribution */ From 554406df6984891f99eef06d03378f8f5b211e84 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:20:47 +0000 Subject: [PATCH 11/41] unnecessary cast --- .../oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java index 86e9cc42b..cad30ccc4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java @@ -45,7 +45,7 @@ public OTMetricsBenchmark(WorkloadConfiguration workConf) { // Compute the number of records per table. this.num_sources = (int) Math.round(OTMetricsConstants.NUM_SOURCES * workConf.getScaleFactor()); this.num_sessions = (int) Math.round(OTMetricsConstants.NUM_SESSIONS * workConf.getScaleFactor()); - this.num_observations = (long) Math.round(OTMetricsConstants.NUM_OBSERVATIONS * workConf.getScaleFactor()); + this.num_observations = Math.round(OTMetricsConstants.NUM_OBSERVATIONS * workConf.getScaleFactor()); } @Override From 79e71875295e06143872661678306db6fe1d7c6f Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:21:23 +0000 Subject: [PATCH 12/41] avoid unused errors --- .../benchmarks/resourcestresser/procedures/CPU1.java | 1 + .../benchmarks/resourcestresser/procedures/CPU2.java | 1 + .../benchmarks/tatp/procedures/GetNewDestination.java | 2 +- .../benchmarks/tatp/procedures/GetSubscriberData.java | 2 +- .../benchmarks/tatp/procedures/InsertCallForwarding.java | 2 +- .../benchmarks/twitter/procedures/GetFollowers.java | 1 + .../oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java | 1 + .../benchmarks/twitter/procedures/GetTweetsFromFollowing.java | 1 + .../benchmarks/twitter/procedures/GetUserTweets.java | 1 + 9 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java index 95fe70c49..2df497786 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java @@ -53,6 +53,7 @@ public void run(Connection conn, int howManyPerTransaction, int sleepLength, int // TODO: Is this the right place to sleep? With rs open??? try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; try { Thread.sleep(sleepLength); } catch (InterruptedException e) { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java index b6d515f12..194bb6279 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java @@ -52,6 +52,7 @@ public void run(Connection conn, int howManyPerTransaction, int sleepLength, int // TODO: Is this the right place to sleep? With rs open??? try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; try { Thread.sleep(sleepLength); } catch (InterruptedException e) { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java index d0ea2dc94..ee9a833b5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java @@ -49,7 +49,7 @@ public void run(Connection conn, long s_id, byte sf_type, byte start_time, byte stmt.setByte(3, start_time); stmt.setByte(4, end_time); try (ResultSet results = stmt.executeQuery()) { - + assert results != null; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java index 77fd0ec7c..a0c95144b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java @@ -35,7 +35,7 @@ public void run(Connection conn, long s_id) throws SQLException { try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { stmt.setLong(1, s_id); try (ResultSet results = stmt.executeQuery()) { - + assert results != null; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java index 0f21e0ef9..7239186a5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java @@ -56,7 +56,7 @@ public long run(Connection conn, String sub_nbr, byte sf_type, byte start_time, try (PreparedStatement stmt = this.getPreparedStatement(conn, getSpecialFacility)) { stmt.setLong(1, s_id); try (ResultSet results = stmt.executeQuery()) { - + assert results != null; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java index 12eb175f9..e78b5b3e2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java @@ -52,6 +52,7 @@ public void run(Connection conn, long uid) throws SQLException { getFollowerNamesstmt.setLong(ctr, last); } try (ResultSet getFollowerNamesrs = getFollowerNamesstmt.executeQuery()) { + assert getFollowerNamesrs != null; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java index 8c94295d8..ae72db178 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java @@ -36,6 +36,7 @@ public void run(Connection conn, long tweet_id) throws SQLException { try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweet)) { stmt.setLong(1, tweet_id); try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java index d29492dce..c726ab571 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java @@ -54,6 +54,7 @@ public void run(Connection conn, int uid) throws SQLException { stmt.setLong(ctr, last); } try (ResultSet getTweetsResult = stmt.executeQuery()) { + assert getTweetsResult != null; } } else { // LOG.debug("No followers for user: "+uid); // so what .. ? diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java index 6815f4095..cd5e633c2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java @@ -34,6 +34,7 @@ public void run(Connection conn, long uid) throws SQLException { try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweets)) { stmt.setLong(1, uid); try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; } } } From d93caf76bf23d44bb99471a08b7267b16d34cb4d Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:21:43 +0000 Subject: [PATCH 13/41] add serialization requirements --- .../java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java | 1 + .../java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java | 1 + .../java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java | 1 + 3 files changed, 3 insertions(+) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java index 2b95eaeed..f60fce86e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java @@ -21,6 +21,7 @@ import java.io.Serializable; public class District implements Serializable { + static final long serialVersionUID = 0; public int d_id; public int d_w_id; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java index 8f09c0ad9..2614bb881 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java @@ -21,6 +21,7 @@ import java.io.Serializable; public class NewOrder implements Serializable { + private static final long serialVersionUID = 1L; public int no_w_id; public int no_d_id; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java index 2f4b4b5ea..6e5a9d22e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java @@ -21,6 +21,7 @@ import java.io.Serializable; public class Warehouse implements Serializable { + static final long serialVersionUID = 0; public int w_id; // PRIMARY KEY public float w_ytd; From 7f89237decde9c7b9648be3e8bc60d736f39bd6c Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:22:14 +0000 Subject: [PATCH 14/41] whitespace --- .../benchmarks/twitter/procedures/GetFollowers.java | 2 +- src/main/java/com/oltpbenchmark/util/JSONUtil.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java index e78b5b3e2..93fad32ab 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java @@ -58,7 +58,7 @@ public void run(Connection conn, long uid) throws SQLException { } } } - // LOG.warn("No followers for user : "+uid); //... so what ? + // LOG.warn("No followers for user : "+uid); //... so what ? } } diff --git a/src/main/java/com/oltpbenchmark/util/JSONUtil.java b/src/main/java/com/oltpbenchmark/util/JSONUtil.java index 81ea84beb..56c10b019 100644 --- a/src/main/java/com/oltpbenchmark/util/JSONUtil.java +++ b/src/main/java/com/oltpbenchmark/util/JSONUtil.java @@ -362,7 +362,7 @@ protected static void readMapField(final JSONObject json_object, final Map map, @SuppressWarnings("unchecked") protected static void readCollectionField(final JSONArray json_array, final Collection collection, final Stack inner_classes) throws Exception { // We need to figure out what the inner type of the collection is - // If it's a Collection or a Map, then we need to instantiate it before + // If it's a Collection or a Map, then we need to instantiate it before // we can call readFieldValue() again for it. Class inner_class = inner_classes.pop(); Collection> inner_interfaces = ClassUtil.getInterfaces(inner_class); From ff5507de6a424b0ec56eb3133aef4072592e6b3d Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:22:41 +0000 Subject: [PATCH 15/41] more minor avoid raw type issues --- .../benchmarks/wikipedia/data/RevisionHistograms.java | 11 ++++++----- src/main/java/com/oltpbenchmark/util/StringUtil.java | 5 ++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java index 17c28eb18..f7a65f7c7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java @@ -290,12 +290,13 @@ public abstract class RevisionHistograms { */ public static final int[] REVISION_DELTA_SIZES = {1000, 10000, 100000}; + public static class IntHistogram extends Histogram {} + /** * */ - @SuppressWarnings("unchecked") - public static final Histogram[] REVISION_DELTAS = (Histogram[]) new Histogram[]{ - new Histogram() { + public static final IntHistogram[] REVISION_DELTAS = new IntHistogram[]{ + new IntHistogram() { { this.put(-1000, 237); this.put(-900, 237); @@ -499,7 +500,7 @@ public abstract class RevisionHistograms { this.put(100000, 4); } }, - new Histogram() { + new IntHistogram() { { this.put(-10000, 15); this.put(-9900, 19); @@ -776,7 +777,7 @@ public abstract class RevisionHistograms { this.put(100000, 1); } }, - new Histogram() { + new IntHistogram() { { this.put(-985000, 1); this.put(-982000, 1); diff --git a/src/main/java/com/oltpbenchmark/util/StringUtil.java b/src/main/java/com/oltpbenchmark/util/StringUtil.java index 459515f5f..a5361d6e3 100644 --- a/src/main/java/com/oltpbenchmark/util/StringUtil.java +++ b/src/main/java/com/oltpbenchmark/util/StringUtil.java @@ -110,7 +110,10 @@ public static String formatMaps(String delimiter, boolean upper, boolean box, bo // Figure out the largest key size so we can get spacing right int max_key_size = 0; int max_title_size = 0; - final Map[] map_keys = (Map[]) new Map[maps.length]; + class Obj2StrArrMap extends HashMap { + static final long serialVersionUID = 0; + } + final Map[] map_keys = new Obj2StrArrMap[maps.length]; final boolean[] map_titles = new boolean[maps.length]; for (int i = 0; i < maps.length; i++) { Map m = maps[i]; From fc97c1eac1805fac27e4fcbb67c1b633f22f046c Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:23:02 +0000 Subject: [PATCH 16/41] in the couple of utility classes, just suppress more warnings --- src/main/java/com/oltpbenchmark/util/ClassUtil.java | 1 + src/main/java/com/oltpbenchmark/util/JSONUtil.java | 6 +++--- src/main/java/com/oltpbenchmark/util/StringUtil.java | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/util/ClassUtil.java b/src/main/java/com/oltpbenchmark/util/ClassUtil.java index 9963b6a33..80a00933f 100644 --- a/src/main/java/com/oltpbenchmark/util/ClassUtil.java +++ b/src/main/java/com/oltpbenchmark/util/ClassUtil.java @@ -150,6 +150,7 @@ public static Constructor getConstructor(Class target_class, Class. LOG.debug("TARGET PARAMS: {}", Arrays.toString(params)); } + @SuppressWarnings("rawtypes") List>[] paramSuper = (List>[]) new List[params.length]; for (int i = 0; i < params.length; i++) { paramSuper[i] = ClassUtil.getSuperClasses(params[i]); diff --git a/src/main/java/com/oltpbenchmark/util/JSONUtil.java b/src/main/java/com/oltpbenchmark/util/JSONUtil.java index 56c10b019..ae6619c79 100644 --- a/src/main/java/com/oltpbenchmark/util/JSONUtil.java +++ b/src/main/java/com/oltpbenchmark/util/JSONUtil.java @@ -313,7 +313,7 @@ public static void writeFieldValue(JSONStringer stringer, Class field_class, * @param inner_classes * @throws Exception */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) protected static void readMapField(final JSONObject json_object, final Map map, final Stack inner_classes) throws Exception { Class key_class = inner_classes.pop(); Class val_class = inner_classes.pop(); @@ -359,7 +359,7 @@ protected static void readMapField(final JSONObject json_object, final Map map, * @param inner_classes * @throws Exception */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) protected static void readCollectionField(final JSONArray json_array, final Collection collection, final Stack inner_classes) throws Exception { // We need to figure out what the inner type of the collection is // If it's a Collection or a Map, then we need to instantiate it before @@ -404,7 +404,7 @@ protected static void readCollectionField(final JSONArray json_array, final Coll * @param object * @throws Exception */ - @SuppressWarnings("unchecked") + @SuppressWarnings("rawtypes") public static void readFieldValue(final JSONObject json_object, final String json_key, Field field_handle, Object object) throws Exception { Class field_class = field_handle.getType(); diff --git a/src/main/java/com/oltpbenchmark/util/StringUtil.java b/src/main/java/com/oltpbenchmark/util/StringUtil.java index a5361d6e3..380c3c817 100644 --- a/src/main/java/com/oltpbenchmark/util/StringUtil.java +++ b/src/main/java/com/oltpbenchmark/util/StringUtil.java @@ -102,7 +102,6 @@ public static String formatMaps(Map... maps) { * @param maps * @return */ - @SuppressWarnings("unchecked") public static String formatMaps(String delimiter, boolean upper, boolean box, boolean border_top, boolean border_bottom, boolean recursive, boolean first_element_title, Map... maps) { boolean need_divider = (maps.length > 1 || border_bottom || border_top); From 5220c3f857c9d01289bdf39de332f3b86a0cb239 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:23:17 +0000 Subject: [PATCH 17/41] convert throw type to avoid InterruptedException handling warnings --- src/main/java/com/oltpbenchmark/util/TableDataIterable.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/util/TableDataIterable.java b/src/main/java/com/oltpbenchmark/util/TableDataIterable.java index d1cb8c4ef..80019099d 100644 --- a/src/main/java/com/oltpbenchmark/util/TableDataIterable.java +++ b/src/main/java/com/oltpbenchmark/util/TableDataIterable.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.io.InputStreamReader; +import java.io.IOException; import java.util.Iterator; /** @@ -80,7 +81,7 @@ public Iterator iterator() { } @Override - public void close() throws Exception { + public void close() throws IOException { if (this.in != null) { in.close(); } From df432f36406dd918016420426296d3eb0af6af4d Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:32:53 +0000 Subject: [PATCH 18/41] docs --- .../benchmarks/auctionmark/AuctionMarkProfile.java | 4 ++++ .../wikipedia/data/RevisionHistograms.java | 3 +++ .../com/oltpbenchmark/util/RandomDistribution.java | 4 ++++ src/main/java/com/oltpbenchmark/util/StringUtil.java | 12 +++++++++--- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index 6d2f78f99..bd2d9b08d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -109,7 +109,11 @@ public class AuctionMarkProfile { */ protected transient Histogram items_per_category = new Histogram<>(); + /** + * Simple generic class overload to avoid some cast warnings below. + */ class ItemInfoList extends LinkedList { + // Required serialization field. static final long serialVersionUID = 0; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java index f7a65f7c7..6abd4f6fb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java @@ -290,6 +290,9 @@ public abstract class RevisionHistograms { */ public static final int[] REVISION_DELTA_SIZES = {1000, 10000, 100000}; + /** + * Simple generic class overload to avoid some cast warnings below. + */ public static class IntHistogram extends Histogram {} /** diff --git a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java index c102dfea5..c6f0b8918 100644 --- a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java +++ b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java @@ -240,7 +240,11 @@ protected long nextLongImpl() { } } + /** + * Simple generic class overload to avoid some cast warnings below. + */ public static class IntegerFlatHistogram extends FlatHistogram { + // Required serialization field. private static final long serialVersionUID = 1L; public IntegerFlatHistogram(Random random, Histogram histogram) { super(random, histogram); diff --git a/src/main/java/com/oltpbenchmark/util/StringUtil.java b/src/main/java/com/oltpbenchmark/util/StringUtil.java index 380c3c817..0babfdf21 100644 --- a/src/main/java/com/oltpbenchmark/util/StringUtil.java +++ b/src/main/java/com/oltpbenchmark/util/StringUtil.java @@ -80,6 +80,14 @@ public static String formatMaps(Map... maps) { return (formatMaps(":", false, false, false, false, true, true, maps)); } + /** + * Simple generic class overload to avoid some cast warnings below. + */ + public static class Obj2StrArrMap extends HashMap { + // Required serialization field. + static final long serialVersionUID = 0; + } + /** * Return key/value maps into a nicely formatted table * The maps are displayed in order from first to last, and there will be a @@ -109,9 +117,7 @@ public static String formatMaps(String delimiter, boolean upper, boolean box, bo // Figure out the largest key size so we can get spacing right int max_key_size = 0; int max_title_size = 0; - class Obj2StrArrMap extends HashMap { - static final long serialVersionUID = 0; - } + final Map[] map_keys = new Obj2StrArrMap[maps.length]; final boolean[] map_titles = new boolean[maps.length]; for (int i = 0; i < maps.length; i++) { From d93c61d7253611c691ec89ac11c83dc254106df2 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 18:48:44 +0000 Subject: [PATCH 19/41] enable deprecations --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 1cdcb2dd6..edb6b30e7 100644 --- a/pom.xml +++ b/pom.xml @@ -336,6 +336,7 @@ ${maven.compiler.source} ${maven.compiler.target} + true true From 9b95f48fdce5085088fbf41bf045c6ffe06b95c5 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 19:16:35 +0000 Subject: [PATCH 20/41] enable auto formatting on compile --- pom.xml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index edb6b30e7..6ab40dca7 100644 --- a/pom.xml +++ b/pom.xml @@ -323,12 +323,25 @@ janino 3.1.11 - ${buildDirectory} + + + com.spotify.fmt + fmt-maven-plugin + 2.21.1 + + + + check + format + + + + org.apache.maven.plugins maven-compiler-plugin From e8949500c6b6ecfce938809b599fd20b4a1e448d Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 19:18:16 +0000 Subject: [PATCH 21/41] check formatting at ci time --- .github/workflows/maven.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 589eb0ff6..77da40e71 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -50,6 +50,12 @@ jobs: cache: 'maven' distribution: 'temurin' + - name: Check formatting + run: mvn -B fmt:check --file pom.xml + + - name: Compile with Maven + run: mvn -B compile --file pom.xml + - name: Test with Maven run: mvn -B test --file pom.xml From 062f7a133a7fa11e041a9d983f68139566584908 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 19:22:33 +0000 Subject: [PATCH 22/41] enable vscode configs for formatting --- .vscode/extensions.json | 11 +++++++++++ .vscode/settings.json | 7 +++++++ 2 files changed, 18 insertions(+) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..81b3f02f4 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "editorconfig.editorconfig", + "redhat.java", + "vscjava.vscode-java-debug", + "vscjava.vscode-java-dependency", + "vscjava.vscode-java-pack", + "vscjava.vscode-java-test", + "vscjava.vscode-maven" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..ae71a3203 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.watcherExclude": { + "**/target": true + }, + "java.format.settings.profile": "GoogleStyle", + "java.format.enabled": true +} \ No newline at end of file From 500240d6179b1c1b5a596bbfb59cc49c246e4539 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 19:42:42 +0000 Subject: [PATCH 23/41] do format checks in docker build step too --- .github/workflows/maven.yml | 1 + docker/benchbase/common-env.sh | 2 ++ docker/benchbase/devcontainer/build-in-container.sh | 7 +++++++ 3 files changed, 10 insertions(+) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 77da40e71..9c60d5550 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -611,6 +611,7 @@ jobs: - name: Build the benchbase docker image with all profiles using the dev image env: SKIP_TESTS: 'false' + DO_FORMAT_CHECKS: 'true' run: | ./docker/benchbase/build-full-image.sh - name: Run a basic test from the docker image against postgres test DB diff --git a/docker/benchbase/common-env.sh b/docker/benchbase/common-env.sh index 08f4e7339..780f7c5b6 100644 --- a/docker/benchbase/common-env.sh +++ b/docker/benchbase/common-env.sh @@ -7,6 +7,8 @@ export BENCHBASE_PROFILE="${BENCHBASE_PROFILE:-postgres}" export CLEAN_BUILD="${CLEAN_BUILD:-true}" # true, pre, post, false # Whether to run the test target during build. export SKIP_TESTS="${SKIP_TESTS:-false}" +# Whether to do format checks during build (mostly for CI). +export DO_FORMAT_CHECKS="${DO_FORMAT_CHECKS:-false}" # Setting this allows us to easily tag and publish the image name in our CI pipelines or locally. CONTAINER_REGISTRY_NAME="${CONTAINER_REGISTRY_NAME:-}" diff --git a/docker/benchbase/devcontainer/build-in-container.sh b/docker/benchbase/devcontainer/build-in-container.sh index ed27f758d..610940fcd 100755 --- a/docker/benchbase/devcontainer/build-in-container.sh +++ b/docker/benchbase/devcontainer/build-in-container.sh @@ -10,6 +10,7 @@ set -eu -o pipefail BENCHBASE_PROFILES="${BENCHBASE_PROFILES:-cockroachdb mariadb mysql postgres spanner phoenix sqlserver sqlite}" CLEAN_BUILD="${CLEAN_BUILD:-true}" # true, false, pre, post SKIP_TESTS="${SKIP_TESTS:-false}" +DO_FORMAT_CHECKS="${DO_FORMAT_CHECKS:-false}" cd /benchbase mkdir -p results @@ -101,6 +102,12 @@ for profile in ${BENCHBASE_PROFILES}; do mvn -T2C -B --file pom.xml -D buildDirectory=target/$profile $EXTRA_MAVEN_ARGS process-resources dependency:copy-dependencies done +# Pre format checks are mostly for CI. +# Else, things are reformatted during compile. +if [ "${DO_FORMAT_CHECKS:-}" == 'true' ]; then + mvn -B --file pom.xml fmt:check +fi + # Make sure that we've built the base stuff (and test) before we build individual profiles. mvn -T 2C -B --file pom.xml $SKIP_TEST_ARGS $EXTRA_MAVEN_ARGS compile # ${TEST_TARGET:-} if [ -n "${TEST_TARGET:-}" ]; then From b0398b136c1de5656031a33ad31909902f8d4073 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:17:35 +0000 Subject: [PATCH 24/41] more compiler warning fixups --- src/test/java/com/oltpbenchmark/api/AbstractTestCase.java | 1 + .../benchmarks/auctionmark/TestAuctionMarkWorker.java | 5 ++--- .../benchmarks/auctionmark/util/TestUserId.java | 2 +- src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java b/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java index 479f9a9ca..2356215da 100644 --- a/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java +++ b/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java @@ -175,6 +175,7 @@ private int findAvailablePort() throws IOException { } try (ServerSocket testSocket = new ServerSocket(port)) { + assert testSocket != null; return port; } catch (BindException e) { // This port is already in use. Continue to next port. diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java index 8458dd356..ca902418a 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java @@ -23,7 +23,6 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; -import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.auctionmark.util.UserId; import java.io.IOException; @@ -61,9 +60,9 @@ public void testUniqueSellers() throws Exception { Set all_users = new HashSet(); Set worker_users = new TreeSet(); Integer last_num_users = null; - for (Worker w : this.workers) { - AuctionMarkWorker worker = (AuctionMarkWorker) w; + for (var w : this.workers) { assertNotNull(w); + AuctionMarkWorker worker = (AuctionMarkWorker) w; // Get the uninitialized profile AuctionMarkProfile profile = worker.getProfile(); diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java index 14961dc94..8fb16662c 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java @@ -17,7 +17,7 @@ package com.oltpbenchmark.benchmarks.auctionmark.util; -import static junit.framework.Assert.assertFalse; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java index 924d15d2d..c2ebecbec 100644 --- a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java +++ b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java @@ -122,6 +122,7 @@ public void testPop() { expected[i] = rng.astring(1, 32); } // FOR + @SuppressWarnings("rawtypes") Collection[] collections = new Collection[]{ CollectionUtil.addAll(new ListOrderedSet(), expected), CollectionUtil.addAll(new HashSet(), expected), From 9fed075599e1416186e8e8c8d8557e6c4a06f788 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:31:57 +0000 Subject: [PATCH 25/41] fixup --- docker/benchbase/devcontainer/build-in-container.sh | 12 ++++++------ docker/benchbase/run-dev-image.sh | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docker/benchbase/devcontainer/build-in-container.sh b/docker/benchbase/devcontainer/build-in-container.sh index 610940fcd..c95564e9b 100755 --- a/docker/benchbase/devcontainer/build-in-container.sh +++ b/docker/benchbase/devcontainer/build-in-container.sh @@ -96,18 +96,18 @@ else echo "WARNING: Unhandled SKIP_TESTS mode: '$SKIP_TESTS'" >&2 fi -# Fetch resources serially to work around mvn races with downloading the same -# file in multiple processes (mvn uses *.part instead of use tmpfile naming). -for profile in ${BENCHBASE_PROFILES}; do - mvn -T2C -B --file pom.xml -D buildDirectory=target/$profile $EXTRA_MAVEN_ARGS process-resources dependency:copy-dependencies -done - # Pre format checks are mostly for CI. # Else, things are reformatted during compile. if [ "${DO_FORMAT_CHECKS:-}" == 'true' ]; then mvn -B --file pom.xml fmt:check fi +# Fetch resources serially to work around mvn races with downloading the same +# file in multiple processes (mvn uses *.part instead of use tmpfile naming). +for profile in ${BENCHBASE_PROFILES}; do + mvn -T2C -B --file pom.xml -D buildDirectory=target/$profile $EXTRA_MAVEN_ARGS process-resources dependency:copy-dependencies +done + # Make sure that we've built the base stuff (and test) before we build individual profiles. mvn -T 2C -B --file pom.xml $SKIP_TEST_ARGS $EXTRA_MAVEN_ARGS compile # ${TEST_TARGET:-} if [ -n "${TEST_TARGET:-}" ]; then diff --git a/docker/benchbase/run-dev-image.sh b/docker/benchbase/run-dev-image.sh index 37de4d1ff..ce1eb4bb4 100755 --- a/docker/benchbase/run-dev-image.sh +++ b/docker/benchbase/run-dev-image.sh @@ -36,6 +36,7 @@ docker run ${INTERACTIVE_ARGS:-} --rm \ --env BENCHBASE_PROFILES="$BENCHBASE_PROFILES" \ --env CLEAN_BUILD="$CLEAN_BUILD" \ --env SKIP_TESTS="$SKIP_TESTS" \ + --env DO_FORMAT_CHECKS="$DO_FORMAT_CHECKS" \ --env EXTRA_MAVEN_ARGS="${EXTRA_MAVEN_ARGS:-}" \ --user "$CONTAINERUSER_UID:$CONTAINERUSER_GID" \ -v "$MAVEN_CONFIG:/home/containeruser/.m2" \ From c53ea80abc64caf739dbfe7e95a2949530b30235 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:40:38 +0000 Subject: [PATCH 26/41] revert order --- .../benchmarks/auctionmark/TestAuctionMarkWorker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java index ca902418a..1973d03ac 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java @@ -61,8 +61,8 @@ public void testUniqueSellers() throws Exception { Set worker_users = new TreeSet(); Integer last_num_users = null; for (var w : this.workers) { - assertNotNull(w); AuctionMarkWorker worker = (AuctionMarkWorker) w; + assertNotNull(w); // Get the uninitialized profile AuctionMarkProfile profile = worker.getProfile(); From e5e9c0013a8c67d03c4c82f91950fd429b98a636 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:42:05 +0000 Subject: [PATCH 27/41] need the col++ --- .../oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 8f14f6044..604852be5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -404,12 +404,10 @@ protected TransactionStatus executeWork(Connection conn, TransactionType txnType public ItemId processItemRecord(Object[] row) { int col = 0; ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id - /* @SuppressWarnings("unused") String i_u_id = SQLUtil.getString(row[col++]); // i_u_id @SuppressWarnings("unused") String i_name = (String) row[col++]; // i_name - */ double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date From 94385e7107385878f8a5ff703b0d7cf6521056ed Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:53:49 +0000 Subject: [PATCH 28/41] address some unused and other lint issues --- .../com/oltpbenchmark/api/StatementDialects.java | 2 -- .../auctionmark/AuctionMarkProfile.java | 2 +- .../benchmarks/auctionmark/AuctionMarkWorker.java | 15 +++++++++------ .../auctionmark/util/AuctionMarkUtil.java | 1 + .../auctionmark/util/CategoryParser.java | 2 +- .../benchmarks/chbenchmark/CHBenCHmarkLoader.java | 10 ---------- .../benchmarks/epinions/EpinionsWorker.java | 4 +--- .../benchmarks/hyadapt/HYADAPTLoader.java | 1 + .../benchmarks/otmetrics/OTMetricsBenchmark.java | 2 +- .../resourcestresser/ResourceStresserLoader.java | 1 + 10 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/api/StatementDialects.java b/src/main/java/com/oltpbenchmark/api/StatementDialects.java index 5e5826ea0..cb63eb2aa 100644 --- a/src/main/java/com/oltpbenchmark/api/StatementDialects.java +++ b/src/main/java/com/oltpbenchmark/api/StatementDialects.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.WorkloadConfiguration; import com.oltpbenchmark.api.dialects.*; import com.oltpbenchmark.types.DatabaseType; -import com.oltpbenchmark.types.State; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; @@ -30,7 +29,6 @@ import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index bd2d9b08d..3b2777cf6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -464,7 +464,6 @@ private static void loadItems(AuctionMarkProfile profile, List vt) { private static void loadPendingItemComments(AuctionMarkProfile profile, List vt) { for (Object[] row : vt) { - int col = 1; long ic_id = SQLUtil.getLong(row[0]); String ic_i_id = SQLUtil.getString(row[1]); String ic_u_id = SQLUtil.getString(row[2]); @@ -721,6 +720,7 @@ private boolean addItem(LinkedList items, ItemInfo itemInfo) { // HACK: Always swap existing ItemInfos with our new one, since it will // more up-to-date information ItemInfo existing = items.set(idx, itemInfo); + assert existing != null; return (true); } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 604852be5..5c40d121e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -404,10 +404,10 @@ protected TransactionStatus executeWork(Connection conn, TransactionType txnType public ItemId processItemRecord(Object[] row) { int col = 0; ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id - @SuppressWarnings("unused") String i_u_id = SQLUtil.getString(row[col++]); // i_u_id - @SuppressWarnings("unused") + assert i_u_id != null; String i_name = (String) row[col++]; // i_name + assert i_name != null; double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date @@ -454,7 +454,7 @@ protected boolean executeCloseAuctions(Connection conn, CloseAuctions proc) thro for (Object[] row : results) { ItemId itemId = this.processItemRecord(row); - + assert itemId != null; } profile.updateItemQueues(); @@ -478,7 +478,7 @@ protected boolean executeGetItem(Connection conn, GetItem proc) throws SQLExcept // The first row will have our item data that we want // We don't care about the user information... ItemId itemId = this.processItemRecord(results[0]); - + assert itemId != null; return (true); } @@ -536,14 +536,17 @@ protected boolean executeGetUserInfo(Connection conn, GetUserInfo proc) throws S for (Object[] row : results.getSellerItems()) { ItemId itemId = this.processItemRecord(row); + assert itemId != null; } for (Object[] row : results.getBuyerItems()) { ItemId itemId = this.processItemRecord(row); + assert itemId != null; } for (Object[] row : results.getWatchedItems()) { ItemId itemId = this.processItemRecord(row); + assert itemId != null; } @@ -616,7 +619,7 @@ protected boolean executeNewBid(Connection conn, NewBid proc) throws SQLExceptio itemInfo.getEndDate()); ItemId itemId = this.processItemRecord(results); - + assert itemId != null; return (true); } @@ -799,7 +802,7 @@ protected boolean executeNewPurchase(Connection conn, NewPurchase proc) throws S buyer_credit); ItemId itemId = this.processItemRecord(results); - + assert itemId != null; return (true); } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java index e6625dfc4..5821e2b35 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java @@ -25,6 +25,7 @@ import java.sql.Timestamp; public abstract class AuctionMarkUtil { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkUtil.class); private static final long ITEM_ID_MASK = 0xFFFFFFFFFFFFFFL; // 56 bits (ITEM_ID) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java index d98e7d348..a1de14819 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java @@ -22,7 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; @@ -31,6 +30,7 @@ public class CategoryParser { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(CategoryParser.class); Map _categoryMap; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java index 5eaf2c300..4f891aa38 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java @@ -26,8 +26,6 @@ import com.oltpbenchmark.util.RandomGenerator; import org.apache.commons.io.IOUtils; -import java.io.BufferedReader; -import java.io.File; import java.io.InputStream; import java.nio.charset.Charset; import java.sql.Connection; @@ -143,11 +141,7 @@ private void truncateTable(Connection conn, String strTable) { } private int loadRegions(Connection conn, PreparedStatement statement) throws SQLException { - int k = 0; - int t = 0; - BufferedReader br = null; - truncateTable(conn, "region"); truncateTable(conn, "nation"); @@ -208,9 +202,7 @@ private int loadRegions(Connection conn, PreparedStatement statement) throws SQL } private int loadNations(Connection conn, PreparedStatement statement) { - int k = 0; - int t = 0; Nation nation = new Nation(); @@ -274,9 +266,7 @@ private int loadNations(Connection conn, PreparedStatement statement) { } private int loadSuppliers(Connection conn, PreparedStatement statement) { - int k = 0; - int t = 0; try { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java index dade16956..100d72fc4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java @@ -30,15 +30,13 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Random; public class EpinionsWorker extends Worker { - + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(EpinionsWorker.class); private final ArrayList user_ids; private final ArrayList item_ids; - private final Random rand = new Random(System.currentTimeMillis()); public EpinionsWorker(EpinionsBenchmark benchmarkModule, int id, ArrayList user_ids, ArrayList item_ids) { super(benchmarkModule, id); diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java index 3afd19fb2..0021d38f1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java @@ -82,6 +82,7 @@ public void load(Connection conn) throws SQLException { total++; if (++batch >= workConf.getBatchSize()) { int[] result = stmt.executeBatch(); + assert result != null; batch = 0; LOG.info(String.format("Records Loaded %d / %d", total, num_record)); diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java index cad30ccc4..c1894bd3c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java @@ -32,7 +32,7 @@ * @author pavlo */ public class OTMetricsBenchmark extends BenchmarkModule { - + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(OTMetricsBenchmark.class); protected final int num_sources; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java index cbd0c96ff..be8933129 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java @@ -97,6 +97,7 @@ private void loadTable(Connection conn, String tableName) throws SQLException { stmt.addBatch(); if (++batch >= workConf.getBatchSize()) { int[] result = stmt.executeBatch(); + assert result != null; batch = 0; if (LOG.isDebugEnabled()) { From 448ca2413a4d5adb5df5336baf7a7eddeffdecdb Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 20:58:54 +0000 Subject: [PATCH 29/41] fixup --- .../oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 5c40d121e..70b51c117 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -406,8 +406,8 @@ public ItemId processItemRecord(Object[] row) { ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id String i_u_id = SQLUtil.getString(row[col++]); // i_u_id assert i_u_id != null; + @SuppressWarnings("unused") String i_name = (String) row[col++]; // i_name - assert i_name != null; double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date From 1e411d4978271d731d5893dd2deb222cd272b629 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Fri, 8 Dec 2023 21:15:43 +0000 Subject: [PATCH 30/41] fixup --- src/main/java/com/oltpbenchmark/util/StringUtil.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/util/StringUtil.java b/src/main/java/com/oltpbenchmark/util/StringUtil.java index 0babfdf21..263d08384 100644 --- a/src/main/java/com/oltpbenchmark/util/StringUtil.java +++ b/src/main/java/com/oltpbenchmark/util/StringUtil.java @@ -80,14 +80,6 @@ public static String formatMaps(Map... maps) { return (formatMaps(":", false, false, false, false, true, true, maps)); } - /** - * Simple generic class overload to avoid some cast warnings below. - */ - public static class Obj2StrArrMap extends HashMap { - // Required serialization field. - static final long serialVersionUID = 0; - } - /** * Return key/value maps into a nicely formatted table * The maps are displayed in order from first to last, and there will be a @@ -117,8 +109,8 @@ public static String formatMaps(String delimiter, boolean upper, boolean box, bo // Figure out the largest key size so we can get spacing right int max_key_size = 0; int max_title_size = 0; - - final Map[] map_keys = new Obj2StrArrMap[maps.length]; + @SuppressWarnings({"unchecked", "rawtypes"}) + final Map[] map_keys = (Map[]) new Map[maps.length]; final boolean[] map_titles = new boolean[maps.length]; for (int i = 0; i < maps.length; i++) { Map m = maps[i]; From 2937b469f3e21d5bc1e5580b9f5ec969321e0c32 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 16:15:52 +0000 Subject: [PATCH 31/41] add a readme with additional developer notes per PR suggestion --- CONTRIBUTING.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 +++-- 2 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..8f2759f54 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +We welcome all contributions! Please open a [pull request](https://github.com/cmu-db/benchbase/pulls). Common contributions may include: + +- Adding support for a new DBMS. +- Adding more tests of existing benchmarks. +- Fixing any bugs or known issues. + +## Contents + + + +- [Contributing](#contributing) + - [Contents](#contents) + - [IDE](#ide) + - [Adding a new DBMS](#adding-a-new-dbms) + - [Java Development Notes](#java-development-notes) + - [Compiler Warnings](#compiler-warnings) + - [Alternatives to arrays of generics](#alternatives-to-arrays-of-generics) + + + +## IDE + +Although you can use any IDE you prefer, there are some configurations for [VSCode](https://code.visualstudio.com/) that you may find useful included in the repository, including [Github Codespaces](https://github.com/features/codespaces) and [VSCode devcontainer](https://code.visualstudio.com/docs/remote/containers) support to automatically handle dependencies, environment setup, code formatting, and more. + +## Adding a new DBMS + +Please see the existing MySQL and PostgreSQL code for an example. + +## Java Development Notes + +### Compiler Warnings + +In an effort to enforce clean, safe, maintainable code, [PR #413](https://github.com/cmu-db/benchbase/pull/413) enabled the `-Werror` and `-Xlint:all` options for the `javac` compiler. + +This means that any compiler warnings will cause the build to fail. + +If you are seeing a build failure due to a compiler warning, please fix the warning or (on rare occassions) add an exception to the line causing the issue. + +#### Alternatives to arrays of generics + +Per the [Java Language Specification](https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays), arrays of generic types are not allowed and will cause compiler warnings (e.g., `unchecked cast`) + +In some cases, you can extend a generic type to create a non-generic type that can be used in an array. + +For instance, + +```java +// Simple generic class overload to avoid some cast warnings. +class SomeTypeList extends LinkedList {} + +SomeTypeList[] someTypeLists = new SomeTypeList[] { + new SomeTypeList(), + new SomeTypeList(), + new SomeTypeList(), +}; +``` diff --git a/README.md b/README.md index 801a3abd3..8dd5b8574 100644 --- a/README.md +++ b/README.md @@ -221,15 +221,17 @@ Please see the existing MySQL and PostgreSQL code for an example. ## Contributing -We welcome all contributions! Please open a pull request. Common contributions may include: +We welcome all contributions! Please open a [pull request](https://github.com/cmu-db/benchbase/pulls). Common contributions may include: - Adding support for a new DBMS. - Adding more tests of existing benchmarks. - Fixing any bugs or known issues. +Please see the [CONTRIBUTING.md](./CONTRIBUTING.md) for addition notes. + ## Known Issues -Please use GitHub's issue tracker for all issues. +Please use [GitHub's issue tracker](https://github.com/cmu-db/benchbase/issues) for all issues. ## Credits From 4b22f8dacc35e1d50c859ba27dbd424822b8a915 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 16:16:16 +0000 Subject: [PATCH 32/41] tweak comment --- .../oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java index 6572c1a7c..00e5a0321 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java @@ -1195,7 +1195,7 @@ protected class ItemBidGenerator extends SubTableGenerator { private LoaderItemInfo.Bid bid = null; private float currentBidPriceAdvanceStep; private long currentCreateDateAdvanceStep; - @SuppressWarnings("unused") // spurious + @SuppressWarnings("unused") // only ever assigned private float currentPrice; private boolean new_item; From fa34754de5c6139e7da3e7aa13a4f7ce2bf8250f Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 16:26:16 +0000 Subject: [PATCH 33/41] add more developer notes --- CONTRIBUTING.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f2759f54..6d181ae70 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,6 +15,7 @@ We welcome all contributions! Please open a [pull request](https://github.com/cm - [IDE](#ide) - [Adding a new DBMS](#adding-a-new-dbms) - [Java Development Notes](#java-development-notes) + - [Avoid var keyword](#avoid-var-keyword) - [Compiler Warnings](#compiler-warnings) - [Alternatives to arrays of generics](#alternatives-to-arrays-of-generics) @@ -38,6 +39,10 @@ This means that any compiler warnings will cause the build to fail. If you are seeing a build failure due to a compiler warning, please fix the warning or (on rare occassions) add an exception to the line causing the issue. +### Avoid `var` keyword + +In general, we prefer to avoid the `var` keyword in favor of explicit types. + #### Alternatives to arrays of generics Per the [Java Language Specification](https://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#createArrays), arrays of generic types are not allowed and will cause compiler warnings (e.g., `unchecked cast`) From be0f41472a1a78c8035a1d81b568e3c37baa1bff Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 16:29:45 +0000 Subject: [PATCH 34/41] include some extension recommendations --- .vscode/extensions.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..842cbfef9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "EditorConfig.EditorConfig", + "github.vscode-pull-request-github", + "huntertran.auto-markdown-toc", + "vscjava.vscode-java-pack" + ] +} \ No newline at end of file From 43b5ceedf34c52166a8a3d9de50f84198f9156f2 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 16:30:56 +0000 Subject: [PATCH 35/41] update extensions --- .devcontainer/devcontainer.json | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a4d313bd9..f38d12ce5 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -40,11 +40,13 @@ "settings": {}, // Add the IDs of extensions you want installed when the container is created. "extensions": [ - "github.vscode-github-actions", + "EditorConfig.EditorConfig", "GitHub.copilot", "eamodio.gitlens", - "vscjava.vscode-java-pack", - "EditorConfig.EditorConfig" + "github.vscode-github-actions", + "github.vscode-pull-request-github", + "huntertran.auto-markdown-toc", + "vscjava.vscode-java-pack" ] } }, From 986c0fb9133f59b09b3447b9813829649ccda967 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 17:07:17 +0000 Subject: [PATCH 36/41] include style notes in the contributor file --- CONTRIBUTING.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d181ae70..2d7cebdf1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,8 +15,9 @@ We welcome all contributions! Please open a [pull request](https://github.com/cm - [IDE](#ide) - [Adding a new DBMS](#adding-a-new-dbms) - [Java Development Notes](#java-development-notes) - - [Avoid var keyword](#avoid-var-keyword) + - [Code Style](#code-style) - [Compiler Warnings](#compiler-warnings) + - [Avoid var keyword](#avoid-var-keyword) - [Alternatives to arrays of generics](#alternatives-to-arrays-of-generics) @@ -31,6 +32,14 @@ Please see the existing MySQL and PostgreSQL code for an example. ## Java Development Notes +### Code Style + +To allow reviewers to focus more on code content and not style nits, [PR #416](https://github.com/cmu-db/benchbase/pulls/416) added support for auto formatting code at compile time according to [Google Java Style](https://google.github.io/styleguide/javaguide.html) using [google-java-format](https://github.com/google/google-java-format) and [fmt-maven-plugin](https://github.com/spotify/fmt-maven-plugin) Maven plugins. + +Be sure to commit and include these changes in your PRs when submitting them so that the CI pipeline passes. + +Additionally, this formatting style is included in the VSCode settings files for this repo. + ### Compiler Warnings In an effort to enforce clean, safe, maintainable code, [PR #413](https://github.com/cmu-db/benchbase/pull/413) enabled the `-Werror` and `-Xlint:all` options for the `javac` compiler. From 4556f10469050b1a1551c7ad58e34f1a82befde9 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 19:35:46 +0000 Subject: [PATCH 37/41] address more unused warnings --- .../oltpbenchmark/DistributionStatistics.java | 1 + .../java/com/oltpbenchmark/WorkloadState.java | 5 +++-- .../auctionmark/util/AuctionMarkUtil.java | 7 ++++--- .../hyadapt/procedures/MaxRecord1.java | 2 ++ .../hyadapt/procedures/MaxRecord10.java | 1 + .../hyadapt/procedures/MaxRecord2.java | 1 + .../hyadapt/procedures/MaxRecord3.java | 1 + .../hyadapt/procedures/MaxRecord4.java | 1 + .../hyadapt/procedures/MaxRecord5.java | 1 + .../hyadapt/procedures/MaxRecord6.java | 1 + .../hyadapt/procedures/MaxRecord7.java | 1 + .../hyadapt/procedures/MaxRecord8.java | 1 + .../hyadapt/procedures/MaxRecord9.java | 1 + .../hyadapt/procedures/SumRecord1.java | 1 + .../hyadapt/procedures/SumRecord10.java | 1 + .../hyadapt/procedures/SumRecord2.java | 1 + .../hyadapt/procedures/SumRecord3.java | 1 + .../hyadapt/procedures/SumRecord4.java | 1 + .../hyadapt/procedures/SumRecord5.java | 1 + .../hyadapt/procedures/SumRecord6.java | 1 + .../hyadapt/procedures/SumRecord7.java | 1 + .../hyadapt/procedures/SumRecord8.java | 1 + .../hyadapt/procedures/SumRecord9.java | 1 + .../resourcestresser/procedures/IO2.java | 2 +- .../benchmarks/seats/SEATSLoader.java | 2 +- .../benchmarks/seats/SEATSProfile.java | 6 +++--- .../benchmarks/seats/SEATSWorker.java | 4 +++- .../benchmarks/sibench/SILoader.java | 2 +- .../benchmarks/sibench/SIWorker.java | 2 +- .../smallbank/procedures/Amalgamate.java | 7 +++---- .../smallbank/procedures/DepositChecking.java | 2 +- .../smallbank/procedures/TransactSavings.java | 2 +- .../smallbank/procedures/WriteCheck.java | 4 ++-- .../benchmarks/tatp/TATPLoader.java | 18 ++++++++---------- .../benchmarks/tpch/util/Distribution.java | 4 +++- .../benchmarks/tpch/util/GenerateUtils.java | 3 +-- .../tpch/util/TextPoolGenerator.java | 3 +-- .../benchmarks/twitter/TwitterLoader.java | 2 +- .../wikipedia/procedures/GetPageAnonymous.java | 1 + .../procedures/GetPageAuthenticated.java | 5 +++-- .../wikipedia/procedures/UpdatePage.java | 1 + .../benchmarks/ycsb/YCSBLoader.java | 2 +- .../benchmarks/ycsb/YCSBWorker.java | 3 +-- .../oltpbenchmark/catalog/HSQLDBCatalog.java | 1 + .../oltpbenchmark/util/TestCollectionUtil.java | 1 - 45 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/DistributionStatistics.java b/src/main/java/com/oltpbenchmark/DistributionStatistics.java index 65705d2a2..e672801e4 100644 --- a/src/main/java/com/oltpbenchmark/DistributionStatistics.java +++ b/src/main/java/com/oltpbenchmark/DistributionStatistics.java @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit; public class DistributionStatistics { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(DistributionStatistics.class); private static final double[] PERCENTILES = {0.0, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99, 1.0}; diff --git a/src/main/java/com/oltpbenchmark/WorkloadState.java b/src/main/java/com/oltpbenchmark/WorkloadState.java index de12ec8ce..7b5b20ff5 100644 --- a/src/main/java/com/oltpbenchmark/WorkloadState.java +++ b/src/main/java/com/oltpbenchmark/WorkloadState.java @@ -42,6 +42,7 @@ public class WorkloadState { private final Iterator phaseIterator; private int workersWaiting = 0; + @SuppressWarnings("unused") // never read private int workersWorking = 0; private int workerNeedSleep; @@ -60,7 +61,7 @@ public WorkloadState(BenchmarkState benchmarkState, List works, int num_t */ public void addToQueue(int amount, boolean resetQueues) { int workAdded = 0; - + synchronized (this) { if (resetQueues) { workQueue.clear(); @@ -71,7 +72,7 @@ public void addToQueue(int amount, boolean resetQueues) { || !currentPhase.isRateLimited() || currentPhase.isSerial()) { return; } - + // Add the specified number of procedures to the end of the queue. // If we can't keep up with current rate, truncate transactions for (int i = 0; i < amount && workQueue.size() <= RATE_QUEUE_LIMIT; ++i) { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java index 5821e2b35..04410db77 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java @@ -28,6 +28,7 @@ public abstract class AuctionMarkUtil { @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkUtil.class); + @SuppressWarnings("unused") private static final long ITEM_ID_MASK = 0xFFFFFFFFFFFFFFL; // 56 bits (ITEM_ID) /** @@ -64,9 +65,9 @@ public static Timestamp getProcTimestamp(Timestamp[] benchmarkTimes) { */ public static long getScaledTimestamp(Timestamp benchmarkStart, Timestamp clientStart, Timestamp current) { // First get the offset between the benchmarkStart and the clientStart - // We then subtract that value from the current time. This gives us the total elapsed - // time from the current time to the time that the benchmark start (with the gap - // from when the benchmark was loading data cut out) + // We then subtract that value from the current time. This gives us the total elapsed + // time from the current time to the time that the benchmark start (with the gap + // from when the benchmark was loading data cut out) long base = benchmarkStart.getTime(); long offset = current.getTime() - (clientStart.getTime() - base); long elapsed = (offset - base) * AuctionMarkConstants.TIME_SCALE_FACTOR; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java index f879a1853..e141c3daf 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java @@ -28,6 +28,7 @@ import java.sql.SQLException; public class MaxRecord1 extends Procedure { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(MaxRecord1.class); public final SQLStmt maxStmt = new SQLStmt( @@ -44,6 +45,7 @@ public void run(Connection conn, int keyname) throws SQLException { } } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java index e4bd1422d..37bfd3377 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java @@ -49,6 +49,7 @@ public void run(Connection conn, int keyname) throws SQLException { } } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java index 08a5e03ea..2a0a3d227 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java @@ -41,6 +41,7 @@ public void run(Connection conn, int keyname) throws SQLException { } } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java index 18fcf9b2c..efca4788f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java @@ -41,6 +41,7 @@ public void run(Connection conn, int keyname) throws SQLException { max = r.getInt(1); } } + assert max != -1; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java index bb227a158..2061715fe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java @@ -43,6 +43,7 @@ public void run(Connection conn, int keyname) throws SQLException { } } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java index 52766a812..b1f54d74b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java @@ -44,6 +44,7 @@ public void run(Connection conn, int keyname) throws SQLException { } } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java index c56e9972d..bb2e3daa8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java @@ -44,6 +44,7 @@ public void run(Connection conn, int keyname) throws SQLException { max = r.getInt(1); } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java index 3f2658c8c..3ae087a3f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java @@ -45,6 +45,7 @@ public void run(Connection conn, int keyname) throws SQLException { max = r.getInt(1); } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java index 20bf5a396..e43881edc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java @@ -46,6 +46,7 @@ public void run(Connection conn, int keyname) throws SQLException { max = r.getInt(1); } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java index 3f88cefa2..7099acfed 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java @@ -47,6 +47,7 @@ public void run(Connection conn, int keyname) throws SQLException { max = r.getInt(1); } } + assert max != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java index 52ac24689..372634d91 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java @@ -41,6 +41,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java index a3309bd23..a9730dec7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java @@ -48,6 +48,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java index d62aaef5b..34d3b1765 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java @@ -40,6 +40,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java index 09e9e0bf9..b144da52a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java @@ -41,6 +41,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java index 3c0d2b868..bfef02bfa 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java @@ -42,6 +42,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java index b4a875cd3..30aa5f4fe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java @@ -43,6 +43,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java index 0d7d54168..57ef98115 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java @@ -44,6 +44,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java index f2fb37b4d..310110eb0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java @@ -45,6 +45,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java index 356e57678..e6c902d45 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java @@ -46,6 +46,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java index 44d2e2b70..9329ac523 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java @@ -47,6 +47,7 @@ public void run(Connection conn, int keyname) throws SQLException { sum = r.getInt(1); } } + assert sum != -1; } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java index 5a237ff88..ef9dae039 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java @@ -43,7 +43,7 @@ public void run(Connection conn, int myId, int howManyUpdatesPerTransaction, boo //int keyRange = (makeSureWorkerSetFitsInMemory ? 16777216 / 160 : 167772160 / 160); // FIXME int startingKey = myId * keyRange; - int lastKey = (myId + 1) * keyRange - 1; + //int lastKey = (myId + 1) * keyRange - 1; for (int up = 0; up < howManyUpdatesPerTransaction; ++up) { int key = ResourceStresserWorker.gen.nextInt(keyRange) + startingKey; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java index e474e4dd4..74c5b90ca 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java @@ -1268,7 +1268,7 @@ public FlightIterable(Table catalog_tbl, int days_past, int days_future) { private Timestamp convertTimeString(Timestamp base_date, String code) { Matcher m = SEATSConstants.TIMECODE_PATTERN.matcher(code); boolean result = m.find(); - + assert result; int hour = -1; try { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java index a7c986012..b58946bee 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java @@ -210,7 +210,7 @@ protected final void saveProfile(Connection conn) throws SQLException { stmt.setObject(param_idx++, this.reservation_upcoming_offset); // CFP_RESERVATION_OFFSET stmt.setObject(param_idx++, this.num_reservations); // CFP_NUM_RESERVATIONS stmt.setObject(param_idx, JSONUtil.toJSONString(this.code_id_xref)); // CFP_CODE_ID_XREF - int result = stmt.executeUpdate(); + stmt.executeUpdate(); if (LOG.isDebugEnabled()) { LOG.debug("Saved profile information into {}", profileTable.getName()); @@ -226,7 +226,7 @@ protected final void saveProfile(Connection conn) throws SQLException { stmt.setObject(param_idx++, e.getKey()); // CFH_NAME stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA stmt.setObject(param_idx, 1); // CFH_IS_AIRPORT - int result = stmt.executeUpdate(); + stmt.executeUpdate(); } if (LOG.isDebugEnabled()) { @@ -238,7 +238,7 @@ protected final void saveProfile(Connection conn) throws SQLException { stmt.setObject(param_idx++, e.getKey()); // CFH_NAME stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA stmt.setObject(param_idx, 0); // CFH_IS_AIRPORT - int result = stmt.executeUpdate(); + stmt.executeUpdate(); } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java index fd44ea3b8..4d9b2e3d9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java @@ -73,7 +73,9 @@ private enum Transaction { this.displayName = StringUtil.title(this.name().replace("_", " ")); } + @SuppressWarnings("unused") // never read public final Class proc_class; + public final String displayName; public final String execName; @@ -269,7 +271,7 @@ protected void initialize() { // Fire off a FindOpenSeats so that we can prime ourselves FindOpenSeats proc = this.getProcedure(FindOpenSeats.class); try (Connection conn = getBenchmark().makeConnection()) { - boolean ret = this.executeFindOpenSeats(conn, proc); + this.executeFindOpenSeats(conn, proc); } catch (SQLException ex) { throw new RuntimeException(ex); } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java index c13785291..942b391f2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java @@ -77,7 +77,7 @@ private void loadSITest(Connection conn, int lo, int hi) throws SQLException { stmt.addBatch(); if (++batch >= workConf.getBatchSize()) { - int[] result = stmt.executeBatch(); + stmt.executeBatch(); batch = 0; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java index 2bc394d27..58a2653ac 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java @@ -60,7 +60,7 @@ protected TransactionStatus executeWork(Connection conn, TransactionType nextTra private void minRecord(Connection conn) throws SQLException { MinRecord proc = this.getProcedure(MinRecord.class); - int minId = proc.run(conn); + proc.run(conn); } private void updateRecord(Connection conn) throws SQLException { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java index 3aaefa57c..4f850caca 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java @@ -44,7 +44,7 @@ public class Amalgamate extends Procedure { // 2013-05-05 // In the original version of the benchmark, this is suppose to be a look up - // on the customer's name. We don't have fast implementation of replicated + // on the customer's name. We don't have fast implementation of replicated // secondary indexes, so we'll just ignore that part for now. public final SQLStmt GetAccount = new SQLStmt( "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + @@ -131,14 +131,13 @@ public void run(Connection conn, long custId0, long custId1) throws SQLException // assert(total >= 0); // Update Balance Information - int status; try (PreparedStatement updateStmt0 = this.getPreparedStatement(conn, ZeroCheckingBalance, custId0)) { - status = updateStmt0.executeUpdate(); + updateStmt0.executeUpdate(); } try (PreparedStatement updateStmt1 = this.getPreparedStatement(conn, UpdateSavingsBalance, total, custId1)) { - status = updateStmt1.executeUpdate(); + updateStmt1.executeUpdate(); } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java index 87b406fa1..44264986e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java @@ -70,7 +70,7 @@ public void run(Connection conn, String custName, double amount) throws SQLExcep // Then update their checking balance try (PreparedStatement stmt1 = this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { - int status = stmt1.executeUpdate(); + stmt1.executeUpdate(); } } } \ No newline at end of file diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java index b4d3fcd45..5e397925a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java @@ -98,7 +98,7 @@ public void run(Connection conn, String custName, double amount) throws SQLExcep // Then update their savings balance try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateSavingsBalance, amount, custId)) { - int status = stmt.executeUpdate(); + stmt.executeUpdate(); } } } \ No newline at end of file diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java index 3cf747593..7bc12ff91 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java @@ -112,11 +112,11 @@ public void run(Connection conn, String custName, double amount) throws SQLExcep if (total < amount) { try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount - 1, custId)) { - int status = updateStmt.executeUpdate(); + updateStmt.executeUpdate(); } } else { try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { - int status = updateStmt.executeUpdate(); + updateStmt.executeUpdate(); } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java index d6d50e993..5780d72e5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java @@ -147,7 +147,7 @@ void genSubscriber(Connection conn, long lo, long hi) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); } - int[] results = pstmt.executeBatch(); + pstmt.executeBatch(); batch = 0; } @@ -156,8 +156,7 @@ void genSubscriber(Connection conn, long lo, long hi) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); } - int[] results = pstmt.executeBatch(); - + pstmt.executeBatch(); } } @@ -195,7 +194,7 @@ void genAccessInfo(Connection conn) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %6d / %d", TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); } - int[] results = pstmt.executeBatch(); + pstmt.executeBatch(); batch = 0; } @@ -204,8 +203,7 @@ void genAccessInfo(Connection conn) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %6d / %d", TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); } - int[] results = pstmt.executeBatch(); - + pstmt.executeBatch(); } } } @@ -273,13 +271,13 @@ void genSpeAndCal(Connection conn) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %d (%s %d / %d)", TATPConstants.TABLENAME_SPECIAL_FACILITY, spe_total, TATPConstants.TABLENAME_SUBSCRIBER, s_id, subscriberSize)); } - int[] results = spe_pstmt.executeBatch(); + spe_pstmt.executeBatch(); if (cal_added) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %d (%s %d / %d)", TATPConstants.TABLENAME_CALL_FORWARDING, cal_total, TATPConstants.TABLENAME_SUBSCRIBER, s_id, subscriberSize)); } - results = cal_pstmt.executeBatch(); + cal_pstmt.executeBatch(); cal_added = false; } @@ -291,13 +289,13 @@ void genSpeAndCal(Connection conn) throws SQLException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_SPECIAL_FACILITY, spe_total)); } - int[] results = spe_pstmt.executeBatch(); + spe_pstmt.executeBatch(); if (cal_added) { if (LOG.isDebugEnabled()) { LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_CALL_FORWARDING, cal_total)); } - results = cal_pstmt.executeBatch(); + cal_pstmt.executeBatch(); cal_added = false; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java index 18f23dc6c..6f89a721a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,7 +25,9 @@ import static java.util.Objects.requireNonNull; public class Distribution { + @SuppressWarnings("unused") // never read private final String name; + private final List values; private final int[] weights; private final String[] distribution; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java index d1ff5bb98..4aa209165 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -21,7 +21,6 @@ import java.util.Calendar; import java.sql.Date; -import static java.util.Locale.ENGLISH; public final class GenerateUtils { private GenerateUtils() { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java index ff3d3c5cf..66de3482c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,7 +16,6 @@ package com.oltpbenchmark.benchmarks.tpch.util; import com.oltpbenchmark.util.StringUtil; -import com.oltpbenchmark.util.RowRandomBoundedInt; import com.oltpbenchmark.util.RowRandomInt; import java.util.List; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java index 9c2d7a1a6..2077b666e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java @@ -169,7 +169,7 @@ protected void loadUsers(Connection conn, int lo, int hi) throws SQLException { batchSize++; total++; if ((batchSize % workConf.getBatchSize()) == 0) { - int[] result = userInsert.executeBatch(); + userInsert.executeBatch(); userInsert.clearBatch(); batchSize = 0; diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java index abf7be623..bd4a4648d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java @@ -32,6 +32,7 @@ import java.sql.SQLException; public class GetPageAnonymous extends Procedure { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(GetPageAnonymous.class); // ----------------------------------------------------------------- diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java index 9fc2a99ff..43f4701d4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java @@ -97,6 +97,7 @@ public Article run(Connection conn, boolean forSelect, String userIp, int userId try (ResultSet rs = st.executeQuery()) { while (rs.next()) { String userGroupName = rs.getString(1); + assert userGroupName != null; } } } @@ -122,7 +123,7 @@ public Article run(Connection conn, boolean forSelect, String userIp, int userId try (ResultSet rs = st.executeQuery()) { while (rs.next()) { byte[] pr_type = rs.getBytes(1); - + assert pr_type != null; } } } @@ -134,7 +135,7 @@ public Article run(Connection conn, boolean forSelect, String userIp, int userId try (ResultSet rs = st.executeQuery()) { while (rs.next()) { byte[] ipb_expiry = rs.getBytes(11); - + assert ipb_expiry != null; } } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java index 1cfa61319..bf0cee39f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java @@ -32,6 +32,7 @@ import java.util.ArrayList; public class UpdatePage extends Procedure { + @SuppressWarnings("unused") private static final Logger LOG = LoggerFactory.getLogger(UpdatePage.class); // ----------------------------------------------------------------- diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java index e83e17e78..707874ae5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java @@ -77,7 +77,7 @@ private void loadRecords(Connection conn, int start, int stop) throws SQLExcepti stmt.addBatch(); total++; if (++batch >= workConf.getBatchSize()) { - int[] result = stmt.executeBatch(); + stmt.executeBatch(); batch = 0; if (LOG.isDebugEnabled()) { diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java index 25c834fa9..1d2ba38c6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java @@ -30,7 +30,6 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Random; /** * YCSBWorker Implementation @@ -69,7 +68,7 @@ public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) } // This is a minor speed-up to avoid having to invoke the hashmap look-up - // everytime we want to execute a txn. This is important to do on + // everytime we want to execute a txn. This is important to do on // a client machine with not a lot of cores this.procUpdateRecord = this.getProcedure(UpdateRecord.class); this.procScanRecord = this.getProcedure(ScanRecord.class); diff --git a/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java b/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java index 969dbbbde..2000406d6 100644 --- a/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java +++ b/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java @@ -93,6 +93,7 @@ private void init() throws SQLException, IOException { while (colRS.next()) { String colName = colRS.getString(4); int colType = colRS.getInt(5); + @SuppressWarnings("unused") String colTypeName = colRS.getString(6); Integer colSize = colRS.getInt(7); boolean colNullable = colRS.getString(18).equalsIgnoreCase("YES"); diff --git a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java index c2ebecbec..7785f3829 100644 --- a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java +++ b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java @@ -24,7 +24,6 @@ import org.apache.commons.collections4.set.ListOrderedSet; import java.util.*; -import org.junit.Before; import org.junit.Test; /** From 5939e2dbd55595fd4938cbb32b6c55d943f95b01 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Mon, 11 Dec 2023 22:25:40 +0000 Subject: [PATCH 38/41] ignore another error --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index edb6b30e7..37710a7f4 100644 --- a/pom.xml +++ b/pom.xml @@ -342,6 +342,11 @@ -Xlint:all,-processing + + -implicit:class + -Werror From 690b024ca6db0c70048c655dbb475605d47c6a6f Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Wed, 13 Dec 2023 20:06:21 +0000 Subject: [PATCH 39/41] fixup toc --- CONTRIBUTING.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed71e5a1b..e2f7c9992 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,9 +15,11 @@ We welcome all contributions! Please open a [pull request](https://github.com/cm - [IDE](#ide) - [Adding a new DBMS](#adding-a-new-dbms) - [Java Development Notes](#java-development-notes) - - [Avoid var keyword](#avoid-var-keyword) + - [Code Style](#code-style) - [Compiler Warnings](#compiler-warnings) + - [Avoid var keyword](#avoid-var-keyword) - [Alternatives to arrays of generics](#alternatives-to-arrays-of-generics) + - [this-escape warnings](#this-escape-warnings) From b845c6d6e9e83697ef004212c594592ea8d3e656 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Wed, 13 Dec 2023 20:20:34 +0000 Subject: [PATCH 40/41] also compile test sources --- .github/workflows/maven.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index c38759b94..b04b8d4e7 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -54,7 +54,7 @@ jobs: run: mvn -B fmt:check --file pom.xml - name: Compile with Maven - run: mvn -B compile --file pom.xml + run: mvn -B compile test-compile --file pom.xml - name: Test with Maven run: mvn -B test --file pom.xml From a51a1eaa971d10a1b0d85dfeb32bd9dab07f86d4 Mon Sep 17 00:00:00 2001 From: Brian Kroth Date: Wed, 13 Dec 2023 20:21:37 +0000 Subject: [PATCH 41/41] reformat java files --- .../com/oltpbenchmark/BenchmarkState.java | 148 +- .../java/com/oltpbenchmark/DBWorkload.java | 1224 +++--- .../oltpbenchmark/DistributionStatistics.java | 284 +- .../java/com/oltpbenchmark/LatencyRecord.java | 277 +- src/main/java/com/oltpbenchmark/Phase.java | 391 +- src/main/java/com/oltpbenchmark/Results.java | 208 +- .../com/oltpbenchmark/SubmittedProcedure.java | 28 +- .../java/com/oltpbenchmark/ThreadBench.java | 906 ++--- .../oltpbenchmark/WorkloadConfiguration.java | 682 ++-- .../java/com/oltpbenchmark/WorkloadState.java | 401 +- .../oltpbenchmark/api/BenchmarkModule.java | 664 ++-- .../java/com/oltpbenchmark/api/Loader.java | 202 +- .../com/oltpbenchmark/api/LoaderThread.java | 78 +- .../java/com/oltpbenchmark/api/Operation.java | 4 +- .../java/com/oltpbenchmark/api/Procedure.java | 346 +- .../java/com/oltpbenchmark/api/SQLStmt.java | 106 +- .../oltpbenchmark/api/StatementDialects.java | 427 ++- .../api/TransactionGenerator.java | 7 +- .../oltpbenchmark/api/TransactionType.java | 147 +- .../oltpbenchmark/api/TransactionTypes.java | 190 +- .../java/com/oltpbenchmark/api/Worker.java | 911 ++--- .../api/collectors/CockroachCollector.java | 49 +- .../api/collectors/DBCollector.java | 55 +- .../api/collectors/DBParameterCollector.java | 10 +- .../collectors/DBParameterCollectorGen.java | 26 +- .../api/collectors/MySQLCollector.java | 66 +- .../api/collectors/PostgresCollector.java | 133 +- .../api/dialects/DialectType.java | 106 +- .../api/dialects/DialectsType.java | 69 +- .../api/dialects/ObjectFactory.java | 92 +- .../api/dialects/ProcedureType.java | 106 +- .../api/dialects/StatementType.java | 94 +- .../api/templates/ObjectFactory.java | 83 +- .../api/templates/TemplateType.java | 94 +- .../api/templates/TemplatesType.java | 44 +- .../api/templates/TypesType.java | 43 +- .../api/templates/ValuesType.java | 43 +- .../auctionmark/AuctionMarkBenchmark.java | 60 +- .../auctionmark/AuctionMarkConstants.java | 596 ++- .../auctionmark/AuctionMarkLoader.java | 2721 +++++++------- .../auctionmark/AuctionMarkProfile.java | 1799 +++++---- .../auctionmark/AuctionMarkWorker.java | 1485 ++++---- .../exceptions/DuplicateItemIdException.java | 46 +- .../auctionmark/procedures/CloseAuctions.java | 318 +- .../auctionmark/procedures/Config.java | 97 +- .../auctionmark/procedures/GetItem.java | 84 +- .../auctionmark/procedures/GetUserInfo.java | 357 +- .../auctionmark/procedures/LoadConfig.java | 225 +- .../auctionmark/procedures/NewBid.java | 665 ++-- .../auctionmark/procedures/NewComment.java | 182 +- .../procedures/NewCommentResponse.java | 71 +- .../auctionmark/procedures/NewFeedback.java | 149 +- .../auctionmark/procedures/NewItem.java | 496 ++- .../auctionmark/procedures/NewPurchase.java | 462 ++- .../auctionmark/procedures/ResetDatabase.java | 97 +- .../auctionmark/procedures/UpdateItem.java | 186 +- .../auctionmark/procedures/UserInfo.java | 84 +- .../auctionmark/util/AuctionMarkUtil.java | 87 +- .../benchmarks/auctionmark/util/Category.java | 90 +- .../auctionmark/util/CategoryParser.java | 151 +- .../util/GlobalAttributeGroupId.java | 157 +- .../util/GlobalAttributeValueId.java | 133 +- .../auctionmark/util/ItemCommentResponse.java | 66 +- .../benchmarks/auctionmark/util/ItemId.java | 176 +- .../benchmarks/auctionmark/util/ItemInfo.java | 207 +- .../auctionmark/util/ItemStatus.java | 30 +- .../auctionmark/util/LoaderItemInfo.java | 351 +- .../benchmarks/auctionmark/util/UserId.java | 187 +- .../auctionmark/util/UserIdGenerator.java | 342 +- .../benchmarks/chbenchmark/CHBenCHmark.java | 47 +- .../chbenchmark/CHBenCHmarkLoader.java | 425 +-- .../chbenchmark/CHBenCHmarkWorker.java | 29 +- .../benchmarks/chbenchmark/pojo/Nation.java | 34 +- .../benchmarks/chbenchmark/pojo/Region.java | 29 +- .../benchmarks/chbenchmark/pojo/Supplier.java | 47 +- .../chbenchmark/queries/GenericQuery.java | 16 +- .../benchmarks/chbenchmark/queries/Q1.java | 30 +- .../benchmarks/chbenchmark/queries/Q10.java | 60 +- .../benchmarks/chbenchmark/queries/Q11.java | 44 +- .../benchmarks/chbenchmark/queries/Q12.java | 38 +- .../benchmarks/chbenchmark/queries/Q13.java | 36 +- .../benchmarks/chbenchmark/queries/Q14.java | 22 +- .../benchmarks/chbenchmark/queries/Q15.java | 83 +- .../benchmarks/chbenchmark/queries/Q16.java | 42 +- .../benchmarks/chbenchmark/queries/Q17.java | 30 +- .../benchmarks/chbenchmark/queries/Q18.java | 56 +- .../benchmarks/chbenchmark/queries/Q19.java | 64 +- .../benchmarks/chbenchmark/queries/Q2.java | 70 +- .../benchmarks/chbenchmark/queries/Q20.java | 44 +- .../benchmarks/chbenchmark/queries/Q21.java | 60 +- .../benchmarks/chbenchmark/queries/Q22.java | 70 +- .../benchmarks/chbenchmark/queries/Q3.java | 60 +- .../benchmarks/chbenchmark/queries/Q4.java | 34 +- .../benchmarks/chbenchmark/queries/Q5.java | 60 +- .../benchmarks/chbenchmark/queries/Q6.java | 20 +- .../benchmarks/chbenchmark/queries/Q7.java | 76 +- .../benchmarks/chbenchmark/queries/Q8.java | 72 +- .../benchmarks/chbenchmark/queries/Q9.java | 56 +- .../epinions/EpinionsBenchmark.java | 116 +- .../epinions/EpinionsConstants.java | 23 +- .../benchmarks/epinions/EpinionsLoader.java | 633 ++-- .../benchmarks/epinions/EpinionsWorker.java | 224 +- .../GetAverageRatingByTrustedUser.java | 26 +- .../procedures/GetItemAverageRating.java | 22 +- .../GetItemReviewsByTrustedUser.java | 43 +- .../procedures/GetReviewItemById.java | 26 +- .../epinions/procedures/GetReviewsByUser.java | 25 +- .../epinions/procedures/UpdateItemTitle.java | 17 +- .../procedures/UpdateReviewRating.java | 20 +- .../procedures/UpdateTrustRating.java | 21 +- .../epinions/procedures/UpdateUserName.java | 15 +- .../benchmarks/hyadapt/HYADAPTBenchmark.java | 88 +- .../benchmarks/hyadapt/HYADAPTConstants.java | 9 +- .../benchmarks/hyadapt/HYADAPTLoader.java | 130 +- .../benchmarks/hyadapt/HYADAPTWorker.java | 467 ++- .../hyadapt/procedures/MaxRecord1.java | 37 +- .../hyadapt/procedures/MaxRecord10.java | 47 +- .../hyadapt/procedures/MaxRecord2.java | 31 +- .../hyadapt/procedures/MaxRecord3.java | 32 +- .../hyadapt/procedures/MaxRecord4.java | 35 +- .../hyadapt/procedures/MaxRecord5.java | 37 +- .../hyadapt/procedures/MaxRecord6.java | 39 +- .../hyadapt/procedures/MaxRecord7.java | 41 +- .../hyadapt/procedures/MaxRecord8.java | 43 +- .../hyadapt/procedures/MaxRecord9.java | 45 +- .../hyadapt/procedures/ReadRecord1.java | 31 +- .../hyadapt/procedures/ReadRecord10.java | 50 +- .../hyadapt/procedures/ReadRecord2.java | 33 +- .../hyadapt/procedures/ReadRecord3.java | 36 +- .../hyadapt/procedures/ReadRecord4.java | 38 +- .../hyadapt/procedures/ReadRecord5.java | 40 +- .../hyadapt/procedures/ReadRecord6.java | 42 +- .../hyadapt/procedures/ReadRecord7.java | 44 +- .../hyadapt/procedures/ReadRecord8.java | 46 +- .../hyadapt/procedures/ReadRecord9.java | 48 +- .../hyadapt/procedures/SumRecord1.java | 31 +- .../hyadapt/procedures/SumRecord10.java | 47 +- .../hyadapt/procedures/SumRecord2.java | 31 +- .../hyadapt/procedures/SumRecord3.java | 33 +- .../hyadapt/procedures/SumRecord4.java | 34 +- .../hyadapt/procedures/SumRecord5.java | 37 +- .../hyadapt/procedures/SumRecord6.java | 39 +- .../hyadapt/procedures/SumRecord7.java | 41 +- .../hyadapt/procedures/SumRecord8.java | 43 +- .../hyadapt/procedures/SumRecord9.java | 45 +- .../benchmarks/noop/NoOpBenchmark.java | 46 +- .../benchmarks/noop/NoOpLoader.java | 16 +- .../benchmarks/noop/NoOpWorker.java | 48 +- .../benchmarks/noop/procedures/NoOp.java | 59 +- .../otmetrics/OTMetricsBenchmark.java | 63 +- .../otmetrics/OTMetricsConstants.java | 39 +- .../benchmarks/otmetrics/OTMetricsLoader.java | 431 +-- .../benchmarks/otmetrics/OTMetricsUtil.java | 47 +- .../benchmarks/otmetrics/OTMetricsWorker.java | 74 +- .../otmetrics/procedures/GetSessionRange.java | 105 +- .../ResourceStresserBenchmark.java | 56 +- .../ResourceStresserConstants.java | 13 +- .../ResourceStresserLoader.java | 145 +- .../ResourceStresserWorker.java | 207 +- .../resourcestresser/procedures/CPU1.java | 58 +- .../resourcestresser/procedures/CPU2.java | 58 +- .../procedures/Contention1.java | 69 +- .../procedures/Contention2.java | 62 +- .../resourcestresser/procedures/IO1.java | 73 +- .../resourcestresser/procedures/IO2.java | 56 +- .../benchmarks/seats/SEATSBenchmark.java | 75 +- .../benchmarks/seats/SEATSConstants.java | 479 ++- .../benchmarks/seats/SEATSLoader.java | 3306 +++++++++-------- .../benchmarks/seats/SEATSProfile.java | 1366 ++++--- .../benchmarks/seats/SEATSWorker.java | 1196 +++--- .../benchmarks/seats/procedures/Config.java | 84 +- .../seats/procedures/DeleteReservation.java | 287 +- .../seats/procedures/FindFlights.java | 277 +- .../seats/procedures/FindOpenSeats.java | 190 +- .../seats/procedures/LoadConfig.java | 185 +- .../seats/procedures/NewReservation.java | 407 +- .../seats/procedures/UpdateCustomer.java | 199 +- .../seats/procedures/UpdateReservation.java | 165 +- .../benchmarks/seats/util/CustomerId.java | 152 +- .../seats/util/CustomerIdIterable.java | 75 +- .../benchmarks/seats/util/DistanceUtil.java | 78 +- .../benchmarks/seats/util/ErrorType.java | 33 +- .../benchmarks/seats/util/FlightId.java | 317 +- .../benchmarks/seats/util/ReturnFlight.java | 170 +- .../seats/util/SEATSHistogramUtil.java | 120 +- .../benchmarks/sibench/SIBenchmark.java | 72 +- .../benchmarks/sibench/SIConstants.java | 8 +- .../benchmarks/sibench/SILoader.java | 89 +- .../benchmarks/sibench/SIWorker.java | 60 +- .../sibench/procedures/MinRecord.java | 25 +- .../sibench/procedures/UpdateRecord.java | 21 +- .../smallbank/SmallBankBenchmark.java | 74 +- .../smallbank/SmallBankConstants.java | 60 +- .../benchmarks/smallbank/SmallBankLoader.java | 201 +- .../benchmarks/smallbank/SmallBankWorker.java | 211 +- .../smallbank/procedures/Amalgamate.java | 178 +- .../smallbank/procedures/Balance.java | 92 +- .../smallbank/procedures/DepositChecking.java | 54 +- .../smallbank/procedures/SendPayment.java | 116 +- .../smallbank/procedures/TransactSavings.java | 97 +- .../smallbank/procedures/WriteCheck.java | 127 +- .../benchmarks/tatp/TATPBenchmark.java | 38 +- .../benchmarks/tatp/TATPConstants.java | 60 +- .../benchmarks/tatp/TATPLoader.java | 495 +-- .../benchmarks/tatp/TATPUtil.java | 144 +- .../benchmarks/tatp/TATPWorker.java | 283 +- .../tatp/procedures/DeleteCallForwarding.java | 60 +- .../tatp/procedures/GetAccessData.java | 27 +- .../tatp/procedures/GetNewDestination.java | 51 +- .../tatp/procedures/GetSubscriberData.java | 19 +- .../tatp/procedures/InsertCallForwarding.java | 85 +- .../tatp/procedures/UpdateLocation.java | 49 +- .../tatp/procedures/UpdateSubscriberData.java | 61 +- .../templated/TemplatedBenchmark.java | 411 +- .../benchmarks/templated/TemplatedWorker.java | 69 +- .../templated/procedures/GenericQuery.java | 148 +- .../templated/util/GenericQueryOperation.java | 24 +- .../util/TraceTransactionGenerator.java | 44 +- .../benchmarks/tpcc/TPCCBenchmark.java | 149 +- .../benchmarks/tpcc/TPCCConfig.java | 24 +- .../benchmarks/tpcc/TPCCConstants.java | 18 +- .../benchmarks/tpcc/TPCCLoader.java | 1194 +++--- .../benchmarks/tpcc/TPCCUtil.java | 197 +- .../benchmarks/tpcc/TPCCWorker.java | 131 +- .../benchmarks/tpcc/pojo/Customer.java | 204 +- .../benchmarks/tpcc/pojo/District.java | 76 +- .../benchmarks/tpcc/pojo/History.java | 47 +- .../benchmarks/tpcc/pojo/Item.java | 34 +- .../benchmarks/tpcc/pojo/NewOrder.java | 27 +- .../benchmarks/tpcc/pojo/Oorder.java | 52 +- .../benchmarks/tpcc/pojo/OrderLine.java | 62 +- .../benchmarks/tpcc/pojo/Stock.java | 115 +- .../benchmarks/tpcc/pojo/Warehouse.java | 54 +- .../benchmarks/tpcc/procedures/Delivery.java | 396 +- .../benchmarks/tpcc/procedures/NewOrder.java | 568 +-- .../tpcc/procedures/OrderStatus.java | 424 ++- .../benchmarks/tpcc/procedures/Payment.java | 822 ++-- .../tpcc/procedures/StockLevel.java | 145 +- .../tpcc/procedures/TPCCProcedure.java | 12 +- .../benchmarks/tpcds/TPCDSBenchmark.java | 59 +- .../benchmarks/tpcds/TPCDSConstants.java | 1004 ++--- .../benchmarks/tpcds/TPCDSLoader.java | 1024 ++--- .../benchmarks/tpcds/TPCDSWorker.java | 15 +- .../benchmarks/tpcds/procedures/Test.java | 5 +- .../benchmarks/tpch/TPCHBenchmark.java | 48 +- .../benchmarks/tpch/TPCHConstants.java | 200 +- .../benchmarks/tpch/TPCHLoader.java | 608 +-- .../benchmarks/tpch/TPCHUtil.java | 172 +- .../benchmarks/tpch/TPCHWorker.java | 38 +- .../tpch/procedures/GenericQuery.java | 35 +- .../benchmarks/tpch/procedures/Q1.java | 23 +- .../benchmarks/tpch/procedures/Q10.java | 32 +- .../benchmarks/tpch/procedures/Q11.java | 33 +- .../benchmarks/tpch/procedures/Q12.java | 50 +- .../benchmarks/tpch/procedures/Q13.java | 32 +- .../benchmarks/tpch/procedures/Q14.java | 31 +- .../benchmarks/tpch/procedures/Q15.java | 71 +- .../benchmarks/tpch/procedures/Q16.java | 63 +- .../benchmarks/tpch/procedures/Q17.java | 36 +- .../benchmarks/tpch/procedures/Q18.java | 25 +- .../benchmarks/tpch/procedures/Q19.java | 60 +- .../benchmarks/tpch/procedures/Q2.java | 33 +- .../benchmarks/tpch/procedures/Q20.java | 41 +- .../benchmarks/tpch/procedures/Q21.java | 25 +- .../benchmarks/tpch/procedures/Q22.java | 62 +- .../benchmarks/tpch/procedures/Q3.java | 33 +- .../benchmarks/tpch/procedures/Q4.java | 29 +- .../benchmarks/tpch/procedures/Q5.java | 31 +- .../benchmarks/tpch/procedures/Q6.java | 51 +- .../benchmarks/tpch/procedures/Q7.java | 43 +- .../benchmarks/tpch/procedures/Q8.java | 48 +- .../benchmarks/tpch/procedures/Q9.java | 28 +- .../tpch/util/CustomerGenerator.java | 214 +- .../benchmarks/tpch/util/Distribution.java | 119 +- .../tpch/util/DistributionLoader.java | 120 +- .../benchmarks/tpch/util/Distributions.java | 312 +- .../benchmarks/tpch/util/GenerateUtils.java | 199 +- .../tpch/util/LineItemGenerator.java | 475 +-- .../benchmarks/tpch/util/NationGenerator.java | 86 +- .../benchmarks/tpch/util/OrderGenerator.java | 392 +- .../benchmarks/tpch/util/PartGenerator.java | 253 +- .../tpch/util/PartSupplierGenerator.java | 198 +- .../benchmarks/tpch/util/RegionGenerator.java | 84 +- .../tpch/util/SupplierGenerator.java | 296 +- .../tpch/util/TPCHRandomAlphaNumeric.java | 59 +- .../tpch/util/TPCHRandomPhoneNumber.java | 42 +- .../tpch/util/TPCHRandomString.java | 27 +- .../tpch/util/TPCHRandomStringSequence.java | 51 +- .../benchmarks/tpch/util/TPCHRandomText.java | 43 +- .../benchmarks/tpch/util/TextPool.java | 323 +- .../tpch/util/TextPoolGenerator.java | 393 +- .../benchmarks/twitter/TwitterBenchmark.java | 71 +- .../twitter/TwitterConfiguration.java | 20 +- .../benchmarks/twitter/TwitterConstants.java | 60 +- .../benchmarks/twitter/TwitterLoader.java | 510 ++- .../benchmarks/twitter/TwitterWorker.java | 118 +- .../twitter/procedures/GetFollowers.java | 61 +- .../twitter/procedures/GetTweet.java | 20 +- .../procedures/GetTweetsFromFollowing.java | 64 +- .../twitter/procedures/GetUserTweets.java | 22 +- .../twitter/procedures/InsertTweet.java | 24 +- .../twitter/util/NameHistogram.java | 37 +- .../util/TraceTransactionGenerator.java | 36 +- .../twitter/util/TweetHistogram.java | 283 +- .../twitter/util/TwitterOperation.java | 21 +- .../benchmarks/voter/VoterBenchmark.java | 55 +- .../benchmarks/voter/VoterConstants.java | 128 +- .../benchmarks/voter/VoterLoader.java | 85 +- .../benchmarks/voter/VoterWorker.java | 29 +- .../benchmarks/voter/procedures/Vote.java | 146 +- .../voter/util/PhoneCallGenerator.java | 110 +- .../wikipedia/WikipediaBenchmark.java | 165 +- .../wikipedia/WikipediaConstants.java | 103 +- .../benchmarks/wikipedia/WikipediaLoader.java | 1112 +++--- .../benchmarks/wikipedia/WikipediaWorker.java | 297 +- .../wikipedia/data/PageHistograms.java | 692 ++-- .../wikipedia/data/RevisionHistograms.java | 2610 +++++++------ .../wikipedia/data/TextHistograms.java | 3034 ++++++++------- .../wikipedia/data/UserHistograms.java | 1368 ++++--- .../wikipedia/procedures/AddWatchList.java | 125 +- .../procedures/GetPageAnonymous.java | 234 +- .../procedures/GetPageAuthenticated.java | 290 +- .../wikipedia/procedures/RemoveWatchList.java | 71 +- .../wikipedia/procedures/UpdatePage.java | 471 ++- .../benchmarks/wikipedia/util/Article.java | 29 +- .../wikipedia/util/WikipediaUtil.java | 33 +- .../benchmarks/ycsb/YCSBBenchmark.java | 123 +- .../benchmarks/ycsb/YCSBConstants.java | 25 +- .../benchmarks/ycsb/YCSBLoader.java | 112 +- .../benchmarks/ycsb/YCSBWorker.java | 181 +- .../ycsb/procedures/DeleteRecord.java | 22 +- .../ycsb/procedures/InsertRecord.java | 29 +- .../procedures/ReadModifyWriteRecord.java | 64 +- .../ycsb/procedures/ReadRecord.java | 32 +- .../ycsb/procedures/ScanRecord.java | 39 +- .../ycsb/procedures/UpdateRecord.java | 36 +- .../catalog/AbstractCatalog.java | 14 +- .../catalog/AbstractCatalogObject.java | 68 +- .../com/oltpbenchmark/catalog/Catalog.java | 42 +- .../com/oltpbenchmark/catalog/Column.java | 132 +- .../oltpbenchmark/catalog/HSQLDBCatalog.java | 408 +- .../java/com/oltpbenchmark/catalog/Index.java | 129 +- .../java/com/oltpbenchmark/catalog/Table.java | 149 +- .../distributions/CounterGenerator.java | 71 +- .../distributions/CyclicCounterGenerator.java | 77 +- .../distributions/Generator.java | 23 +- .../distributions/IntegerGenerator.java | 75 +- .../ScrambledZipfianGenerator.java | 143 +- .../oltpbenchmark/distributions/Utils.java | 70 +- .../distributions/ZipfianGenerator.java | 550 +-- .../jdbc/AutoIncrementPreparedStatement.java | 1037 +++--- .../com/oltpbenchmark/types/DatabaseType.java | 189 +- .../types/SortDirectionType.java | 49 +- .../java/com/oltpbenchmark/types/State.java | 14 +- .../types/TransactionStatus.java | 48 +- .../com/oltpbenchmark/util/ClassUtil.java | 325 +- .../oltpbenchmark/util/CollectionUtil.java | 298 +- .../com/oltpbenchmark/util/CompositeId.java | 63 +- .../java/com/oltpbenchmark/util/FileUtil.java | 136 +- .../com/oltpbenchmark/util/Histogram.java | 1226 +++--- .../oltpbenchmark/util/JSONSerializable.java | 13 +- .../java/com/oltpbenchmark/util/JSONUtil.java | 1125 +++--- .../util/LatchedExceptionHandler.java | 31 +- .../java/com/oltpbenchmark/util/Pair.java | 94 +- .../util/RandomDistribution.java | 575 ++- .../oltpbenchmark/util/RandomGenerator.java | 198 +- .../com/oltpbenchmark/util/ResultWriter.java | 353 +- .../util/RowRandomBoundedInt.java | 31 +- .../util/RowRandomBoundedLong.java | 73 +- .../com/oltpbenchmark/util/RowRandomInt.java | 159 +- .../com/oltpbenchmark/util/RowRandomLong.java | 121 +- .../java/com/oltpbenchmark/util/SQLUtil.java | 1159 +++--- .../com/oltpbenchmark/util/ScriptRunner.java | 255 +- .../com/oltpbenchmark/util/StringUtil.java | 801 ++-- .../oltpbenchmark/util/TableDataIterable.java | 226 +- .../com/oltpbenchmark/util/TextGenerator.java | 252 +- .../com/oltpbenchmark/util/ThreadUtil.java | 168 +- .../java/com/oltpbenchmark/util/TimeUtil.java | 46 +- .../api/AbstractTestBenchmarkModule.java | 290 +- .../oltpbenchmark/api/AbstractTestCase.java | 341 +- .../oltpbenchmark/api/AbstractTestLoader.java | 149 +- .../oltpbenchmark/api/AbstractTestWorker.java | 146 +- .../com/oltpbenchmark/api/MockBenchmark.java | 49 +- .../oltpbenchmark/api/TestDDLOverride.java | 72 +- .../com/oltpbenchmark/api/TestProcedure.java | 88 +- .../com/oltpbenchmark/api/TestSQLStmt.java | 66 +- .../auctionmark/TestAuctionMarkBenchmark.java | 80 +- .../auctionmark/TestAuctionMarkLoader.java | 142 +- .../auctionmark/TestAuctionMarkWorker.java | 102 +- .../auctionmark/util/TestItemId.java | 79 +- .../auctionmark/util/TestUserId.java | 283 +- .../auctionmark/util/TestUserIdGenerator.java | 479 ++- .../chbenchmark/TestCHBenCHmark.java | 52 +- .../chbenchmark/TestCHBenCHmarkLoader.java | 20 +- .../chbenchmark/TestCHBenCHmarkWorker.java | 20 +- .../epinions/TestEpinionsBenchmark.java | 43 +- .../epinions/TestEpinionsLoader.java | 26 +- .../epinions/TestEpinionsWorker.java | 19 +- .../benchmarks/noop/TestNoOpBenchmark.java | 22 +- .../benchmarks/noop/TestNoOpLoader.java | 25 +- .../benchmarks/noop/TestNoOpWorker.java | 18 +- .../otmetrics/TestOTMetricsBenchmark.java | 23 +- .../otmetrics/TestOTMetricsLoader.java | 29 +- .../otmetrics/TestOTMetricsWorker.java | 17 +- .../TestResourceStresserBenchmark.java | 32 +- .../TestResourceStresserLoader.java | 17 +- .../TestResourceStresserWorker.java | 17 +- .../benchmarks/seats/TestSEATSBenchmark.java | 65 +- .../benchmarks/seats/TestSEATSLoader.java | 91 +- .../benchmarks/seats/TestSEATSWorker.java | 18 +- .../benchmarks/seats/util/TestCustomerId.java | 99 +- .../seats/util/TestCustomerIdIterable.java | 60 +- .../seats/util/TestDistanceUtil.java | 64 +- .../benchmarks/seats/util/TestFlightId.java | 164 +- .../seats/util/TestReturnFlight.java | 70 +- .../smallbank/TestSmallBankBenchmark.java | 39 +- .../smallbank/TestSmallBankLoader.java | 18 +- .../smallbank/TestSmallBankWorker.java | 17 +- .../benchmarks/tatp/TestTATPBenchmark.java | 41 +- .../benchmarks/tatp/TestTATPLoader.java | 18 +- .../benchmarks/tatp/TestTATPWorker.java | 17 +- .../templated/TestTemplatedWorker.java | 196 +- .../benchmarks/tpcc/TestTPCCBenchmark.java | 28 +- .../benchmarks/tpcc/TestTPCCLoader.java | 18 +- .../benchmarks/tpcc/TestTPCCWorker.java | 18 +- .../benchmarks/tpch/TestTPCHBenchmark.java | 51 +- .../benchmarks/tpch/TestTPCHLoader.java | 18 +- .../benchmarks/tpch/TestTPCHWorker.java | 31 +- .../twitter/TestTwitterBenchmark.java | 26 +- .../benchmarks/twitter/TestTwitterLoader.java | 32 +- .../benchmarks/twitter/TestTwitterWorker.java | 19 +- .../benchmarks/voter/TestVoterBenchmark.java | 22 +- .../benchmarks/voter/TestVoterLoader.java | 30 +- .../benchmarks/voter/TestVoterWorker.java | 17 +- .../wikipedia/TestWikipediaBenchmark.java | 37 +- .../wikipedia/TestWikipediaLoader.java | 53 +- .../wikipedia/TestWikipediaWorker.java | 17 +- .../benchmarks/ycsb/TestYCSBBenchmark.java | 39 +- .../benchmarks/ycsb/TestYCSBLoader.java | 18 +- .../benchmarks/ycsb/TestYCSBWorker.java | 17 +- .../catalog/TestHSQLDBCatalog.java | 228 +- .../com/oltpbenchmark/util/TestClassUtil.java | 181 +- .../util/TestCollectionUtil.java | 207 +- .../util/TestCompositeIdRange.java | 138 +- .../com/oltpbenchmark/util/TestFileUtil.java | 68 +- .../com/oltpbenchmark/util/TestHistogram.java | 477 ++- .../util/TestRandomDistribution.java | 311 +- .../oltpbenchmark/util/TestTextGenerator.java | 195 +- 448 files changed, 41914 insertions(+), 41018 deletions(-) diff --git a/src/main/java/com/oltpbenchmark/BenchmarkState.java b/src/main/java/com/oltpbenchmark/BenchmarkState.java index 8eee9cbe7..8c5cb9158 100644 --- a/src/main/java/com/oltpbenchmark/BenchmarkState.java +++ b/src/main/java/com/oltpbenchmark/BenchmarkState.java @@ -18,109 +18,99 @@ package com.oltpbenchmark; import com.oltpbenchmark.types.State; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class BenchmarkState { - private static final Logger LOG = LoggerFactory.getLogger(BenchmarkState.class); + private static final Logger LOG = LoggerFactory.getLogger(BenchmarkState.class); - private final long testStartNs; - private final CountDownLatch startBarrier; - private final AtomicInteger notDoneCount; - private volatile State state = State.WARMUP; + private final long testStartNs; + private final CountDownLatch startBarrier; + private final AtomicInteger notDoneCount; + private volatile State state = State.WARMUP; - /** - * @param numThreads number of threads involved in the test: including the - * master thread. - */ - public BenchmarkState(int numThreads) { - startBarrier = new CountDownLatch(numThreads); - notDoneCount = new AtomicInteger(numThreads); + /** + * @param numThreads number of threads involved in the test: including the master thread. + */ + public BenchmarkState(int numThreads) { + startBarrier = new CountDownLatch(numThreads); + notDoneCount = new AtomicInteger(numThreads); + testStartNs = System.nanoTime(); + } - testStartNs = System.nanoTime(); - } + // Protected by this - // Protected by this + public long getTestStartNs() { + return testStartNs; + } - public long getTestStartNs() { - return testStartNs; + public State getState() { + synchronized (this) { + return state; } + } - public State getState() { - synchronized (this) { - return state; - } + /** Wait for all threads to call this. Returns once all the threads have entered. */ + public void blockForStart() { + + startBarrier.countDown(); + try { + startBarrier.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - /** - * Wait for all threads to call this. Returns once all the threads have - * entered. - */ - public void blockForStart() { + public void startMeasure() { + state = State.MEASURE; + } + public void startColdQuery() { + state = State.COLD_QUERY; + } - startBarrier.countDown(); - try { - startBarrier.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } + public void startHotQuery() { + state = State.MEASURE; + } - public void startMeasure() { - state = State.MEASURE; - } + public void signalLatencyComplete() { + state = State.LATENCY_COMPLETE; + } - public void startColdQuery() { - state = State.COLD_QUERY; - } + public void ackLatencyComplete() { + state = State.MEASURE; + } - public void startHotQuery() { - state = State.MEASURE; - } + public void signalError() { + // A thread died, decrement the count and set error state + notDoneCount.decrementAndGet(); + state = State.ERROR; + } - public void signalLatencyComplete() { - state = State.LATENCY_COMPLETE; - } + public void startCoolDown() { + state = State.DONE; - public void ackLatencyComplete() { - state = State.MEASURE; - } + // The master thread must also signal that it is done + signalDone(); + } - public void signalError() { - // A thread died, decrement the count and set error state - notDoneCount.decrementAndGet(); - state = State.ERROR; - } + /** Notify that this thread has entered the done state. */ + public int signalDone() { - public void startCoolDown() { - state = State.DONE; + int current = notDoneCount.decrementAndGet(); - // The master thread must also signal that it is done - signalDone(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%d workers are not done. Waiting until they finish", current)); } - - /** - * Notify that this thread has entered the done state. - */ - public int signalDone() { - - int current = notDoneCount.decrementAndGet(); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%d workers are not done. Waiting until they finish", current)); - } - if (current == 0) { - // We are the last thread to notice that we are done: wake any - // blocked workers - this.state = State.EXIT; - } - return current; + if (current == 0) { + // We are the last thread to notice that we are done: wake any + // blocked workers + this.state = State.EXIT; } - -} \ No newline at end of file + return current; + } +} diff --git a/src/main/java/com/oltpbenchmark/DBWorkload.java b/src/main/java/com/oltpbenchmark/DBWorkload.java index 46231c0e7..5ca701046 100644 --- a/src/main/java/com/oltpbenchmark/DBWorkload.java +++ b/src/main/java/com/oltpbenchmark/DBWorkload.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark; import com.oltpbenchmark.api.BenchmarkModule; @@ -24,6 +23,11 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.*; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.sql.SQLException; +import java.util.*; import org.apache.commons.cli.*; import org.apache.commons.collections4.map.ListOrderedMap; import org.apache.commons.configuration2.HierarchicalConfiguration; @@ -38,642 +42,728 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.sql.SQLException; -import java.util.*; - public class DBWorkload { - private static final Logger LOG = LoggerFactory.getLogger(DBWorkload.class); + private static final Logger LOG = LoggerFactory.getLogger(DBWorkload.class); - private static final String SINGLE_LINE = StringUtil.repeat("=", 70); + private static final String SINGLE_LINE = StringUtil.repeat("=", 70); - private static final String RATE_DISABLED = "disabled"; - private static final String RATE_UNLIMITED = "unlimited"; + private static final String RATE_DISABLED = "disabled"; + private static final String RATE_UNLIMITED = "unlimited"; - /** - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { + /** + * @param args + * @throws Exception + */ + public static void main(String[] args) throws Exception { - // create the command line parser - CommandLineParser parser = new DefaultParser(); + // create the command line parser + CommandLineParser parser = new DefaultParser(); - XMLConfiguration pluginConfig = buildConfiguration("config/plugin.xml"); + XMLConfiguration pluginConfig = buildConfiguration("config/plugin.xml"); - Options options = buildOptions(pluginConfig); + Options options = buildOptions(pluginConfig); - CommandLine argsLine = parser.parse(options, args); + CommandLine argsLine = parser.parse(options, args); - if (argsLine.hasOption("h")) { - printUsage(options); - return; - } else if (!argsLine.hasOption("c")) { - LOG.error("Missing Configuration file"); - printUsage(options); - return; - } else if (!argsLine.hasOption("b")) { - LOG.error("Missing Benchmark Class to load"); - printUsage(options); - return; - } + if (argsLine.hasOption("h")) { + printUsage(options); + return; + } else if (!argsLine.hasOption("c")) { + LOG.error("Missing Configuration file"); + printUsage(options); + return; + } else if (!argsLine.hasOption("b")) { + LOG.error("Missing Benchmark Class to load"); + printUsage(options); + return; + } + // Seconds + int intervalMonitor = 0; + if (argsLine.hasOption("im")) { + intervalMonitor = Integer.parseInt(argsLine.getOptionValue("im")); + } - // Seconds - int intervalMonitor = 0; - if (argsLine.hasOption("im")) { - intervalMonitor = Integer.parseInt(argsLine.getOptionValue("im")); + // ------------------------------------------------------------------- + // GET PLUGIN LIST + // ------------------------------------------------------------------- + + String targetBenchmarks = argsLine.getOptionValue("b"); + + String[] targetList = targetBenchmarks.split(","); + List benchList = new ArrayList<>(); + + // Use this list for filtering of the output + List activeTXTypes = new ArrayList<>(); + + String configFile = argsLine.getOptionValue("c"); + + XMLConfiguration xmlConfig = buildConfiguration(configFile); + + // Load the configuration for each benchmark + int lastTxnId = 0; + for (String plugin : targetList) { + String pluginTest = "[@bench='" + plugin + "']"; + + // ---------------------------------------------------------------- + // BEGIN LOADING WORKLOAD CONFIGURATION + // ---------------------------------------------------------------- + + WorkloadConfiguration wrkld = new WorkloadConfiguration(); + wrkld.setBenchmarkName(plugin); + wrkld.setXmlConfig(xmlConfig); + + // Pull in database configuration + wrkld.setDatabaseType(DatabaseType.get(xmlConfig.getString("type"))); + wrkld.setDriverClass(xmlConfig.getString("driver")); + wrkld.setUrl(xmlConfig.getString("url")); + wrkld.setUsername(xmlConfig.getString("username")); + wrkld.setPassword(xmlConfig.getString("password")); + wrkld.setRandomSeed(xmlConfig.getInt("randomSeed", -1)); + wrkld.setBatchSize(xmlConfig.getInt("batchsize", 128)); + wrkld.setMaxRetries(xmlConfig.getInt("retries", 3)); + wrkld.setNewConnectionPerTxn(xmlConfig.getBoolean("newConnectionPerTxn", false)); + + int terminals = xmlConfig.getInt("terminals[not(@bench)]", 0); + terminals = xmlConfig.getInt("terminals" + pluginTest, terminals); + wrkld.setTerminals(terminals); + + if (xmlConfig.containsKey("loaderThreads")) { + int loaderThreads = xmlConfig.getInt("loaderThreads"); + wrkld.setLoaderThreads(loaderThreads); + } + + String isolationMode = + xmlConfig.getString("isolation[not(@bench)]", "TRANSACTION_SERIALIZABLE"); + wrkld.setIsolationMode(xmlConfig.getString("isolation" + pluginTest, isolationMode)); + wrkld.setScaleFactor(xmlConfig.getDouble("scalefactor", 1.0)); + wrkld.setDataDir(xmlConfig.getString("datadir", ".")); + wrkld.setDDLPath(xmlConfig.getString("ddlpath", null)); + + double selectivity = -1; + try { + selectivity = xmlConfig.getDouble("selectivity"); + wrkld.setSelectivity(selectivity); + } catch (NoSuchElementException nse) { + // Nothing to do here ! + } + + // ---------------------------------------------------------------- + // CREATE BENCHMARK MODULE + // ---------------------------------------------------------------- + + String classname = pluginConfig.getString("/plugin[@name='" + plugin + "']"); + + if (classname == null) { + throw new ParseException("Plugin " + plugin + " is undefined in config/plugin.xml"); + } + + BenchmarkModule bench = + ClassUtil.newInstance( + classname, new Object[] {wrkld}, new Class[] {WorkloadConfiguration.class}); + Map initDebug = new ListOrderedMap<>(); + initDebug.put("Benchmark", String.format("%s {%s}", plugin.toUpperCase(), classname)); + initDebug.put("Configuration", configFile); + initDebug.put("Type", wrkld.getDatabaseType()); + initDebug.put("Driver", wrkld.getDriverClass()); + initDebug.put("URL", wrkld.getUrl()); + initDebug.put("Isolation", wrkld.getIsolationString()); + initDebug.put("Batch Size", wrkld.getBatchSize()); + initDebug.put("Scale Factor", wrkld.getScaleFactor()); + initDebug.put("Terminals", wrkld.getTerminals()); + initDebug.put("New Connection Per Txn", wrkld.getNewConnectionPerTxn()); + + if (selectivity != -1) { + initDebug.put("Selectivity", selectivity); + } + + LOG.info("{}\n\n{}", SINGLE_LINE, StringUtil.formatMaps(initDebug)); + LOG.info(SINGLE_LINE); + + // ---------------------------------------------------------------- + // LOAD TRANSACTION DESCRIPTIONS + // ---------------------------------------------------------------- + int numTxnTypes = + xmlConfig.configurationsAt("transactiontypes" + pluginTest + "/transactiontype").size(); + if (numTxnTypes == 0 && targetList.length == 1) { + // if it is a single workload run, w/o attribute is used + pluginTest = "[not(@bench)]"; + numTxnTypes = + xmlConfig.configurationsAt("transactiontypes" + pluginTest + "/transactiontype").size(); + } + + List ttypes = new ArrayList<>(); + ttypes.add(TransactionType.INVALID); + int txnIdOffset = lastTxnId; + for (int i = 1; i <= numTxnTypes; i++) { + String key = "transactiontypes" + pluginTest + "/transactiontype[" + i + "]"; + String txnName = xmlConfig.getString(key + "/name"); + + // Get ID if specified; else increment from last one. + int txnId = i; + if (xmlConfig.containsKey(key + "/id")) { + txnId = xmlConfig.getInt(key + "/id"); } - // ------------------------------------------------------------------- - // GET PLUGIN LIST - // ------------------------------------------------------------------- - - String targetBenchmarks = argsLine.getOptionValue("b"); - - String[] targetList = targetBenchmarks.split(","); - List benchList = new ArrayList<>(); - - // Use this list for filtering of the output - List activeTXTypes = new ArrayList<>(); - - String configFile = argsLine.getOptionValue("c"); - - XMLConfiguration xmlConfig = buildConfiguration(configFile); - - // Load the configuration for each benchmark - int lastTxnId = 0; - for (String plugin : targetList) { - String pluginTest = "[@bench='" + plugin + "']"; - - // ---------------------------------------------------------------- - // BEGIN LOADING WORKLOAD CONFIGURATION - // ---------------------------------------------------------------- - - WorkloadConfiguration wrkld = new WorkloadConfiguration(); - wrkld.setBenchmarkName(plugin); - wrkld.setXmlConfig(xmlConfig); - - // Pull in database configuration - wrkld.setDatabaseType(DatabaseType.get(xmlConfig.getString("type"))); - wrkld.setDriverClass(xmlConfig.getString("driver")); - wrkld.setUrl(xmlConfig.getString("url")); - wrkld.setUsername(xmlConfig.getString("username")); - wrkld.setPassword(xmlConfig.getString("password")); - wrkld.setRandomSeed(xmlConfig.getInt("randomSeed", -1)); - wrkld.setBatchSize(xmlConfig.getInt("batchsize", 128)); - wrkld.setMaxRetries(xmlConfig.getInt("retries", 3)); - wrkld.setNewConnectionPerTxn(xmlConfig.getBoolean("newConnectionPerTxn", false)); - - int terminals = xmlConfig.getInt("terminals[not(@bench)]", 0); - terminals = xmlConfig.getInt("terminals" + pluginTest, terminals); - wrkld.setTerminals(terminals); - - if (xmlConfig.containsKey("loaderThreads")) { - int loaderThreads = xmlConfig.getInt("loaderThreads"); - wrkld.setLoaderThreads(loaderThreads); - } - - String isolationMode = xmlConfig.getString("isolation[not(@bench)]", "TRANSACTION_SERIALIZABLE"); - wrkld.setIsolationMode(xmlConfig.getString("isolation" + pluginTest, isolationMode)); - wrkld.setScaleFactor(xmlConfig.getDouble("scalefactor", 1.0)); - wrkld.setDataDir(xmlConfig.getString("datadir", ".")); - wrkld.setDDLPath(xmlConfig.getString("ddlpath", null)); - - double selectivity = -1; - try { - selectivity = xmlConfig.getDouble("selectivity"); - wrkld.setSelectivity(selectivity); - } catch (NoSuchElementException nse) { - // Nothing to do here ! - } - - // ---------------------------------------------------------------- - // CREATE BENCHMARK MODULE - // ---------------------------------------------------------------- - - String classname = pluginConfig.getString("/plugin[@name='" + plugin + "']"); - - if (classname == null) { - throw new ParseException("Plugin " + plugin + " is undefined in config/plugin.xml"); - } - - BenchmarkModule bench = ClassUtil.newInstance(classname, new Object[]{wrkld}, new Class[]{WorkloadConfiguration.class}); - Map initDebug = new ListOrderedMap<>(); - initDebug.put("Benchmark", String.format("%s {%s}", plugin.toUpperCase(), classname)); - initDebug.put("Configuration", configFile); - initDebug.put("Type", wrkld.getDatabaseType()); - initDebug.put("Driver", wrkld.getDriverClass()); - initDebug.put("URL", wrkld.getUrl()); - initDebug.put("Isolation", wrkld.getIsolationString()); - initDebug.put("Batch Size", wrkld.getBatchSize()); - initDebug.put("Scale Factor", wrkld.getScaleFactor()); - initDebug.put("Terminals", wrkld.getTerminals()); - initDebug.put("New Connection Per Txn", wrkld.getNewConnectionPerTxn()); - - if (selectivity != -1) { - initDebug.put("Selectivity", selectivity); - } - - LOG.info("{}\n\n{}", SINGLE_LINE, StringUtil.formatMaps(initDebug)); - LOG.info(SINGLE_LINE); - - // ---------------------------------------------------------------- - // LOAD TRANSACTION DESCRIPTIONS - // ---------------------------------------------------------------- - int numTxnTypes = xmlConfig.configurationsAt("transactiontypes" + pluginTest + "/transactiontype").size(); - if (numTxnTypes == 0 && targetList.length == 1) { - //if it is a single workload run, w/o attribute is used - pluginTest = "[not(@bench)]"; - numTxnTypes = xmlConfig.configurationsAt("transactiontypes" + pluginTest + "/transactiontype").size(); - } - - - List ttypes = new ArrayList<>(); - ttypes.add(TransactionType.INVALID); - int txnIdOffset = lastTxnId; - for (int i = 1; i <= numTxnTypes; i++) { - String key = "transactiontypes" + pluginTest + "/transactiontype[" + i + "]"; - String txnName = xmlConfig.getString(key + "/name"); - - // Get ID if specified; else increment from last one. - int txnId = i; - if (xmlConfig.containsKey(key + "/id")) { - txnId = xmlConfig.getInt(key + "/id"); - } - - long preExecutionWait = 0; - if (xmlConfig.containsKey(key + "/preExecutionWait")) { - preExecutionWait = xmlConfig.getLong(key + "/preExecutionWait"); - } - - long postExecutionWait = 0; - if (xmlConfig.containsKey(key + "/postExecutionWait")) { - postExecutionWait = xmlConfig.getLong(key + "/postExecutionWait"); - } - - // After load - if (xmlConfig.containsKey("afterload")) { - bench.setAfterLoadScriptPath(xmlConfig.getString("afterload")); - } - - TransactionType tmpType = bench.initTransactionType(txnName, txnId + txnIdOffset, preExecutionWait, postExecutionWait); + long preExecutionWait = 0; + if (xmlConfig.containsKey(key + "/preExecutionWait")) { + preExecutionWait = xmlConfig.getLong(key + "/preExecutionWait"); + } - // Keep a reference for filtering - activeTXTypes.add(tmpType); + long postExecutionWait = 0; + if (xmlConfig.containsKey(key + "/postExecutionWait")) { + postExecutionWait = xmlConfig.getLong(key + "/postExecutionWait"); + } - // Add a ref for the active TTypes in this benchmark - ttypes.add(tmpType); - lastTxnId = i; - } + // After load + if (xmlConfig.containsKey("afterload")) { + bench.setAfterLoadScriptPath(xmlConfig.getString("afterload")); + } - // Wrap the list of transactions and save them - TransactionTypes tt = new TransactionTypes(ttypes); - wrkld.setTransTypes(tt); - LOG.debug("Using the following transaction types: {}", tt); - - // Read in the groupings of transactions (if any) defined for this - // benchmark - int numGroupings = xmlConfig.configurationsAt("transactiontypes" + pluginTest + "/groupings/grouping").size(); - LOG.debug("Num groupings: {}", numGroupings); - for (int i = 1; i < numGroupings + 1; i++) { - String key = "transactiontypes" + pluginTest + "/groupings/grouping[" + i + "]"; - - // Get the name for the grouping and make sure it's valid. - String groupingName = xmlConfig.getString(key + "/name").toLowerCase(); - if (!groupingName.matches("^[a-z]\\w*$")) { - LOG.error(String.format("Grouping name \"%s\" is invalid." + " Must begin with a letter and contain only" + " alphanumeric characters.", groupingName)); - System.exit(-1); - } else if (groupingName.equals("all")) { - LOG.error("Grouping name \"all\" is reserved." + " Please pick a different name."); - System.exit(-1); - } - - // Get the weights for this grouping and make sure that there - // is an appropriate number of them. - List groupingWeights = Arrays.asList(xmlConfig.getString(key + "/weights").split("\\s*,\\s*")); - if (groupingWeights.size() != numTxnTypes) { - LOG.error(String.format("Grouping \"%s\" has %d weights," + " but there are %d transactions in this" + " benchmark.", groupingName, groupingWeights.size(), numTxnTypes)); - System.exit(-1); - } - - LOG.debug("Creating grouping with name, weights: {}, {}", groupingName, groupingWeights); - } + TransactionType tmpType = + bench.initTransactionType( + txnName, txnId + txnIdOffset, preExecutionWait, postExecutionWait); + + // Keep a reference for filtering + activeTXTypes.add(tmpType); + + // Add a ref for the active TTypes in this benchmark + ttypes.add(tmpType); + lastTxnId = i; + } + + // Wrap the list of transactions and save them + TransactionTypes tt = new TransactionTypes(ttypes); + wrkld.setTransTypes(tt); + LOG.debug("Using the following transaction types: {}", tt); + + // Read in the groupings of transactions (if any) defined for this + // benchmark + int numGroupings = + xmlConfig + .configurationsAt("transactiontypes" + pluginTest + "/groupings/grouping") + .size(); + LOG.debug("Num groupings: {}", numGroupings); + for (int i = 1; i < numGroupings + 1; i++) { + String key = "transactiontypes" + pluginTest + "/groupings/grouping[" + i + "]"; + + // Get the name for the grouping and make sure it's valid. + String groupingName = xmlConfig.getString(key + "/name").toLowerCase(); + if (!groupingName.matches("^[a-z]\\w*$")) { + LOG.error( + String.format( + "Grouping name \"%s\" is invalid." + + " Must begin with a letter and contain only" + + " alphanumeric characters.", + groupingName)); + System.exit(-1); + } else if (groupingName.equals("all")) { + LOG.error("Grouping name \"all\" is reserved." + " Please pick a different name."); + System.exit(-1); + } + // Get the weights for this grouping and make sure that there + // is an appropriate number of them. + List groupingWeights = + Arrays.asList(xmlConfig.getString(key + "/weights").split("\\s*,\\s*")); + if (groupingWeights.size() != numTxnTypes) { + LOG.error( + String.format( + "Grouping \"%s\" has %d weights," + + " but there are %d transactions in this" + + " benchmark.", + groupingName, groupingWeights.size(), numTxnTypes)); + System.exit(-1); + } - benchList.add(bench); - - // ---------------------------------------------------------------- - // WORKLOAD CONFIGURATION - // ---------------------------------------------------------------- - - int size = xmlConfig.configurationsAt("/works/work").size(); - for (int i = 1; i < size + 1; i++) { - final HierarchicalConfiguration work = xmlConfig.configurationAt("works/work[" + i + "]"); - List weight_strings; - - // use a workaround if there are multiple workloads or single - // attributed workload - if (targetList.length > 1 || work.containsKey("weights[@bench]")) { - weight_strings = Arrays.asList(work.getString("weights" + pluginTest).split("\\s*,\\s*")); - } else { - weight_strings = Arrays.asList(work.getString("weights[not(@bench)]").split("\\s*,\\s*")); - } - - double rate = 1; - boolean rateLimited = true; - boolean disabled = false; - boolean timed; - - // can be "disabled", "unlimited" or a number - String rate_string; - rate_string = work.getString("rate[not(@bench)]", ""); - rate_string = work.getString("rate" + pluginTest, rate_string); - if (rate_string.equals(RATE_DISABLED)) { - disabled = true; - } else if (rate_string.equals(RATE_UNLIMITED)) { - rateLimited = false; - } else if (rate_string.isEmpty()) { - LOG.error(String.format("Please specify the rate for phase %d and workload %s", i, plugin)); - System.exit(-1); - } else { - try { - rate = Double.parseDouble(rate_string); - if (rate <= 0) { - LOG.error("Rate limit must be at least 0. Use unlimited or disabled values instead."); - System.exit(-1); - } - } catch (NumberFormatException e) { - LOG.error(String.format("Rate string must be '%s', '%s' or a number", RATE_DISABLED, RATE_UNLIMITED)); - System.exit(-1); - } - } - Phase.Arrival arrival = Phase.Arrival.REGULAR; - String arrive = work.getString("@arrival", "regular"); - if (arrive.equalsIgnoreCase("POISSON")) { - arrival = Phase.Arrival.POISSON; - } - - // We now have the option to run all queries exactly once in - // a serial (rather than random) order. - boolean serial = Boolean.parseBoolean(work.getString("serial", Boolean.FALSE.toString())); - - - int activeTerminals; - activeTerminals = work.getInt("active_terminals[not(@bench)]", terminals); - activeTerminals = work.getInt("active_terminals" + pluginTest, activeTerminals); - // If using serial, we should have only one terminal - if (serial && activeTerminals != 1) { - LOG.warn("Serial ordering is enabled, so # of active terminals is clamped to 1."); - activeTerminals = 1; - } - if (activeTerminals > terminals) { - LOG.error(String.format("Configuration error in work %d: " + "Number of active terminals is bigger than the total number of terminals", i)); - System.exit(-1); - } - - int time = work.getInt("/time", 0); - int warmup = work.getInt("/warmup", 0); - timed = (time > 0); - if (!timed) { - if (serial) { - LOG.info("Timer disabled for serial run; will execute" + " all queries exactly once."); - } else { - LOG.error("Must provide positive time bound for" + " non-serial executions. Either provide" + " a valid time or enable serial mode."); - System.exit(-1); - } - } else if (serial) { - LOG.info("Timer enabled for serial run; will run queries" + " serially in a loop until the timer expires."); - } - if (warmup < 0) { - LOG.error("Must provide non-negative time bound for" + " warmup."); - System.exit(-1); - } - - ArrayList weights = new ArrayList<>(); - - double totalWeight = 0; - - for (String weightString : weight_strings) { - double weight = Double.parseDouble(weightString); - totalWeight += weight; - weights.add(weight); - } - - long roundedWeight = Math.round(totalWeight); - - if (roundedWeight != 100) { - LOG.warn("rounded weight [{}] does not equal 100. Original weight is [{}]", roundedWeight, totalWeight); - } - - - wrkld.addPhase(i, time, warmup, rate, weights, rateLimited, disabled, serial, timed, activeTerminals, arrival); - } + LOG.debug("Creating grouping with name, weights: {}, {}", groupingName, groupingWeights); + } - // CHECKING INPUT PHASES - int j = 0; - for (Phase p : wrkld.getPhases()) { - j++; - if (p.getWeightCount() != numTxnTypes) { - LOG.error(String.format("Configuration files is inconsistent, phase %d contains %d weights but you defined %d transaction types", j, p.getWeightCount(), numTxnTypes)); - if (p.isSerial()) { - LOG.error("However, note that since this a serial phase, the weights are irrelevant (but still must be included---sorry)."); - } - System.exit(-1); - } - } + benchList.add(bench); - // Generate the dialect map - wrkld.init(); + // ---------------------------------------------------------------- + // WORKLOAD CONFIGURATION + // ---------------------------------------------------------------- + int size = xmlConfig.configurationsAt("/works/work").size(); + for (int i = 1; i < size + 1; i++) { + final HierarchicalConfiguration work = + xmlConfig.configurationAt("works/work[" + i + "]"); + List weight_strings; + // use a workaround if there are multiple workloads or single + // attributed workload + if (targetList.length > 1 || work.containsKey("weights[@bench]")) { + weight_strings = Arrays.asList(work.getString("weights" + pluginTest).split("\\s*,\\s*")); + } else { + weight_strings = Arrays.asList(work.getString("weights[not(@bench)]").split("\\s*,\\s*")); } - - // Export StatementDialects - if (isBooleanOptionSet(argsLine, "dialects-export")) { - BenchmarkModule bench = benchList.get(0); - if (bench.getStatementDialects() != null) { - LOG.info("Exporting StatementDialects for {}", bench); - String xml = bench.getStatementDialects().export(bench.getWorkloadConfiguration().getDatabaseType(), bench.getProcedures().values()); - LOG.debug(xml); - System.exit(0); + double rate = 1; + boolean rateLimited = true; + boolean disabled = false; + boolean timed; + + // can be "disabled", "unlimited" or a number + String rate_string; + rate_string = work.getString("rate[not(@bench)]", ""); + rate_string = work.getString("rate" + pluginTest, rate_string); + if (rate_string.equals(RATE_DISABLED)) { + disabled = true; + } else if (rate_string.equals(RATE_UNLIMITED)) { + rateLimited = false; + } else if (rate_string.isEmpty()) { + LOG.error( + String.format("Please specify the rate for phase %d and workload %s", i, plugin)); + System.exit(-1); + } else { + try { + rate = Double.parseDouble(rate_string); + if (rate <= 0) { + LOG.error("Rate limit must be at least 0. Use unlimited or disabled values instead."); + System.exit(-1); } - throw new RuntimeException("No StatementDialects is available for " + bench); + } catch (NumberFormatException e) { + LOG.error( + String.format( + "Rate string must be '%s', '%s' or a number", RATE_DISABLED, RATE_UNLIMITED)); + System.exit(-1); + } } - - // Create the Benchmark's Database - if (isBooleanOptionSet(argsLine, "create")) { - try { - for (BenchmarkModule benchmark : benchList) { - LOG.info("Creating new {} database...", benchmark.getBenchmarkName().toUpperCase()); - runCreator(benchmark); - LOG.info("Finished creating new {} database...", benchmark.getBenchmarkName().toUpperCase()); - } - } catch (Throwable ex) { - LOG.error("Unexpected error when creating benchmark database tables.", ex); - System.exit(1); - } - } else { - LOG.debug("Skipping creating benchmark database tables"); + Phase.Arrival arrival = Phase.Arrival.REGULAR; + String arrive = work.getString("@arrival", "regular"); + if (arrive.equalsIgnoreCase("POISSON")) { + arrival = Phase.Arrival.POISSON; } - // Refresh the catalog. - for (BenchmarkModule benchmark : benchList) { - benchmark.refreshCatalog(); + // We now have the option to run all queries exactly once in + // a serial (rather than random) order. + boolean serial = Boolean.parseBoolean(work.getString("serial", Boolean.FALSE.toString())); + + int activeTerminals; + activeTerminals = work.getInt("active_terminals[not(@bench)]", terminals); + activeTerminals = work.getInt("active_terminals" + pluginTest, activeTerminals); + // If using serial, we should have only one terminal + if (serial && activeTerminals != 1) { + LOG.warn("Serial ordering is enabled, so # of active terminals is clamped to 1."); + activeTerminals = 1; } - - // Clear the Benchmark's Database - if (isBooleanOptionSet(argsLine, "clear")) { - try { - for (BenchmarkModule benchmark : benchList) { - LOG.info("Clearing {} database...", benchmark.getBenchmarkName().toUpperCase()); - benchmark.refreshCatalog(); - benchmark.clearDatabase(); - benchmark.refreshCatalog(); - LOG.info("Finished clearing {} database...", benchmark.getBenchmarkName().toUpperCase()); - } - } catch (Throwable ex) { - LOG.error("Unexpected error when clearing benchmark database tables.", ex); - System.exit(1); - } - } else { - LOG.debug("Skipping clearing benchmark database tables"); + if (activeTerminals > terminals) { + LOG.error( + String.format( + "Configuration error in work %d: " + + "Number of active terminals is bigger than the total number of terminals", + i)); + System.exit(-1); } - // Execute Loader - if (isBooleanOptionSet(argsLine, "load")) { - try { - for (BenchmarkModule benchmark : benchList) { - LOG.info("Loading data into {} database...", benchmark.getBenchmarkName().toUpperCase()); - runLoader(benchmark); - LOG.info("Finished loading data into {} database...", benchmark.getBenchmarkName().toUpperCase()); - } - } catch (Throwable ex) { - LOG.error("Unexpected error when loading benchmark database records.", ex); - System.exit(1); - } - - } else { - LOG.debug("Skipping loading benchmark database records"); + int time = work.getInt("/time", 0); + int warmup = work.getInt("/warmup", 0); + timed = (time > 0); + if (!timed) { + if (serial) { + LOG.info("Timer disabled for serial run; will execute" + " all queries exactly once."); + } else { + LOG.error( + "Must provide positive time bound for" + + " non-serial executions. Either provide" + + " a valid time or enable serial mode."); + System.exit(-1); + } + } else if (serial) { + LOG.info( + "Timer enabled for serial run; will run queries" + + " serially in a loop until the timer expires."); } - - // Execute Workload - if (isBooleanOptionSet(argsLine, "execute")) { - // Bombs away! - try { - Results r = runWorkload(benchList, intervalMonitor); - writeOutputs(r, activeTXTypes, argsLine, xmlConfig); - writeHistograms(r); - - if (argsLine.hasOption("json-histograms")) { - String histogram_json = writeJSONHistograms(r); - String fileName = argsLine.getOptionValue("json-histograms"); - FileUtil.writeStringToFile(new File(fileName), histogram_json); - LOG.info("Histograms JSON Data: " + fileName); - } - } catch (Throwable ex) { - LOG.error("Unexpected error when executing benchmarks.", ex); - System.exit(1); - } - - } else { - LOG.info("Skipping benchmark workload execution"); + if (warmup < 0) { + LOG.error("Must provide non-negative time bound for" + " warmup."); + System.exit(-1); } - } - - private static Options buildOptions(XMLConfiguration pluginConfig) { - Options options = new Options(); - options.addOption("b", "bench", true, "[required] Benchmark class. Currently supported: " + pluginConfig.getList("/plugin//@name")); - options.addOption("c", "config", true, "[required] Workload configuration file"); - options.addOption(null, "create", true, "Initialize the database for this benchmark"); - options.addOption(null, "clear", true, "Clear all records in the database for this benchmark"); - options.addOption(null, "load", true, "Load data using the benchmark's data loader"); - options.addOption(null, "execute", true, "Execute the benchmark workload"); - options.addOption("h", "help", false, "Print this help"); - options.addOption("s", "sample", true, "Sampling window"); - options.addOption("im", "interval-monitor", true, "Throughput Monitoring Interval in milliseconds"); - options.addOption("d", "directory", true, "Base directory for the result files, default is current directory"); - options.addOption(null, "dialects-export", true, "Export benchmark SQL to a dialects file"); - options.addOption("jh", "json-histograms", true, "Export histograms to JSON file"); - return options; - } - - public static XMLConfiguration buildConfiguration(String filename) throws ConfigurationException { - Parameters params = new Parameters(); - FileBasedConfigurationBuilder builder = new FileBasedConfigurationBuilder<>(XMLConfiguration.class) - .configure(params.xml() - .setFileName(filename) - .setListDelimiterHandler(new DisabledListDelimiterHandler()) - .setExpressionEngine(new XPathExpressionEngine())); - return builder.getConfiguration(); - } - private static void writeHistograms(Results r) { - StringBuilder sb = new StringBuilder(); - sb.append("\n"); + ArrayList weights = new ArrayList<>(); - sb.append(StringUtil.bold("Completed Transactions:")).append("\n").append(r.getSuccess()).append("\n\n"); + double totalWeight = 0; - sb.append(StringUtil.bold("Aborted Transactions:")).append("\n").append(r.getAbort()).append("\n\n"); - - sb.append(StringUtil.bold("Rejected Transactions (Server Retry):")).append("\n").append(r.getRetry()).append("\n\n"); - - sb.append(StringUtil.bold("Rejected Transactions (Retry Different):")).append("\n").append(r.getRetryDifferent()).append("\n\n"); + for (String weightString : weight_strings) { + double weight = Double.parseDouble(weightString); + totalWeight += weight; + weights.add(weight); + } - sb.append(StringUtil.bold("Unexpected SQL Errors:")).append("\n").append(r.getError()).append("\n\n"); + long roundedWeight = Math.round(totalWeight); - sb.append(StringUtil.bold("Unknown Status Transactions:")).append("\n").append(r.getUnknown()).append("\n\n"); + if (roundedWeight != 100) { + LOG.warn( + "rounded weight [{}] does not equal 100. Original weight is [{}]", + roundedWeight, + totalWeight); + } - if (!r.getAbortMessages().isEmpty()) { - sb.append("\n\n").append(StringUtil.bold("User Aborts:")).append("\n").append(r.getAbortMessages()); + wrkld.addPhase( + i, + time, + warmup, + rate, + weights, + rateLimited, + disabled, + serial, + timed, + activeTerminals, + arrival); + } + + // CHECKING INPUT PHASES + int j = 0; + for (Phase p : wrkld.getPhases()) { + j++; + if (p.getWeightCount() != numTxnTypes) { + LOG.error( + String.format( + "Configuration files is inconsistent, phase %d contains %d weights but you defined %d transaction types", + j, p.getWeightCount(), numTxnTypes)); + if (p.isSerial()) { + LOG.error( + "However, note that since this a serial phase, the weights are irrelevant (but still must be included---sorry)."); + } + System.exit(-1); } + } - LOG.info(SINGLE_LINE); - LOG.info("Workload Histograms:\n{}", sb); - LOG.info(SINGLE_LINE); + // Generate the dialect map + wrkld.init(); } - private static String writeJSONHistograms(Results r) { - Map map = new HashMap<>(); - map.put("completed", r.getSuccess()); - map.put("aborted", r.getAbort()); - map.put("rejected", r.getRetry()); - map.put("unexpected", r.getError()); - return JSONUtil.toJSONString(map); + // Export StatementDialects + if (isBooleanOptionSet(argsLine, "dialects-export")) { + BenchmarkModule bench = benchList.get(0); + if (bench.getStatementDialects() != null) { + LOG.info("Exporting StatementDialects for {}", bench); + String xml = + bench + .getStatementDialects() + .export( + bench.getWorkloadConfiguration().getDatabaseType(), + bench.getProcedures().values()); + LOG.debug(xml); + System.exit(0); + } + throw new RuntimeException("No StatementDialects is available for " + bench); } - /** - * Write out the results for a benchmark run to a bunch of files - * - * @param r - * @param activeTXTypes - * @param argsLine - * @param xmlConfig - * @throws Exception - */ - private static void writeOutputs(Results r, List activeTXTypes, CommandLine argsLine, XMLConfiguration xmlConfig) throws Exception { - - // If an output directory is used, store the information - String outputDirectory = "results"; - - if (argsLine.hasOption("d")) { - outputDirectory = argsLine.getOptionValue("d"); + // Create the Benchmark's Database + if (isBooleanOptionSet(argsLine, "create")) { + try { + for (BenchmarkModule benchmark : benchList) { + LOG.info("Creating new {} database...", benchmark.getBenchmarkName().toUpperCase()); + runCreator(benchmark); + LOG.info( + "Finished creating new {} database...", benchmark.getBenchmarkName().toUpperCase()); } + } catch (Throwable ex) { + LOG.error("Unexpected error when creating benchmark database tables.", ex); + System.exit(1); + } + } else { + LOG.debug("Skipping creating benchmark database tables"); + } + // Refresh the catalog. + for (BenchmarkModule benchmark : benchList) { + benchmark.refreshCatalog(); + } - FileUtil.makeDirIfNotExists(outputDirectory); - ResultWriter rw = new ResultWriter(r, xmlConfig, argsLine); - - String name = StringUtils.join(StringUtils.split(argsLine.getOptionValue("b"), ','), '-'); - - String baseFileName = name + "_" + TimeUtil.getCurrentTimeString(); - - int windowSize = Integer.parseInt(argsLine.getOptionValue("s", "5")); - - String rawFileName = baseFileName + ".raw.csv"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, rawFileName))) { - LOG.info("Output Raw data into file: {}", rawFileName); - rw.writeRaw(activeTXTypes, ps); + // Clear the Benchmark's Database + if (isBooleanOptionSet(argsLine, "clear")) { + try { + for (BenchmarkModule benchmark : benchList) { + LOG.info("Clearing {} database...", benchmark.getBenchmarkName().toUpperCase()); + benchmark.refreshCatalog(); + benchmark.clearDatabase(); + benchmark.refreshCatalog(); + LOG.info("Finished clearing {} database...", benchmark.getBenchmarkName().toUpperCase()); } + } catch (Throwable ex) { + LOG.error("Unexpected error when clearing benchmark database tables.", ex); + System.exit(1); + } + } else { + LOG.debug("Skipping clearing benchmark database tables"); + } - String sampleFileName = baseFileName + ".samples.csv"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, sampleFileName))) { - LOG.info("Output samples into file: {}", sampleFileName); - rw.writeSamples(ps); + // Execute Loader + if (isBooleanOptionSet(argsLine, "load")) { + try { + for (BenchmarkModule benchmark : benchList) { + LOG.info("Loading data into {} database...", benchmark.getBenchmarkName().toUpperCase()); + runLoader(benchmark); + LOG.info( + "Finished loading data into {} database...", + benchmark.getBenchmarkName().toUpperCase()); } + } catch (Throwable ex) { + LOG.error("Unexpected error when loading benchmark database records.", ex); + System.exit(1); + } - String summaryFileName = baseFileName + ".summary.json"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, summaryFileName))) { - LOG.info("Output summary data into file: {}", summaryFileName); - rw.writeSummary(ps); - } + } else { + LOG.debug("Skipping loading benchmark database records"); + } - String paramsFileName = baseFileName + ".params.json"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, paramsFileName))) { - LOG.info("Output DBMS parameters into file: {}", paramsFileName); - rw.writeParams(ps); + // Execute Workload + if (isBooleanOptionSet(argsLine, "execute")) { + // Bombs away! + try { + Results r = runWorkload(benchList, intervalMonitor); + writeOutputs(r, activeTXTypes, argsLine, xmlConfig); + writeHistograms(r); + + if (argsLine.hasOption("json-histograms")) { + String histogram_json = writeJSONHistograms(r); + String fileName = argsLine.getOptionValue("json-histograms"); + FileUtil.writeStringToFile(new File(fileName), histogram_json); + LOG.info("Histograms JSON Data: " + fileName); } + } catch (Throwable ex) { + LOG.error("Unexpected error when executing benchmarks.", ex); + System.exit(1); + } - if (rw.hasMetrics()) { - String metricsFileName = baseFileName + ".metrics.json"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, metricsFileName))) { - LOG.info("Output DBMS metrics into file: {}", metricsFileName); - rw.writeMetrics(ps); - } - } + } else { + LOG.info("Skipping benchmark workload execution"); + } + } + + private static Options buildOptions(XMLConfiguration pluginConfig) { + Options options = new Options(); + options.addOption( + "b", + "bench", + true, + "[required] Benchmark class. Currently supported: " + + pluginConfig.getList("/plugin//@name")); + options.addOption("c", "config", true, "[required] Workload configuration file"); + options.addOption(null, "create", true, "Initialize the database for this benchmark"); + options.addOption(null, "clear", true, "Clear all records in the database for this benchmark"); + options.addOption(null, "load", true, "Load data using the benchmark's data loader"); + options.addOption(null, "execute", true, "Execute the benchmark workload"); + options.addOption("h", "help", false, "Print this help"); + options.addOption("s", "sample", true, "Sampling window"); + options.addOption( + "im", "interval-monitor", true, "Throughput Monitoring Interval in milliseconds"); + options.addOption( + "d", + "directory", + true, + "Base directory for the result files, default is current directory"); + options.addOption(null, "dialects-export", true, "Export benchmark SQL to a dialects file"); + options.addOption("jh", "json-histograms", true, "Export histograms to JSON file"); + return options; + } + + public static XMLConfiguration buildConfiguration(String filename) throws ConfigurationException { + Parameters params = new Parameters(); + FileBasedConfigurationBuilder builder = + new FileBasedConfigurationBuilder<>(XMLConfiguration.class) + .configure( + params + .xml() + .setFileName(filename) + .setListDelimiterHandler(new DisabledListDelimiterHandler()) + .setExpressionEngine(new XPathExpressionEngine())); + return builder.getConfiguration(); + } + + private static void writeHistograms(Results r) { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + + sb.append(StringUtil.bold("Completed Transactions:")) + .append("\n") + .append(r.getSuccess()) + .append("\n\n"); + + sb.append(StringUtil.bold("Aborted Transactions:")) + .append("\n") + .append(r.getAbort()) + .append("\n\n"); + + sb.append(StringUtil.bold("Rejected Transactions (Server Retry):")) + .append("\n") + .append(r.getRetry()) + .append("\n\n"); + + sb.append(StringUtil.bold("Rejected Transactions (Retry Different):")) + .append("\n") + .append(r.getRetryDifferent()) + .append("\n\n"); + + sb.append(StringUtil.bold("Unexpected SQL Errors:")) + .append("\n") + .append(r.getError()) + .append("\n\n"); + + sb.append(StringUtil.bold("Unknown Status Transactions:")) + .append("\n") + .append(r.getUnknown()) + .append("\n\n"); + + if (!r.getAbortMessages().isEmpty()) { + sb.append("\n\n") + .append(StringUtil.bold("User Aborts:")) + .append("\n") + .append(r.getAbortMessages()); + } - String configFileName = baseFileName + ".config.xml"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, configFileName))) { - LOG.info("Output benchmark config into file: {}", configFileName); - rw.writeConfig(ps); - } + LOG.info(SINGLE_LINE); + LOG.info("Workload Histograms:\n{}", sb); + LOG.info(SINGLE_LINE); + } + + private static String writeJSONHistograms(Results r) { + Map map = new HashMap<>(); + map.put("completed", r.getSuccess()); + map.put("aborted", r.getAbort()); + map.put("rejected", r.getRetry()); + map.put("unexpected", r.getError()); + return JSONUtil.toJSONString(map); + } + + /** + * Write out the results for a benchmark run to a bunch of files + * + * @param r + * @param activeTXTypes + * @param argsLine + * @param xmlConfig + * @throws Exception + */ + private static void writeOutputs( + Results r, + List activeTXTypes, + CommandLine argsLine, + XMLConfiguration xmlConfig) + throws Exception { + + // If an output directory is used, store the information + String outputDirectory = "results"; + + if (argsLine.hasOption("d")) { + outputDirectory = argsLine.getOptionValue("d"); + } - String resultsFileName = baseFileName + ".results.csv"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, resultsFileName))) { - LOG.info("Output results into file: {} with window size {}", resultsFileName, windowSize); - rw.writeResults(windowSize, ps); - } + FileUtil.makeDirIfNotExists(outputDirectory); + ResultWriter rw = new ResultWriter(r, xmlConfig, argsLine); - for (TransactionType t : activeTXTypes) { - String fileName = baseFileName + ".results." + t.getName() + ".csv"; - try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, fileName))) { - rw.writeResults(windowSize, ps, t); - } - } + String name = StringUtils.join(StringUtils.split(argsLine.getOptionValue("b"), ','), '-'); + + String baseFileName = name + "_" + TimeUtil.getCurrentTimeString(); + + int windowSize = Integer.parseInt(argsLine.getOptionValue("s", "5")); + String rawFileName = baseFileName + ".raw.csv"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, rawFileName))) { + LOG.info("Output Raw data into file: {}", rawFileName); + rw.writeRaw(activeTXTypes, ps); } - private static void runCreator(BenchmarkModule bench) throws SQLException, IOException { - LOG.debug(String.format("Creating %s Database", bench)); - bench.createDatabase(); + String sampleFileName = baseFileName + ".samples.csv"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, sampleFileName))) { + LOG.info("Output samples into file: {}", sampleFileName); + rw.writeSamples(ps); } - private static void runLoader(BenchmarkModule bench) throws IOException, SQLException, InterruptedException { - LOG.debug(String.format("Loading %s Database", bench)); - bench.loadDatabase(); + String summaryFileName = baseFileName + ".summary.json"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, summaryFileName))) { + LOG.info("Output summary data into file: {}", summaryFileName); + rw.writeSummary(ps); } - private static Results runWorkload(List benchList, int intervalMonitor) throws IOException { - List> workers = new ArrayList<>(); - List workConfs = new ArrayList<>(); - for (BenchmarkModule bench : benchList) { - LOG.info("Creating {} virtual terminals...", bench.getWorkloadConfiguration().getTerminals()); - workers.addAll(bench.makeWorkers()); + String paramsFileName = baseFileName + ".params.json"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, paramsFileName))) { + LOG.info("Output DBMS parameters into file: {}", paramsFileName); + rw.writeParams(ps); + } - int num_phases = bench.getWorkloadConfiguration().getNumberOfPhases(); - LOG.info(String.format("Launching the %s Benchmark with %s Phase%s...", bench.getBenchmarkName().toUpperCase(), num_phases, (num_phases > 1 ? "s" : ""))); - workConfs.add(bench.getWorkloadConfiguration()); + if (rw.hasMetrics()) { + String metricsFileName = baseFileName + ".metrics.json"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, metricsFileName))) { + LOG.info("Output DBMS metrics into file: {}", metricsFileName); + rw.writeMetrics(ps); + } + } - } - Results r = ThreadBench.runRateLimitedBenchmark(workers, workConfs, intervalMonitor); - LOG.info(SINGLE_LINE); - LOG.info("Rate limited reqs/s: {}", r); - return r; + String configFileName = baseFileName + ".config.xml"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, configFileName))) { + LOG.info("Output benchmark config into file: {}", configFileName); + rw.writeConfig(ps); } - private static void printUsage(Options options) { - HelpFormatter hlpfrmt = new HelpFormatter(); - hlpfrmt.printHelp("benchbase", options); + String resultsFileName = baseFileName + ".results.csv"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, resultsFileName))) { + LOG.info("Output results into file: {} with window size {}", resultsFileName, windowSize); + rw.writeResults(windowSize, ps); } - /** - * Returns true if the given key is in the CommandLine object and is set to - * true. - * - * @param argsLine - * @param key - * @return - */ - private static boolean isBooleanOptionSet(CommandLine argsLine, String key) { - if (argsLine.hasOption(key)) { - LOG.debug("CommandLine has option '{}'. Checking whether set to true", key); - String val = argsLine.getOptionValue(key); - LOG.debug(String.format("CommandLine %s => %s", key, val)); - return (val != null && val.equalsIgnoreCase("true")); - } - return (false); + for (TransactionType t : activeTXTypes) { + String fileName = baseFileName + ".results." + t.getName() + ".csv"; + try (PrintStream ps = new PrintStream(FileUtil.joinPath(outputDirectory, fileName))) { + rw.writeResults(windowSize, ps, t); + } + } + } + + private static void runCreator(BenchmarkModule bench) throws SQLException, IOException { + LOG.debug(String.format("Creating %s Database", bench)); + bench.createDatabase(); + } + + private static void runLoader(BenchmarkModule bench) + throws IOException, SQLException, InterruptedException { + LOG.debug(String.format("Loading %s Database", bench)); + bench.loadDatabase(); + } + + private static Results runWorkload(List benchList, int intervalMonitor) + throws IOException { + List> workers = new ArrayList<>(); + List workConfs = new ArrayList<>(); + for (BenchmarkModule bench : benchList) { + LOG.info("Creating {} virtual terminals...", bench.getWorkloadConfiguration().getTerminals()); + workers.addAll(bench.makeWorkers()); + + int num_phases = bench.getWorkloadConfiguration().getNumberOfPhases(); + LOG.info( + String.format( + "Launching the %s Benchmark with %s Phase%s...", + bench.getBenchmarkName().toUpperCase(), num_phases, (num_phases > 1 ? "s" : ""))); + workConfs.add(bench.getWorkloadConfiguration()); + } + Results r = ThreadBench.runRateLimitedBenchmark(workers, workConfs, intervalMonitor); + LOG.info(SINGLE_LINE); + LOG.info("Rate limited reqs/s: {}", r); + return r; + } + + private static void printUsage(Options options) { + HelpFormatter hlpfrmt = new HelpFormatter(); + hlpfrmt.printHelp("benchbase", options); + } + + /** + * Returns true if the given key is in the CommandLine object and is set to true. + * + * @param argsLine + * @param key + * @return + */ + private static boolean isBooleanOptionSet(CommandLine argsLine, String key) { + if (argsLine.hasOption(key)) { + LOG.debug("CommandLine has option '{}'. Checking whether set to true", key); + String val = argsLine.getOptionValue(key); + LOG.debug(String.format("CommandLine %s => %s", key, val)); + return (val != null && val.equalsIgnoreCase("true")); } + return (false); + } } diff --git a/src/main/java/com/oltpbenchmark/DistributionStatistics.java b/src/main/java/com/oltpbenchmark/DistributionStatistics.java index e672801e4..b5ad94414 100644 --- a/src/main/java/com/oltpbenchmark/DistributionStatistics.java +++ b/src/main/java/com/oltpbenchmark/DistributionStatistics.java @@ -15,157 +15,171 @@ * */ - package com.oltpbenchmark; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DistributionStatistics { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(DistributionStatistics.class); - - private static final double[] PERCENTILES = {0.0, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99, 1.0}; - - private static final int MINIMUM = 0; - private static final int PERCENTILE_25TH = 1; - private static final int MEDIAN = 2; - private static final int PERCENTILE_75TH = 3; - private static final int PERCENTILE_90TH = 4; - private static final int PERCENTILE_95TH = 5; - private static final int PERCENTILE_99TH = 6; - private static final int MAXIMUM = 7; - - private final int count; - private final long[] percentiles; - private final double average; - private final double standardDeviation; - - public DistributionStatistics(int count, long[] percentiles, double average, double standardDeviation) { - this.count = count; - this.percentiles = Arrays.copyOfRange(percentiles, 0, PERCENTILES.length); - this.average = average; - this.standardDeviation = standardDeviation; + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(DistributionStatistics.class); + + private static final double[] PERCENTILES = {0.0, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99, 1.0}; + + private static final int MINIMUM = 0; + private static final int PERCENTILE_25TH = 1; + private static final int MEDIAN = 2; + private static final int PERCENTILE_75TH = 3; + private static final int PERCENTILE_90TH = 4; + private static final int PERCENTILE_95TH = 5; + private static final int PERCENTILE_99TH = 6; + private static final int MAXIMUM = 7; + + private final int count; + private final long[] percentiles; + private final double average; + private final double standardDeviation; + + public DistributionStatistics( + int count, long[] percentiles, double average, double standardDeviation) { + this.count = count; + this.percentiles = Arrays.copyOfRange(percentiles, 0, PERCENTILES.length); + this.average = average; + this.standardDeviation = standardDeviation; + } + + /** Computes distribution statistics over values. WARNING: This will sort values. */ + public static DistributionStatistics computeStatistics(int[] valuesAsMicroseconds) { + if (valuesAsMicroseconds.length == 0) { + long[] percentiles = new long[PERCENTILES.length]; + Arrays.fill(percentiles, -1); + return new DistributionStatistics(0, percentiles, -1, -1); } - /** - * Computes distribution statistics over values. WARNING: This will sort - * values. - */ - public static DistributionStatistics computeStatistics(int[] valuesAsMicroseconds) { - if (valuesAsMicroseconds.length == 0) { - long[] percentiles = new long[PERCENTILES.length]; - Arrays.fill(percentiles, -1); - return new DistributionStatistics(0, percentiles, -1, -1); - } - - Arrays.sort(valuesAsMicroseconds); - - double sum = 0; - for (int value1 : valuesAsMicroseconds) { - sum += value1; - } - double average = sum / valuesAsMicroseconds.length; - - double sumDiffsSquared = 0; - for (int value : valuesAsMicroseconds) { - double v = value - average; - sumDiffsSquared += v * v; - } - double standardDeviation = 0; - if (valuesAsMicroseconds.length > 1) { - standardDeviation = Math - .sqrt(sumDiffsSquared / (valuesAsMicroseconds.length - 1)); - } - - // NOTE: NIST recommends interpolating. This just selects the closest - // value, which is described as another common technique. - // http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm - long[] percentiles = new long[PERCENTILES.length]; - for (int i = 0; i < percentiles.length; ++i) { - int index = (int) (PERCENTILES[i] * valuesAsMicroseconds.length); - if (index == valuesAsMicroseconds.length) { - index = valuesAsMicroseconds.length - 1; - } - percentiles[i] = valuesAsMicroseconds[index]; - } - - return new DistributionStatistics(valuesAsMicroseconds.length, percentiles, average, standardDeviation); - } + Arrays.sort(valuesAsMicroseconds); - public int getCount() { - return count; + double sum = 0; + for (int value1 : valuesAsMicroseconds) { + sum += value1; } + double average = sum / valuesAsMicroseconds.length; - public double getAverage() { - return average; + double sumDiffsSquared = 0; + for (int value : valuesAsMicroseconds) { + double v = value - average; + sumDiffsSquared += v * v; } - - public double getStandardDeviation() { - return standardDeviation; - } - - public double getMinimum() { - return percentiles[MINIMUM]; + double standardDeviation = 0; + if (valuesAsMicroseconds.length > 1) { + standardDeviation = Math.sqrt(sumDiffsSquared / (valuesAsMicroseconds.length - 1)); } - public double get25thPercentile() { - return percentiles[PERCENTILE_25TH]; + // NOTE: NIST recommends interpolating. This just selects the closest + // value, which is described as another common technique. + // http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm + long[] percentiles = new long[PERCENTILES.length]; + for (int i = 0; i < percentiles.length; ++i) { + int index = (int) (PERCENTILES[i] * valuesAsMicroseconds.length); + if (index == valuesAsMicroseconds.length) { + index = valuesAsMicroseconds.length - 1; + } + percentiles[i] = valuesAsMicroseconds[index]; } - public double getMedian() { - return percentiles[MEDIAN]; - } - - public double get75thPercentile() { - return percentiles[PERCENTILE_75TH]; - } - - public double get90thPercentile() { - return percentiles[PERCENTILE_90TH]; - } - - public double get95thPercentile() { - return percentiles[PERCENTILE_95TH]; - } - - public double get99thPercentile() { - return percentiles[PERCENTILE_99TH]; - } - - public double getMaximum() { - return percentiles[MAXIMUM]; - } - - @Override - public String toString() { - return "in milliseconds [min=" + TimeUnit.MICROSECONDS.toMillis((long) getMinimum()) + ", " - + "25th=" + TimeUnit.MICROSECONDS.toMillis((long) get25thPercentile()) + ", " - + "median=" + TimeUnit.MICROSECONDS.toMillis((long) getMedian()) + ", " - + "avg=" + TimeUnit.MICROSECONDS.toMillis((long) getAverage()) + ", " - + "75th=" + TimeUnit.MICROSECONDS.toMillis((long) get75thPercentile()) + ", " - + "90th=" + TimeUnit.MICROSECONDS.toMillis((long) get90thPercentile()) + ", " - + "95th=" + TimeUnit.MICROSECONDS.toMillis((long) get95thPercentile()) + ", " - + "99th=" + TimeUnit.MICROSECONDS.toMillis((long) get99thPercentile()) + ", " - + "max=" + TimeUnit.MICROSECONDS.toMillis((long) getMaximum()) + "]"; - } - - public Map toMap() { - Map distMap = new LinkedHashMap<>(); - distMap.put("Minimum Latency (microseconds)", (int) getMinimum()); - distMap.put("25th Percentile Latency (microseconds)", (int) get25thPercentile()); - distMap.put("Median Latency (microseconds)", (int) getMedian()); - distMap.put("Average Latency (microseconds)", (int) getAverage()); - distMap.put("75th Percentile Latency (microseconds)", (int) get75thPercentile()); - distMap.put("90th Percentile Latency (microseconds)", (int) get90thPercentile()); - distMap.put("95th Percentile Latency (microseconds)", (int) get95thPercentile()); - distMap.put("99th Percentile Latency (microseconds)", (int) get99thPercentile()); - distMap.put("Maximum Latency (microseconds)", (int) getMaximum()); - return distMap; - } + return new DistributionStatistics( + valuesAsMicroseconds.length, percentiles, average, standardDeviation); + } + + public int getCount() { + return count; + } + + public double getAverage() { + return average; + } + + public double getStandardDeviation() { + return standardDeviation; + } + + public double getMinimum() { + return percentiles[MINIMUM]; + } + + public double get25thPercentile() { + return percentiles[PERCENTILE_25TH]; + } + + public double getMedian() { + return percentiles[MEDIAN]; + } + + public double get75thPercentile() { + return percentiles[PERCENTILE_75TH]; + } + + public double get90thPercentile() { + return percentiles[PERCENTILE_90TH]; + } + + public double get95thPercentile() { + return percentiles[PERCENTILE_95TH]; + } + + public double get99thPercentile() { + return percentiles[PERCENTILE_99TH]; + } + + public double getMaximum() { + return percentiles[MAXIMUM]; + } + + @Override + public String toString() { + return "in milliseconds [min=" + + TimeUnit.MICROSECONDS.toMillis((long) getMinimum()) + + ", " + + "25th=" + + TimeUnit.MICROSECONDS.toMillis((long) get25thPercentile()) + + ", " + + "median=" + + TimeUnit.MICROSECONDS.toMillis((long) getMedian()) + + ", " + + "avg=" + + TimeUnit.MICROSECONDS.toMillis((long) getAverage()) + + ", " + + "75th=" + + TimeUnit.MICROSECONDS.toMillis((long) get75thPercentile()) + + ", " + + "90th=" + + TimeUnit.MICROSECONDS.toMillis((long) get90thPercentile()) + + ", " + + "95th=" + + TimeUnit.MICROSECONDS.toMillis((long) get95thPercentile()) + + ", " + + "99th=" + + TimeUnit.MICROSECONDS.toMillis((long) get99thPercentile()) + + ", " + + "max=" + + TimeUnit.MICROSECONDS.toMillis((long) getMaximum()) + + "]"; + } + + public Map toMap() { + Map distMap = new LinkedHashMap<>(); + distMap.put("Minimum Latency (microseconds)", (int) getMinimum()); + distMap.put("25th Percentile Latency (microseconds)", (int) get25thPercentile()); + distMap.put("Median Latency (microseconds)", (int) getMedian()); + distMap.put("Average Latency (microseconds)", (int) getAverage()); + distMap.put("75th Percentile Latency (microseconds)", (int) get75thPercentile()); + distMap.put("90th Percentile Latency (microseconds)", (int) get90thPercentile()); + distMap.put("95th Percentile Latency (microseconds)", (int) get95thPercentile()); + distMap.put("99th Percentile Latency (microseconds)", (int) get99thPercentile()); + distMap.put("Maximum Latency (microseconds)", (int) getMaximum()); + return distMap; + } } diff --git a/src/main/java/com/oltpbenchmark/LatencyRecord.java b/src/main/java/com/oltpbenchmark/LatencyRecord.java index 0525d23f2..9db4fa145 100644 --- a/src/main/java/com/oltpbenchmark/LatencyRecord.java +++ b/src/main/java/com/oltpbenchmark/LatencyRecord.java @@ -15,171 +15,166 @@ * */ - package com.oltpbenchmark; import java.util.ArrayList; import java.util.Iterator; -/** - * Efficiently stores a record of (start time, latency) pairs. - */ +/** Efficiently stores a record of (start time, latency) pairs. */ public class LatencyRecord implements Iterable { - /** - * Allocate space for 500k samples at a time - */ - static final int ALLOC_SIZE = 500000; - - /** - * Contains (start time, latency, transactionType, workerid, phaseid) pentiplets - * in microsecond form. The start times are "compressed" by encoding them as - * increments, starting from startNs. A 32-bit integer provides sufficient resolution - * for an interval of 2146 seconds, or 35 minutes. - */ - private final ArrayList values = new ArrayList<>(); - private int nextIndex; - - private final long startNanosecond; - private long lastNanosecond; - - public LatencyRecord(long startNanosecond) { - this.startNanosecond = startNanosecond; - this.lastNanosecond = startNanosecond; - allocateChunk(); - - } + /** Allocate space for 500k samples at a time */ + static final int ALLOC_SIZE = 500000; - public void addLatency(int transType, long startNanosecond, long endNanosecond, int workerId, int phaseId) { + /** + * Contains (start time, latency, transactionType, workerid, phaseid) pentiplets in microsecond + * form. The start times are "compressed" by encoding them as increments, starting from startNs. A + * 32-bit integer provides sufficient resolution for an interval of 2146 seconds, or 35 minutes. + */ + private final ArrayList values = new ArrayList<>(); + private int nextIndex; - if (nextIndex == ALLOC_SIZE) { - allocateChunk(); - } - Sample[] chunk = values.get(values.size() - 1); + private final long startNanosecond; + private long lastNanosecond; - long startOffsetNanosecond = (startNanosecond - lastNanosecond + 500); + public LatencyRecord(long startNanosecond) { + this.startNanosecond = startNanosecond; + this.lastNanosecond = startNanosecond; + allocateChunk(); + } - int latencyMicroseconds = (int) ((endNanosecond - startNanosecond + 500) / 1000); + public void addLatency( + int transType, long startNanosecond, long endNanosecond, int workerId, int phaseId) { + if (nextIndex == ALLOC_SIZE) { + allocateChunk(); + } + Sample[] chunk = values.get(values.size() - 1); + + long startOffsetNanosecond = (startNanosecond - lastNanosecond + 500); + + int latencyMicroseconds = (int) ((endNanosecond - startNanosecond + 500) / 1000); + + chunk[nextIndex] = + new Sample(transType, startOffsetNanosecond, latencyMicroseconds, workerId, phaseId); + ++nextIndex; + + lastNanosecond += startOffsetNanosecond; + } + + private void allocateChunk() { + values.add(new Sample[ALLOC_SIZE]); + nextIndex = 0; + } + + /** Returns the number of recorded samples. */ + public int size() { + // Samples stored in full chunks + int samples = (values.size() - 1) * ALLOC_SIZE; + + // Samples stored in the last not full chunk + samples += nextIndex; + return samples; + } + + /** Stores the start time and latency for a single sample. Immutable. */ + public static final class Sample implements Comparable { + private final int transactionType; + private long startNanosecond; + private final int latencyMicrosecond; + private final int workerId; + private final int phaseId; + + public Sample( + int transactionType, + long startNanosecond, + int latencyMicrosecond, + int workerId, + int phaseId) { + this.transactionType = transactionType; + this.startNanosecond = startNanosecond; + this.latencyMicrosecond = latencyMicrosecond; + this.workerId = workerId; + this.phaseId = phaseId; + } - chunk[nextIndex] = new Sample(transType, startOffsetNanosecond, latencyMicroseconds, workerId, phaseId); - ++nextIndex; + public int getTransactionType() { + return transactionType; + } - lastNanosecond += startOffsetNanosecond; + public long getStartNanosecond() { + return startNanosecond; } - private void allocateChunk() { - values.add(new Sample[ALLOC_SIZE]); - nextIndex = 0; + public int getLatencyMicrosecond() { + return latencyMicrosecond; } - /** - * Returns the number of recorded samples. - */ - public int size() { - // Samples stored in full chunks - int samples = (values.size() - 1) * ALLOC_SIZE; + public int getWorkerId() { + return workerId; + } - // Samples stored in the last not full chunk - samples += nextIndex; - return samples; + public int getPhaseId() { + return phaseId; } - /** - * Stores the start time and latency for a single sample. Immutable. - */ - public static final class Sample implements Comparable { - private final int transactionType; - private long startNanosecond; - private final int latencyMicrosecond; - private final int workerId; - private final int phaseId; - - public Sample(int transactionType, long startNanosecond, int latencyMicrosecond, int workerId, int phaseId) { - this.transactionType = transactionType; - this.startNanosecond = startNanosecond; - this.latencyMicrosecond = latencyMicrosecond; - this.workerId = workerId; - this.phaseId = phaseId; - } - - public int getTransactionType() { - return transactionType; - } - - public long getStartNanosecond() { - return startNanosecond; - } - - public int getLatencyMicrosecond() { - return latencyMicrosecond; - } - - public int getWorkerId() { - return workerId; - } - - public int getPhaseId() { - return phaseId; - } - - @Override - public int compareTo(Sample other) { - long diff = this.startNanosecond - other.startNanosecond; - - // explicit comparison to avoid long to int overflow - if (diff > 0) { - return 1; - } else if (diff < 0) { - return -1; - } else { - - return 0; - } - } + @Override + public int compareTo(Sample other) { + long diff = this.startNanosecond - other.startNanosecond; + + // explicit comparison to avoid long to int overflow + if (diff > 0) { + return 1; + } else if (diff < 0) { + return -1; + } else { + + return 0; + } } + } + + private final class LatencyRecordIterator implements Iterator { + private int chunkIndex = 0; + private int subIndex = 0; + private long lastIteratorNanosecond = startNanosecond; + + @Override + public boolean hasNext() { + if (chunkIndex < values.size() - 1) { + return true; + } + return subIndex < nextIndex; + } + + @Override + public Sample next() { + Sample[] chunk = values.get(chunkIndex); + Sample s = chunk[subIndex]; - private final class LatencyRecordIterator implements Iterator { - private int chunkIndex = 0; - private int subIndex = 0; - private long lastIteratorNanosecond = startNanosecond; - - @Override - public boolean hasNext() { - if (chunkIndex < values.size() - 1) { - return true; - } - return subIndex < nextIndex; - } - - @Override - public Sample next() { - Sample[] chunk = values.get(chunkIndex); - Sample s = chunk[subIndex]; - - // Iterate in chunk, and wrap to next one - ++subIndex; - - if (subIndex == ALLOC_SIZE) { - chunkIndex += 1; - subIndex = 0; - } - - // Previously, s.startNs was just an offset from the previous - // value. Now we make it an absolute. - s.startNanosecond += lastIteratorNanosecond; - lastIteratorNanosecond = s.startNanosecond; - - return s; - } - - @Override - public void remove() { - throw new UnsupportedOperationException("remove is not supported"); - } + // Iterate in chunk, and wrap to next one + ++subIndex; + + if (subIndex == ALLOC_SIZE) { + chunkIndex += 1; + subIndex = 0; + } + + // Previously, s.startNs was just an offset from the previous + // value. Now we make it an absolute. + s.startNanosecond += lastIteratorNanosecond; + lastIteratorNanosecond = s.startNanosecond; + + return s; } - public Iterator iterator() { - return new LatencyRecordIterator(); + @Override + public void remove() { + throw new UnsupportedOperationException("remove is not supported"); } + } + + public Iterator iterator() { + return new LatencyRecordIterator(); + } } diff --git a/src/main/java/com/oltpbenchmark/Phase.java b/src/main/java/com/oltpbenchmark/Phase.java index 76bed1e4f..f3344d2d4 100644 --- a/src/main/java/com/oltpbenchmark/Phase.java +++ b/src/main/java/com/oltpbenchmark/Phase.java @@ -18,207 +18,212 @@ package com.oltpbenchmark; import com.oltpbenchmark.util.StringUtil; - import java.util.ArrayList; import java.util.List; import java.util.Random; public class Phase { - public enum Arrival { - REGULAR, POISSON, - } - - private final Random gen = new Random(); - private final String benchmarkName; - private final int id; - private final int time; - private final int warmupTime; - private final double rate; - private final Arrival arrival; - - - private final boolean rateLimited; - private final boolean disabled; - private final boolean serial; - private final boolean timed; - private final List weights; - private final int weightCount; - private final int activeTerminals; - private int nextSerial; - - - Phase(String benchmarkName, int id, int t, int wt, double r, List weights, boolean rateLimited, boolean disabled, boolean serial, boolean timed, int activeTerminals, Arrival a) { - this.benchmarkName = benchmarkName; - this.id = id; - this.time = t; - this.warmupTime = wt; - this.rate = r; - this.weights = weights; - this.weightCount = this.weights.size(); - this.rateLimited = rateLimited; - this.disabled = disabled; - this.serial = serial; - this.timed = timed; - this.nextSerial = 1; - this.activeTerminals = activeTerminals; - this.arrival = a; - } - - - - public boolean isRateLimited() { - return rateLimited; - } - - public boolean isDisabled() { - return disabled; - } - - public boolean isSerial() { - return serial; - } - - public boolean isTimed() { - return timed; - } - - public boolean isLatencyRun() { - return !timed && serial; - } - - public boolean isThroughputRun() { - return !isLatencyRun(); - } - - public void resetSerial() { - this.nextSerial = 1; - } - - public int getActiveTerminals() { - return activeTerminals; - } - - public int getWeightCount() { - return (this.weightCount); - } - - public int getId() { - return id; - } - - public int getTime() { - return time; - } - - public int getWarmupTime() { - return warmupTime; - } - - public double getRate() { - return rate; - } - - public Arrival getArrival() { - return arrival; - } - - public List getWeights() { - return (this.weights); - } - - /** - * Computes the sum of weights. Usually needs to add up to 100% - * - * @return The total weight - */ - public double totalWeight() { - double total = 0.0; - for (Double d : weights) { - total += d; + public enum Arrival { + REGULAR, + POISSON, + } + + private final Random gen = new Random(); + private final String benchmarkName; + private final int id; + private final int time; + private final int warmupTime; + private final double rate; + private final Arrival arrival; + + private final boolean rateLimited; + private final boolean disabled; + private final boolean serial; + private final boolean timed; + private final List weights; + private final int weightCount; + private final int activeTerminals; + private int nextSerial; + + Phase( + String benchmarkName, + int id, + int t, + int wt, + double r, + List weights, + boolean rateLimited, + boolean disabled, + boolean serial, + boolean timed, + int activeTerminals, + Arrival a) { + this.benchmarkName = benchmarkName; + this.id = id; + this.time = t; + this.warmupTime = wt; + this.rate = r; + this.weights = weights; + this.weightCount = this.weights.size(); + this.rateLimited = rateLimited; + this.disabled = disabled; + this.serial = serial; + this.timed = timed; + this.nextSerial = 1; + this.activeTerminals = activeTerminals; + this.arrival = a; + } + + public boolean isRateLimited() { + return rateLimited; + } + + public boolean isDisabled() { + return disabled; + } + + public boolean isSerial() { + return serial; + } + + public boolean isTimed() { + return timed; + } + + public boolean isLatencyRun() { + return !timed && serial; + } + + public boolean isThroughputRun() { + return !isLatencyRun(); + } + + public void resetSerial() { + this.nextSerial = 1; + } + + public int getActiveTerminals() { + return activeTerminals; + } + + public int getWeightCount() { + return (this.weightCount); + } + + public int getId() { + return id; + } + + public int getTime() { + return time; + } + + public int getWarmupTime() { + return warmupTime; + } + + public double getRate() { + return rate; + } + + public Arrival getArrival() { + return arrival; + } + + public List getWeights() { + return (this.weights); + } + + /** + * Computes the sum of weights. Usually needs to add up to 100% + * + * @return The total weight + */ + public double totalWeight() { + double total = 0.0; + for (Double d : weights) { + total += d; + } + return total; + } + + /** + * This simply computes the next transaction by randomly selecting one based on the weights of + * this phase. + * + * @return + */ + public int chooseTransaction() { + return chooseTransaction(false); + } + + public int chooseTransaction(boolean isColdQuery) { + if (isDisabled()) { + return -1; + } + + if (isSerial()) { + int ret; + synchronized (this) { + ret = this.nextSerial; + + // Serial runs should not execute queries with non-positive + // weights. + while (ret <= this.weightCount && weights.get(ret - 1) <= 0.0) { + ret = ++this.nextSerial; } - return total; - } - /** - * This simply computes the next transaction by randomly selecting one based - * on the weights of this phase. - * - * @return - */ - public int chooseTransaction() { - return chooseTransaction(false); - } + // If it's a cold execution, then we don't want to advance yet, + // since the hot run needs to execute the same query. + if (!isColdQuery) { - public int chooseTransaction(boolean isColdQuery) { - if (isDisabled()) { - return -1; - } + // throughput) run, so we loop through the list multiple + // times. Note that we do the modulus before the increment + // so that we end up in the range [1,num_weights] + if (isTimed()) { - if (isSerial()) { - int ret; - synchronized (this) { - ret = this.nextSerial; - - // Serial runs should not execute queries with non-positive - // weights. - while (ret <= this.weightCount && weights.get(ret - 1) <= 0.0) { - ret = ++this.nextSerial; - } - - // If it's a cold execution, then we don't want to advance yet, - // since the hot run needs to execute the same query. - if (!isColdQuery) { - - // throughput) run, so we loop through the list multiple - // times. Note that we do the modulus before the increment - // so that we end up in the range [1,num_weights] - if (isTimed()) { - - this.nextSerial %= this.weightCount; - } - - ++this.nextSerial; - } - } - return ret; - } else { - int randomPercentage = gen.nextInt((int) totalWeight()) + 1; - double weight = 0.0; - for (int i = 0; i < this.weightCount; i++) { - weight += weights.get(i); - if (randomPercentage <= weight) { - return i + 1; - } - } - } + this.nextSerial %= this.weightCount; + } - return -1; - } - - /** - * Returns a string for logging purposes when entering the phase - */ - public String currentPhaseString() { - List inner = new ArrayList<>(); - inner.add("[Workload=" + benchmarkName.toUpperCase() + "]"); - if (isDisabled()) { - inner.add("[Disabled=true]"); - } else { - if (isLatencyRun()) { - inner.add("[Serial=true]"); - inner.add("[Time=n/a]"); - } else { - inner.add("[Serial=" + isSerial() + "]"); - inner.add("[Time=" + time + "]"); - } - inner.add("[WarmupTime=" + warmupTime + "]"); - inner.add("[Rate=" + (isRateLimited() ? rate : "unlimited") + "]"); - inner.add("[Arrival=" + arrival + "]"); - inner.add("[Ratios=" + getWeights() + "]"); - inner.add("[ActiveWorkers=" + getActiveTerminals() + "]"); + ++this.nextSerial; } - - return StringUtil.bold("PHASE START") + " :: " + StringUtil.join(" ", inner); - } - -} \ No newline at end of file + } + return ret; + } else { + int randomPercentage = gen.nextInt((int) totalWeight()) + 1; + double weight = 0.0; + for (int i = 0; i < this.weightCount; i++) { + weight += weights.get(i); + if (randomPercentage <= weight) { + return i + 1; + } + } + } + + return -1; + } + + /** Returns a string for logging purposes when entering the phase */ + public String currentPhaseString() { + List inner = new ArrayList<>(); + inner.add("[Workload=" + benchmarkName.toUpperCase() + "]"); + if (isDisabled()) { + inner.add("[Disabled=true]"); + } else { + if (isLatencyRun()) { + inner.add("[Serial=true]"); + inner.add("[Time=n/a]"); + } else { + inner.add("[Serial=" + isSerial() + "]"); + inner.add("[Time=" + time + "]"); + } + inner.add("[WarmupTime=" + warmupTime + "]"); + inner.add("[Rate=" + (isRateLimited() ? rate : "unlimited") + "]"); + inner.add("[Arrival=" + arrival + "]"); + inner.add("[Ratios=" + getWeights() + "]"); + inner.add("[ActiveWorkers=" + getActiveTerminals() + "]"); + } + + return StringUtil.bold("PHASE START") + " :: " + StringUtil.join(" ", inner); + } +} diff --git a/src/main/java/com/oltpbenchmark/Results.java b/src/main/java/com/oltpbenchmark/Results.java index 1d3c34d07..9e740351f 100644 --- a/src/main/java/com/oltpbenchmark/Results.java +++ b/src/main/java/com/oltpbenchmark/Results.java @@ -15,118 +15,118 @@ * */ - package com.oltpbenchmark; import com.oltpbenchmark.LatencyRecord.Sample; import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.util.Histogram; - import java.util.HashMap; import java.util.List; import java.util.Map; public final class Results { - private final long startTimestampMs; - private final long nanoseconds; - private final int measuredRequests; - private final DistributionStatistics distributionStatistics; - private final List latencySamples; - private final Histogram unknown = new Histogram<>(false); - private final Histogram success = new Histogram<>(true); - private final Histogram abort = new Histogram<>(false); - private final Histogram retry = new Histogram<>(false); - private final Histogram error = new Histogram<>(false); - private final Histogram retryDifferent = new Histogram<>(false); - private final Map> abortMessages = new HashMap<>(); - - public Results(long startTimestampMs, long elapsedNanoseconds, int measuredRequests, DistributionStatistics distributionStatistics, final List latencySamples) { - this.startTimestampMs = startTimestampMs; - this.nanoseconds = elapsedNanoseconds; - this.measuredRequests = measuredRequests; - this.distributionStatistics = distributionStatistics; - - if (distributionStatistics == null) { - this.latencySamples = null; - } else { - // defensive copy - this.latencySamples = List.copyOf(latencySamples); - - } - } - - public DistributionStatistics getDistributionStatistics() { - return distributionStatistics; - } - - public Histogram getSuccess() { - return success; - } - - public Histogram getUnknown() { - return unknown; - } - - public Histogram getAbort() { - return abort; - } - - public Histogram getRetry() { - return retry; - } - - public Histogram getError() { - return error; - } - - public Histogram getRetryDifferent() { - return retryDifferent; - } - - public Map> getAbortMessages() { - return abortMessages; - } - - public double requestsPerSecondThroughput() { - return (double) measuredRequests / (double) nanoseconds * 1e9; - } - - public double requestsPerSecondGoodput() { - return (double) success.getSampleCount() / (double) nanoseconds * 1e9; - } - - public List getLatencySamples() { - return latencySamples; - } - - public long getStartTimestampMs() { - return startTimestampMs; - } - - public long getNanoseconds() { - return nanoseconds; - } - - public int getMeasuredRequests() { - return measuredRequests; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Results(nanoSeconds="); - sb.append(nanoseconds); - sb.append(", measuredRequests="); - sb.append(measuredRequests); - sb.append(") = "); - sb.append(requestsPerSecondThroughput()); - sb.append(" requests/sec (throughput)"); - sb.append(", "); - sb.append(requestsPerSecondGoodput()); - sb.append(" requests/sec (goodput)"); - return sb.toString(); - } - - -} \ No newline at end of file + private final long startTimestampMs; + private final long nanoseconds; + private final int measuredRequests; + private final DistributionStatistics distributionStatistics; + private final List latencySamples; + private final Histogram unknown = new Histogram<>(false); + private final Histogram success = new Histogram<>(true); + private final Histogram abort = new Histogram<>(false); + private final Histogram retry = new Histogram<>(false); + private final Histogram error = new Histogram<>(false); + private final Histogram retryDifferent = new Histogram<>(false); + private final Map> abortMessages = new HashMap<>(); + + public Results( + long startTimestampMs, + long elapsedNanoseconds, + int measuredRequests, + DistributionStatistics distributionStatistics, + final List latencySamples) { + this.startTimestampMs = startTimestampMs; + this.nanoseconds = elapsedNanoseconds; + this.measuredRequests = measuredRequests; + this.distributionStatistics = distributionStatistics; + + if (distributionStatistics == null) { + this.latencySamples = null; + } else { + // defensive copy + this.latencySamples = List.copyOf(latencySamples); + } + } + + public DistributionStatistics getDistributionStatistics() { + return distributionStatistics; + } + + public Histogram getSuccess() { + return success; + } + + public Histogram getUnknown() { + return unknown; + } + + public Histogram getAbort() { + return abort; + } + + public Histogram getRetry() { + return retry; + } + + public Histogram getError() { + return error; + } + + public Histogram getRetryDifferent() { + return retryDifferent; + } + + public Map> getAbortMessages() { + return abortMessages; + } + + public double requestsPerSecondThroughput() { + return (double) measuredRequests / (double) nanoseconds * 1e9; + } + + public double requestsPerSecondGoodput() { + return (double) success.getSampleCount() / (double) nanoseconds * 1e9; + } + + public List getLatencySamples() { + return latencySamples; + } + + public long getStartTimestampMs() { + return startTimestampMs; + } + + public long getNanoseconds() { + return nanoseconds; + } + + public int getMeasuredRequests() { + return measuredRequests; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Results(nanoSeconds="); + sb.append(nanoseconds); + sb.append(", measuredRequests="); + sb.append(measuredRequests); + sb.append(") = "); + sb.append(requestsPerSecondThroughput()); + sb.append(" requests/sec (throughput)"); + sb.append(", "); + sb.append(requestsPerSecondGoodput()); + sb.append(" requests/sec (goodput)"); + return sb.toString(); + } +} diff --git a/src/main/java/com/oltpbenchmark/SubmittedProcedure.java b/src/main/java/com/oltpbenchmark/SubmittedProcedure.java index e1558bc9e..24af5c0df 100644 --- a/src/main/java/com/oltpbenchmark/SubmittedProcedure.java +++ b/src/main/java/com/oltpbenchmark/SubmittedProcedure.java @@ -18,25 +18,25 @@ package com.oltpbenchmark; /** - * This class is used for keeping track of the procedures that have been - * submitted to the system when running a rate-limited benchmark. + * This class is used for keeping track of the procedures that have been submitted to the system + * when running a rate-limited benchmark. * * @author breilly */ public class SubmittedProcedure { - private final int type; - private final long startTime; + private final int type; + private final long startTime; - SubmittedProcedure(int type) { - this.type = type; - this.startTime = System.nanoTime(); - } + SubmittedProcedure(int type) { + this.type = type; + this.startTime = System.nanoTime(); + } - public int getType() { - return type; - } + public int getType() { + return type; + } - public long getStartTime() { - return startTime; - } + public long getStartTime() { + return startTime; + } } diff --git a/src/main/java/com/oltpbenchmark/ThreadBench.java b/src/main/java/com/oltpbenchmark/ThreadBench.java index 259452d00..450ad249e 100644 --- a/src/main/java/com/oltpbenchmark/ThreadBench.java +++ b/src/main/java/com/oltpbenchmark/ThreadBench.java @@ -23,532 +23,536 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.types.State; import com.oltpbenchmark.util.StringUtil; +import java.util.*; import org.apache.commons.collections4.map.ListOrderedMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; - public class ThreadBench implements Thread.UncaughtExceptionHandler { - private static final Logger LOG = LoggerFactory.getLogger(ThreadBench.class); - - private final BenchmarkState testState; - private final List> workers; - private final ArrayList workerThreads; - private final List workConfs; - private final ArrayList samples = new ArrayList<>(); - private final int intervalMonitor; - - private ThreadBench(List> workers, - List workConfs, int intervalMonitoring) { - this.workers = workers; - this.workConfs = workConfs; - this.workerThreads = new ArrayList<>(workers.size()); - this.intervalMonitor = intervalMonitoring; - this.testState = new BenchmarkState(workers.size() + 1); + private static final Logger LOG = LoggerFactory.getLogger(ThreadBench.class); + + private final BenchmarkState testState; + private final List> workers; + private final ArrayList workerThreads; + private final List workConfs; + private final ArrayList samples = new ArrayList<>(); + private final int intervalMonitor; + + private ThreadBench( + List> workers, + List workConfs, + int intervalMonitoring) { + this.workers = workers; + this.workConfs = workConfs; + this.workerThreads = new ArrayList<>(workers.size()); + this.intervalMonitor = intervalMonitoring; + this.testState = new BenchmarkState(workers.size() + 1); + } + + public static Results runRateLimitedBenchmark( + List> workers, + List workConfs, + int intervalMonitoring) { + ThreadBench bench = new ThreadBench(workers, workConfs, intervalMonitoring); + return bench.runRateLimitedMultiPhase(); + } + + private void createWorkerThreads() { + + for (Worker worker : workers) { + worker.initializeState(); + Thread thread = new Thread(worker); + thread.setUncaughtExceptionHandler(this); + thread.start(); + this.workerThreads.add(thread); } + } - public static Results runRateLimitedBenchmark(List> workers, - List workConfs, int intervalMonitoring) { - ThreadBench bench = new ThreadBench(workers, workConfs, intervalMonitoring); - return bench.runRateLimitedMultiPhase(); + private void interruptWorkers() { + for (Worker worker : workers) { + worker.cancelStatement(); } + } - private void createWorkerThreads() { + private int finalizeWorkers(ArrayList workerThreads) throws InterruptedException { - for (Worker worker : workers) { - worker.initializeState(); - Thread thread = new Thread(worker); - thread.setUncaughtExceptionHandler(this); - thread.start(); - this.workerThreads.add(thread); - } - } + int requests = 0; - private void interruptWorkers() { - for (Worker worker : workers) { - worker.cancelStatement(); - } - } - - private int finalizeWorkers(ArrayList workerThreads) throws InterruptedException { - - int requests = 0; + new WatchDogThread().start(); - new WatchDogThread().start(); + for (int i = 0; i < workerThreads.size(); ++i) { - for (int i = 0; i < workerThreads.size(); ++i) { + // FIXME not sure this is the best solution... ensure we don't hang + // forever, however we might ignore problems + workerThreads.get(i).join(60000); // wait for 60second for threads + // to terminate... hands otherwise - // FIXME not sure this is the best solution... ensure we don't hang - // forever, however we might ignore problems - workerThreads.get(i).join(60000); // wait for 60second for threads - // to terminate... hands otherwise + /* + * // CARLO: Maybe we might want to do this to kill threads that are + * hanging... if (workerThreads.get(i).isAlive()) { + * workerThreads.get(i).kill(); try { workerThreads.get(i).join(); } + * catch (InterruptedException e) { } } + */ - /* - * // CARLO: Maybe we might want to do this to kill threads that are - * hanging... if (workerThreads.get(i).isAlive()) { - * workerThreads.get(i).kill(); try { workerThreads.get(i).join(); } - * catch (InterruptedException e) { } } - */ + requests += workers.get(i).getRequests(); - requests += workers.get(i).getRequests(); - - LOG.debug("threadbench calling teardown"); - - workers.get(i).tearDown(); - } + LOG.debug("threadbench calling teardown"); - return requests; + workers.get(i).tearDown(); } - private Results runRateLimitedMultiPhase() { - List workStates = new ArrayList<>(); + return requests; + } - for (WorkloadConfiguration workState : this.workConfs) { - workState.initializeState(testState); - workStates.add(workState.getWorkloadState()); - } + private Results runRateLimitedMultiPhase() { + List workStates = new ArrayList<>(); - this.createWorkerThreads(); + for (WorkloadConfiguration workState : this.workConfs) { + workState.initializeState(testState); + workStates.add(workState.getWorkloadState()); + } - // long measureStart = start; + this.createWorkerThreads(); - long start_ts = System.currentTimeMillis(); - long start = System.nanoTime(); - long warmupStart = System.nanoTime(); - long warmup = warmupStart; - long measureEnd = -1; - // used to determine the longest sleep interval - double lowestRate = Double.MAX_VALUE; + // long measureStart = start; - Phase phase = null; + long start_ts = System.currentTimeMillis(); + long start = System.nanoTime(); + long warmupStart = System.nanoTime(); + long warmup = warmupStart; + long measureEnd = -1; + // used to determine the longest sleep interval + double lowestRate = Double.MAX_VALUE; - for (WorkloadState workState : workStates) { - workState.switchToNextPhase(); - phase = workState.getCurrentPhase(); - LOG.info(phase.currentPhaseString()); - if (phase.getRate() < lowestRate) { - lowestRate = phase.getRate(); - } - } + Phase phase = null; - // Change testState to cold query if execution is serial, since we don't - // have a warm-up phase for serial execution but execute a cold and a - // measured query in sequence. - if (phase != null && phase.isLatencyRun()) { - synchronized (testState) { - testState.startColdQuery(); - } - } + for (WorkloadState workState : workStates) { + workState.switchToNextPhase(); + phase = workState.getCurrentPhase(); + LOG.info(phase.currentPhaseString()); + if (phase.getRate() < lowestRate) { + lowestRate = phase.getRate(); + } + } - long intervalNs = getInterval(lowestRate, phase.getArrival()); + // Change testState to cold query if execution is serial, since we don't + // have a warm-up phase for serial execution but execute a cold and a + // measured query in sequence. + if (phase != null && phase.isLatencyRun()) { + synchronized (testState) { + testState.startColdQuery(); + } + } - long nextInterval = start + intervalNs; - int nextToAdd = 1; - int rateFactor; + long intervalNs = getInterval(lowestRate, phase.getArrival()); - boolean resetQueues = true; + long nextInterval = start + intervalNs; + int nextToAdd = 1; + int rateFactor; - long delta = phase.getTime() * 1000000000L; - boolean lastEntry = false; + boolean resetQueues = true; - // Initialize the Monitor - if (this.intervalMonitor > 0) { - new MonitorThread(this.intervalMonitor).start(); - } + long delta = phase.getTime() * 1000000000L; + boolean lastEntry = false; - // Allow workers to start work. - testState.blockForStart(); + // Initialize the Monitor + if (this.intervalMonitor > 0) { + new MonitorThread(this.intervalMonitor).start(); + } - // Main Loop - while (true) { - // posting new work... and resetting the queue in case we have new - // portion of the workload... + // Allow workers to start work. + testState.blockForStart(); - for (WorkloadState workState : workStates) { - if (workState.getCurrentPhase() != null) { - rateFactor = (int) (workState.getCurrentPhase().getRate() / lowestRate); - } else { - rateFactor = 1; - } - workState.addToQueue(nextToAdd * rateFactor, resetQueues); - } - resetQueues = false; + // Main Loop + while (true) { + // posting new work... and resetting the queue in case we have new + // portion of the workload... - // Wait until the interval expires, which may be "don't wait" - long now = System.nanoTime(); - if (phase != null) { - warmup = warmupStart + phase.getWarmupTime() * 1000000000L; - } - long diff = nextInterval - now; - while (diff > 0) { // this can wake early: sleep multiple times to avoid that - long ms = diff / 1000000; - diff = diff % 1000000; - try { - Thread.sleep(ms, (int) diff); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - now = System.nanoTime(); - diff = nextInterval - now; - } + for (WorkloadState workState : workStates) { + if (workState.getCurrentPhase() != null) { + rateFactor = (int) (workState.getCurrentPhase().getRate() / lowestRate); + } else { + rateFactor = 1; + } + workState.addToQueue(nextToAdd * rateFactor, resetQueues); + } + resetQueues = false; + + // Wait until the interval expires, which may be "don't wait" + long now = System.nanoTime(); + if (phase != null) { + warmup = warmupStart + phase.getWarmupTime() * 1000000000L; + } + long diff = nextInterval - now; + while (diff > 0) { // this can wake early: sleep multiple times to avoid that + long ms = diff / 1000000; + diff = diff % 1000000; + try { + Thread.sleep(ms, (int) diff); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + now = System.nanoTime(); + diff = nextInterval - now; + } + + boolean phaseComplete = false; + if (phase != null) { + if (phase.isLatencyRun()) + // Latency runs (serial run through each query) have their own + // state to mark completion + { + phaseComplete = testState.getState() == State.LATENCY_COMPLETE; + } else { + phaseComplete = testState.getState() == State.MEASURE && (start + delta <= now); + } + } - boolean phaseComplete = false; - if (phase != null) { - if (phase.isLatencyRun()) - // Latency runs (serial run through each query) have their own - // state to mark completion - { - phaseComplete = testState.getState() == State.LATENCY_COMPLETE; - } else { - phaseComplete = testState.getState() == State.MEASURE - && (start + delta <= now); - } - } + // Go to next phase if this one is complete or enter if error was thrown + boolean errorThrown = testState.getState() == State.ERROR; + if ((phaseComplete || errorThrown) && !lastEntry) { + // enters here after each phase of the test + // reset the queues so that the new phase is not affected by the + // queue of the previous one + resetQueues = true; - // Go to next phase if this one is complete or enter if error was thrown - boolean errorThrown = testState.getState() == State.ERROR; - if ((phaseComplete || errorThrown) && !lastEntry) { - // enters here after each phase of the test - // reset the queues so that the new phase is not affected by the - // queue of the previous one - resetQueues = true; - - // Fetch a new Phase - synchronized (testState) { - if (phase.isLatencyRun()) { - testState.ackLatencyComplete(); - } - for (WorkloadState workState : workStates) { - synchronized (workState) { - workState.switchToNextPhase(); - lowestRate = Integer.MAX_VALUE; - phase = workState.getCurrentPhase(); - interruptWorkers(); - if (phase == null && !lastEntry) { - // Last phase - lastEntry = true; - testState.startCoolDown(); - measureEnd = now; - LOG.info("{} :: Waiting for all terminals to finish ..", StringUtil.bold("TERMINATE")); - } else if (phase != null) { - // Reset serial execution parameters. - if (phase.isLatencyRun()) { - phase.resetSerial(); - testState.startColdQuery(); - } - LOG.info(phase.currentPhaseString()); - if (phase.getRate() < lowestRate) { - lowestRate = phase.getRate(); - } - } - } - } - if (phase != null) { - // update frequency in which we check according to - // wakeup - // speed - // intervalNs = (long) (1000000000. / (double) - // lowestRate + 0.5); - delta += phase.getTime() * 1000000000L; - } + // Fetch a new Phase + synchronized (testState) { + if (phase.isLatencyRun()) { + testState.ackLatencyComplete(); + } + for (WorkloadState workState : workStates) { + synchronized (workState) { + workState.switchToNextPhase(); + lowestRate = Integer.MAX_VALUE; + phase = workState.getCurrentPhase(); + interruptWorkers(); + if (phase == null && !lastEntry) { + // Last phase + lastEntry = true; + testState.startCoolDown(); + measureEnd = now; + LOG.info( + "{} :: Waiting for all terminals to finish ..", StringUtil.bold("TERMINATE")); + } else if (phase != null) { + // Reset serial execution parameters. + if (phase.isLatencyRun()) { + phase.resetSerial(); + testState.startColdQuery(); } - } - - // Compute the next interval - // and how many messages to deliver - if (phase != null) { - intervalNs = 0; - nextToAdd = 0; - do { - intervalNs += getInterval(lowestRate, phase.getArrival()); - nextToAdd++; - } while ((-diff) > intervalNs && !lastEntry); - nextInterval += intervalNs; - } - - // Update the test state appropriately - State state = testState.getState(); - if (state == State.WARMUP && now >= warmup) { - synchronized (testState) { - if (phase != null && phase.isLatencyRun()) { - testState.startColdQuery(); - } else { - testState.startMeasure(); - } - interruptWorkers(); + LOG.info(phase.currentPhaseString()); + if (phase.getRate() < lowestRate) { + lowestRate = phase.getRate(); } - start = now; - LOG.info("{} :: Warmup complete, starting measurements.", StringUtil.bold("MEASURE")); - // measureEnd = measureStart + measureSeconds * 1000000000L; - - // For serial executions, we want to do every query exactly - // once, so we need to restart in case some of the queries - // began during the warmup phase. - // If we're not doing serial executions, this function has no - // effect and is thus safe to call regardless. - phase.resetSerial(); - } else if (state == State.EXIT) { - // All threads have noticed the done, meaning all measured - // requests have definitely finished. - // Time to quit. - break; + } } + } + if (phase != null) { + // update frequency in which we check according to + // wakeup + // speed + // intervalNs = (long) (1000000000. / (double) + // lowestRate + 0.5); + delta += phase.getTime() * 1000000000L; + } } + } + + // Compute the next interval + // and how many messages to deliver + if (phase != null) { + intervalNs = 0; + nextToAdd = 0; + do { + intervalNs += getInterval(lowestRate, phase.getArrival()); + nextToAdd++; + } while ((-diff) > intervalNs && !lastEntry); + nextInterval += intervalNs; + } + + // Update the test state appropriately + State state = testState.getState(); + if (state == State.WARMUP && now >= warmup) { + synchronized (testState) { + if (phase != null && phase.isLatencyRun()) { + testState.startColdQuery(); + } else { + testState.startMeasure(); + } + interruptWorkers(); + } + start = now; + LOG.info("{} :: Warmup complete, starting measurements.", StringUtil.bold("MEASURE")); + // measureEnd = measureStart + measureSeconds * 1000000000L; + + // For serial executions, we want to do every query exactly + // once, so we need to restart in case some of the queries + // began during the warmup phase. + // If we're not doing serial executions, this function has no + // effect and is thus safe to call regardless. + phase.resetSerial(); + } else if (state == State.EXIT) { + // All threads have noticed the done, meaning all measured + // requests have definitely finished. + // Time to quit. + break; + } + } - try { - int requests = finalizeWorkers(this.workerThreads); - - // Combine all the latencies together in the most disgusting way - // possible: sorting! - for (Worker w : workers) { - for (LatencyRecord.Sample sample : w.getLatencyRecords()) { - samples.add(sample); - } - } - Collections.sort(samples); - - // Compute stats on all the latencies - int[] latencies = new int[samples.size()]; - for (int i = 0; i < samples.size(); ++i) { - latencies[i] = samples.get(i).getLatencyMicrosecond(); - } - DistributionStatistics stats = DistributionStatistics.computeStatistics(latencies); - - Results results = new Results(start_ts, measureEnd - start, requests, stats, samples); - - // Compute transaction histogram - Set txnTypes = new HashSet<>(); - for (WorkloadConfiguration workConf : workConfs) { - txnTypes.addAll(workConf.getTransTypes()); - } - txnTypes.remove(TransactionType.INVALID); - - results.getUnknown().putAll(txnTypes, 0); - results.getSuccess().putAll(txnTypes, 0); - results.getRetry().putAll(txnTypes, 0); - results.getAbort().putAll(txnTypes, 0); - results.getError().putAll(txnTypes, 0); - results.getRetryDifferent().putAll(txnTypes, 0); - - for (Worker w : workers) { - results.getUnknown().putHistogram(w.getTransactionUnknownHistogram()); - results.getSuccess().putHistogram(w.getTransactionSuccessHistogram()); - results.getRetry().putHistogram(w.getTransactionRetryHistogram()); - results.getAbort().putHistogram(w.getTransactionAbortHistogram()); - results.getError().putHistogram(w.getTransactionErrorHistogram()); - results.getRetryDifferent().putHistogram(w.getTransactionRetryDifferentHistogram()); - } + try { + int requests = finalizeWorkers(this.workerThreads); - return (results); - } catch (InterruptedException e) { - throw new RuntimeException(e); + // Combine all the latencies together in the most disgusting way + // possible: sorting! + for (Worker w : workers) { + for (LatencyRecord.Sample sample : w.getLatencyRecords()) { + samples.add(sample); } + } + Collections.sort(samples); + + // Compute stats on all the latencies + int[] latencies = new int[samples.size()]; + for (int i = 0; i < samples.size(); ++i) { + latencies[i] = samples.get(i).getLatencyMicrosecond(); + } + DistributionStatistics stats = DistributionStatistics.computeStatistics(latencies); + + Results results = new Results(start_ts, measureEnd - start, requests, stats, samples); + + // Compute transaction histogram + Set txnTypes = new HashSet<>(); + for (WorkloadConfiguration workConf : workConfs) { + txnTypes.addAll(workConf.getTransTypes()); + } + txnTypes.remove(TransactionType.INVALID); + + results.getUnknown().putAll(txnTypes, 0); + results.getSuccess().putAll(txnTypes, 0); + results.getRetry().putAll(txnTypes, 0); + results.getAbort().putAll(txnTypes, 0); + results.getError().putAll(txnTypes, 0); + results.getRetryDifferent().putAll(txnTypes, 0); + + for (Worker w : workers) { + results.getUnknown().putHistogram(w.getTransactionUnknownHistogram()); + results.getSuccess().putHistogram(w.getTransactionSuccessHistogram()); + results.getRetry().putHistogram(w.getTransactionRetryHistogram()); + results.getAbort().putHistogram(w.getTransactionAbortHistogram()); + results.getError().putHistogram(w.getTransactionErrorHistogram()); + results.getRetryDifferent().putHistogram(w.getTransactionRetryDifferentHistogram()); + } + + return (results); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - - private long getInterval(double lowestRate, Phase.Arrival arrival) { - // TODO Auto-generated method stub - if (arrival == Phase.Arrival.POISSON) { - return (long) ((-Math.log(1 - Math.random()) / lowestRate) * 1000000000.); - } else { - return (long) (1000000000. / lowestRate + 0.5); + } + + private long getInterval(double lowestRate, Phase.Arrival arrival) { + // TODO Auto-generated method stub + if (arrival == Phase.Arrival.POISSON) { + return (long) ((-Math.log(1 - Math.random()) / lowestRate) * 1000000000.); + } else { + return (long) (1000000000. / lowestRate + 0.5); + } + } + + @Override + public void uncaughtException(Thread t, Throwable e) { + // Here we handle the case in which one of our worker threads died + LOG.error(e.getMessage(), e); + // We do not continue with the experiment. Instead, bypass rest of + // phases that were left in the test and signal error state. + // The rest of the workflow to finish the experiment remains the same, + // and partial metrics will be reported (i.e., until failure happened). + synchronized (testState) { + for (WorkloadConfiguration workConf : this.workConfs) { + synchronized (workConf.getWorkloadState()) { + WorkloadState workState = workConf.getWorkloadState(); + Phase phase = workState.getCurrentPhase(); + while (phase != null) { + workState.switchToNextPhase(); + phase = workState.getCurrentPhase(); + } } + } + testState.signalError(); + } + } + + public static final class TimeBucketIterable implements Iterable { + private final Iterable samples; + private final int windowSizeSeconds; + private final TransactionType transactionType; + + /** + * @param samples + * @param windowSizeSeconds + * @param transactionType Allows to filter transactions by type + */ + public TimeBucketIterable( + Iterable samples, int windowSizeSeconds, TransactionType transactionType) { + this.samples = samples; + this.windowSizeSeconds = windowSizeSeconds; + this.transactionType = transactionType; } @Override - public void uncaughtException(Thread t, Throwable e) { - // Here we handle the case in which one of our worker threads died - LOG.error(e.getMessage(), e); - // We do not continue with the experiment. Instead, bypass rest of - // phases that were left in the test and signal error state. - // The rest of the workflow to finish the experiment remains the same, - // and partial metrics will be reported (i.e., until failure happened). - synchronized (testState) { - for (WorkloadConfiguration workConf : this.workConfs) { - synchronized (workConf.getWorkloadState()) { - WorkloadState workState = workConf.getWorkloadState(); - Phase phase = workState.getCurrentPhase(); - while (phase != null) { - workState.switchToNextPhase(); - phase = workState.getCurrentPhase(); - } - } - } - testState.signalError(); - } + public Iterator iterator() { + return new TimeBucketIterator(samples.iterator(), windowSizeSeconds, transactionType); + } + } + + private static final class TimeBucketIterator implements Iterator { + private final Iterator samples; + private final int windowSizeSeconds; + private final TransactionType txType; + + private Sample sample; + private long nextStartNanosecond; + + private DistributionStatistics next; + + /** + * @param samples + * @param windowSizeSeconds + * @param txType Allows to filter transactions by type + */ + public TimeBucketIterator( + Iterator samples, int windowSizeSeconds, TransactionType txType) { + this.samples = samples; + this.windowSizeSeconds = windowSizeSeconds; + this.txType = txType; + + if (samples.hasNext()) { + sample = samples.next(); + // TODO: To be totally correct, we would want this to be the + // timestamp of the start + // of the measurement interval. In most cases this won't matter. + nextStartNanosecond = sample.getStartNanosecond(); + calculateNext(); + } } - public static final class TimeBucketIterable implements Iterable { - private final Iterable samples; - private final int windowSizeSeconds; - private final TransactionType transactionType; - - /** - * @param samples - * @param windowSizeSeconds - * @param transactionType Allows to filter transactions by type - */ - public TimeBucketIterable(Iterable samples, int windowSizeSeconds, TransactionType transactionType) { - this.samples = samples; - this.windowSizeSeconds = windowSizeSeconds; - this.transactionType = transactionType; - } + private void calculateNext() { - @Override - public Iterator iterator() { - return new TimeBucketIterator(samples.iterator(), windowSizeSeconds, transactionType); - } - } + // Collect all samples in the time window + ArrayList latencies = new ArrayList<>(); + long endNanoseconds = nextStartNanosecond + (windowSizeSeconds * 1000000000L); + while (sample != null && sample.getStartNanosecond() < endNanoseconds) { - private static final class TimeBucketIterator implements Iterator { - private final Iterator samples; - private final int windowSizeSeconds; - private final TransactionType txType; - - private Sample sample; - private long nextStartNanosecond; - - private DistributionStatistics next; - - /** - * @param samples - * @param windowSizeSeconds - * @param txType Allows to filter transactions by type - */ - public TimeBucketIterator(Iterator samples, int windowSizeSeconds, - TransactionType txType) { - this.samples = samples; - this.windowSizeSeconds = windowSizeSeconds; - this.txType = txType; - - if (samples.hasNext()) { - sample = samples.next(); - // TODO: To be totally correct, we would want this to be the - // timestamp of the start - // of the measurement interval. In most cases this won't matter. - nextStartNanosecond = sample.getStartNanosecond(); - calculateNext(); - } + // Check if a TX Type filter is set, in the default case, + // INVALID TXType means all should be reported, if a filter is + // set, only this specific transaction + if (txType.equals(TransactionType.INVALID) + || txType.getId() == sample.getTransactionType()) { + latencies.add(sample.getLatencyMicrosecond()); } - private void calculateNext() { + if (samples.hasNext()) { + sample = samples.next(); + } else { + sample = null; + } + } - // Collect all samples in the time window - ArrayList latencies = new ArrayList<>(); - long endNanoseconds = nextStartNanosecond + (windowSizeSeconds * 1000000000L); - while (sample != null && sample.getStartNanosecond() < endNanoseconds) { + // Set up the next time window - // Check if a TX Type filter is set, in the default case, - // INVALID TXType means all should be reported, if a filter is - // set, only this specific transaction - if (txType.equals(TransactionType.INVALID) || txType.getId() == sample.getTransactionType()) { - latencies.add(sample.getLatencyMicrosecond()); - } + nextStartNanosecond = endNanoseconds; - if (samples.hasNext()) { - sample = samples.next(); - } else { - sample = null; - } - } + int[] l = new int[latencies.size()]; + for (int i = 0; i < l.length; ++i) { + l[i] = latencies.get(i); + } - // Set up the next time window + next = DistributionStatistics.computeStatistics(l); + } - nextStartNanosecond = endNanoseconds; + @Override + public boolean hasNext() { + return next != null; + } - int[] l = new int[latencies.size()]; - for (int i = 0; i < l.length; ++i) { - l[i] = latencies.get(i); - } + @Override + public DistributionStatistics next() { + if (next == null) { + throw new NoSuchElementException(); + } + DistributionStatistics out = next; + next = null; + if (sample != null) { + calculateNext(); + } + return out; + } - next = DistributionStatistics.computeStatistics(l); - } + @Override + public void remove() { + throw new UnsupportedOperationException("unsupported"); + } + } - @Override - public boolean hasNext() { - return next != null; - } + private class WatchDogThread extends Thread { + { + this.setDaemon(true); + } - @Override - public DistributionStatistics next() { - if (next == null) { - throw new NoSuchElementException(); - } - DistributionStatistics out = next; - next = null; - if (sample != null) { - calculateNext(); - } - return out; + @Override + public void run() { + Map m = new ListOrderedMap<>(); + LOG.info("Starting WatchDogThread"); + while (true) { + try { + Thread.sleep(20000); + } catch (InterruptedException ex) { + return; } - @Override - public void remove() { - throw new UnsupportedOperationException("unsupported"); + m.clear(); + for (Thread t : workerThreads) { + m.put(t.getName(), t.isAlive()); } + LOG.info("Worker Thread Status:\n{}", StringUtil.formatMaps(m)); + } } + } - private class WatchDogThread extends Thread { - { - this.setDaemon(true); - } - - @Override - public void run() { - Map m = new ListOrderedMap<>(); - LOG.info("Starting WatchDogThread"); - while (true) { - try { - Thread.sleep(20000); - } catch (InterruptedException ex) { - return; - } + private class MonitorThread extends Thread { + private final int intervalMonitor; - m.clear(); - for (Thread t : workerThreads) { - m.put(t.getName(), t.isAlive()); - } - LOG.info("Worker Thread Status:\n{}", StringUtil.formatMaps(m)); - } - } + { + this.setDaemon(true); } - private class MonitorThread extends Thread { - private final int intervalMonitor; - - { - this.setDaemon(true); - } + /** + * @param interval How long to wait between polling in milliseconds + */ + MonitorThread(int interval) { + this.intervalMonitor = interval; + } - /** - * @param interval How long to wait between polling in milliseconds - */ - MonitorThread(int interval) { - this.intervalMonitor = interval; + @Override + public void run() { + LOG.info("Starting MonitorThread Interval [{}ms]", this.intervalMonitor); + while (true) { + try { + Thread.sleep(this.intervalMonitor); + } catch (InterruptedException ex) { + return; } - @Override - public void run() { - LOG.info("Starting MonitorThread Interval [{}ms]", this.intervalMonitor); - while (true) { - try { - Thread.sleep(this.intervalMonitor); - } catch (InterruptedException ex) { - return; - } - - // Compute the last throughput - long measuredRequests = 0; - synchronized (testState) { - for (Worker w : workers) { - measuredRequests += w.getAndResetIntervalRequests(); - } - } - double seconds = this.intervalMonitor / 1000d; - double tps = (double) measuredRequests / seconds; - LOG.info("Throughput: {} txn/sec", tps); - } + // Compute the last throughput + long measuredRequests = 0; + synchronized (testState) { + for (Worker w : workers) { + measuredRequests += w.getAndResetIntervalRequests(); + } } + double seconds = this.intervalMonitor / 1000d; + double tps = (double) measuredRequests / seconds; + LOG.info("Throughput: {} txn/sec", tps); + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/WorkloadConfiguration.java b/src/main/java/com/oltpbenchmark/WorkloadConfiguration.java index 68fa03cbc..fb31c1881 100644 --- a/src/main/java/com/oltpbenchmark/WorkloadConfiguration.java +++ b/src/main/java/com/oltpbenchmark/WorkloadConfiguration.java @@ -15,337 +15,375 @@ * */ - package com.oltpbenchmark; import com.oltpbenchmark.api.TransactionTypes; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.ThreadUtil; -import org.apache.commons.configuration2.XMLConfiguration; - import java.sql.Connection; import java.util.ArrayList; import java.util.List; +import org.apache.commons.configuration2.XMLConfiguration; public class WorkloadConfiguration { - private final List phases = new ArrayList<>(); - private DatabaseType databaseType; - private String benchmarkName; - private String url; - private String username; - private String password; - private String driverClass; - private int batchSize; - private int maxRetries; - private int randomSeed = -1; - private double scaleFactor = 1.0; - private double selectivity = -1.0; - private int terminals; - private int loaderThreads = ThreadUtil.availableProcessors(); - private XMLConfiguration xmlConfig = null; - private WorkloadState workloadState; - private TransactionTypes transTypes = null; - private int isolationMode = Connection.TRANSACTION_SERIALIZABLE; - private String dataDir = null; - private String ddlPath = null; - - /** - * If true, establish a new connection for each transaction, otherwise use one persistent connection per client - * session. This is useful to measure the connection overhead. - */ - private boolean newConnectionPerTxn = false; - - public String getBenchmarkName() { - return benchmarkName; - } - - public void setBenchmarkName(String benchmarkName) { - this.benchmarkName = benchmarkName; - } - - public WorkloadState getWorkloadState() { - return workloadState; - } - - public DatabaseType getDatabaseType() { - return databaseType; - } - - public void setDatabaseType(DatabaseType databaseType) { - this.databaseType = databaseType; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getDriverClass() { - return driverClass; - } - - public void setDriverClass(String driverClass) { - this.driverClass = driverClass; - } - - public int getBatchSize() { - return batchSize; - } - - public void setBatchSize(int batchSize) { - this.batchSize = batchSize; - } - - public int getMaxRetries() { - return maxRetries; - } - - public void setMaxRetries(int maxRetries) { - this.maxRetries = maxRetries; - } - - /** - * @return @see newConnectionPerTxn member docs for behavior. - */ - public boolean getNewConnectionPerTxn() { - return newConnectionPerTxn; - } - - /** - * Used by the configuration loader at startup. Changing it any other time is probably dangeroues. @see - * newConnectionPerTxn member docs for behavior. - * - * @param newConnectionPerTxn - */ - public void setNewConnectionPerTxn(boolean newConnectionPerTxn) { - this.newConnectionPerTxn = newConnectionPerTxn; - } - - /** - * Initiate a new benchmark and workload state - */ - public void initializeState(BenchmarkState benchmarkState) { - this.workloadState = new WorkloadState(benchmarkState, phases, terminals); - } - - public void addPhase(int id, int time, int warmup, double rate, List weights, boolean rateLimited, boolean disabled, boolean serial, boolean timed, int active_terminals, Phase.Arrival arrival) { - phases.add(new Phase(benchmarkName, id, time, warmup, rate, weights, rateLimited, disabled, serial, timed, active_terminals, arrival)); - } - - - - - /** - * The number of loader threads that the framework is allowed to use. - * - * @return - */ - public int getLoaderThreads() { - return this.loaderThreads; - } - - public void setLoaderThreads(int loaderThreads) { - this.loaderThreads = loaderThreads; - } - - public double getSelectivity() { - return this.selectivity; - } - - public void setSelectivity(double selectivity) { - this.selectivity = selectivity; - } - - /** - * The random seed for this benchmark - * @return - */ - public int getRandomSeed() { return this.randomSeed; } - - /** - * Set the random seed for this benchmark - * @param randomSeed - */ - public void setRandomSeed(int randomSeed) { this.randomSeed = randomSeed; } - - /** - * Return the scale factor of the database size - * - * @return - */ - public double getScaleFactor() { - return this.scaleFactor; - } - - /** - * Set the scale factor for the database - * A value of 1 means the default size. - * A value greater than 1 means the database is larger - * A value less than 1 means the database is smaller - * - * @param scaleFactor - */ - public void setScaleFactor(double scaleFactor) { - this.scaleFactor = scaleFactor; - } - - /** - * Return the number of phases specified in the config file - * - * @return - */ - public int getNumberOfPhases() { - return phases.size(); - } - - /** - * Return the directory in which we can find the data files (for example, CSV - * files) for loading the database. - */ - public String getDataDir() { - return this.dataDir; - } - - /** - * Set the directory in which we can find the data files (for example, CSV - * files) for loading the database. - */ - public void setDataDir(String dir) { - this.dataDir = dir; - } - - /** - * Return the path in which we can find the ddl script. - */ - public String getDDLPath() { - return this.ddlPath; - } - - /** - * Set the path in which we can find the ddl script. - */ - public void setDDLPath(String ddlPath) { - this.ddlPath = ddlPath; - } - - /** - * A utility method that init the phaseIterator and dialectMap - */ - public void init() { - try { - Class.forName(this.driverClass); - } catch (ClassNotFoundException ex) { - throw new RuntimeException("Failed to initialize JDBC driver '" + this.driverClass + "'", ex); - } - } - - public int getTerminals() { - return terminals; - } - - public void setTerminals(int terminals) { - this.terminals = terminals; - } - - public TransactionTypes getTransTypes() { - return transTypes; - } - - public void setTransTypes(TransactionTypes transTypes) { - this.transTypes = transTypes; - } - - public List getPhases() { - return phases; - } - - public XMLConfiguration getXmlConfig() { - return xmlConfig; - } - - public void setXmlConfig(XMLConfiguration xmlConfig) { - this.xmlConfig = xmlConfig; - } - - public int getIsolationMode() { - return isolationMode; - } - - public void setIsolationMode(String mode) { - switch (mode) { - case "TRANSACTION_SERIALIZABLE": - this.isolationMode = Connection.TRANSACTION_SERIALIZABLE; - break; - case "TRANSACTION_READ_COMMITTED": - this.isolationMode = Connection.TRANSACTION_READ_COMMITTED; - break; - case "TRANSACTION_REPEATABLE_READ": - this.isolationMode = Connection.TRANSACTION_REPEATABLE_READ; - break; - case "TRANSACTION_READ_UNCOMMITTED": - this.isolationMode = Connection.TRANSACTION_READ_UNCOMMITTED; - break; - case "TRANSACTION_NONE": - this.isolationMode = Connection.TRANSACTION_NONE; - } - } - - public String getIsolationString() { - if (this.isolationMode == Connection.TRANSACTION_SERIALIZABLE) { - return "TRANSACTION_SERIALIZABLE"; - } else if (this.isolationMode == Connection.TRANSACTION_READ_COMMITTED) { - return "TRANSACTION_READ_COMMITTED"; - } else if (this.isolationMode == Connection.TRANSACTION_REPEATABLE_READ) { - return "TRANSACTION_REPEATABLE_READ"; - } else if (this.isolationMode == Connection.TRANSACTION_READ_UNCOMMITTED) { - return "TRANSACTION_READ_UNCOMMITTED"; - } else if (this.isolationMode == Connection.TRANSACTION_NONE) { - return "TRANSACTION_NONE"; - } else { - return "TRANSACTION_SERIALIZABLE"; - } - } - - @Override - public String toString() { - return "WorkloadConfiguration{" + - "phases=" + phases + - ", databaseType=" + databaseType + - ", benchmarkName='" + benchmarkName + '\'' + - ", url='" + url + '\'' + - ", username='" + username + '\'' + - ", password='" + password + '\'' + - ", driverClass='" + driverClass + '\'' + - ", batchSize=" + batchSize + - ", maxRetries=" + maxRetries + - ", scaleFactor=" + scaleFactor + - ", selectivity=" + selectivity + - ", terminals=" + terminals + - ", loaderThreads=" + loaderThreads + - ", workloadState=" + workloadState + - ", transTypes=" + transTypes + - ", isolationMode=" + isolationMode + - ", dataDir='" + dataDir + '\'' + - '}'; - } + private final List phases = new ArrayList<>(); + private DatabaseType databaseType; + private String benchmarkName; + private String url; + private String username; + private String password; + private String driverClass; + private int batchSize; + private int maxRetries; + private int randomSeed = -1; + private double scaleFactor = 1.0; + private double selectivity = -1.0; + private int terminals; + private int loaderThreads = ThreadUtil.availableProcessors(); + private XMLConfiguration xmlConfig = null; + private WorkloadState workloadState; + private TransactionTypes transTypes = null; + private int isolationMode = Connection.TRANSACTION_SERIALIZABLE; + private String dataDir = null; + private String ddlPath = null; + + /** + * If true, establish a new connection for each transaction, otherwise use one persistent + * connection per client session. This is useful to measure the connection overhead. + */ + private boolean newConnectionPerTxn = false; + + public String getBenchmarkName() { + return benchmarkName; + } + + public void setBenchmarkName(String benchmarkName) { + this.benchmarkName = benchmarkName; + } + + public WorkloadState getWorkloadState() { + return workloadState; + } + + public DatabaseType getDatabaseType() { + return databaseType; + } + + public void setDatabaseType(DatabaseType databaseType) { + this.databaseType = databaseType; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getDriverClass() { + return driverClass; + } + + public void setDriverClass(String driverClass) { + this.driverClass = driverClass; + } + + public int getBatchSize() { + return batchSize; + } + + public void setBatchSize(int batchSize) { + this.batchSize = batchSize; + } + + public int getMaxRetries() { + return maxRetries; + } + + public void setMaxRetries(int maxRetries) { + this.maxRetries = maxRetries; + } + + /** + * @return @see newConnectionPerTxn member docs for behavior. + */ + public boolean getNewConnectionPerTxn() { + return newConnectionPerTxn; + } + + /** + * Used by the configuration loader at startup. Changing it any other time is probably + * dangeroues. @see newConnectionPerTxn member docs for behavior. + * + * @param newConnectionPerTxn + */ + public void setNewConnectionPerTxn(boolean newConnectionPerTxn) { + this.newConnectionPerTxn = newConnectionPerTxn; + } + + /** Initiate a new benchmark and workload state */ + public void initializeState(BenchmarkState benchmarkState) { + this.workloadState = new WorkloadState(benchmarkState, phases, terminals); + } + + public void addPhase( + int id, + int time, + int warmup, + double rate, + List weights, + boolean rateLimited, + boolean disabled, + boolean serial, + boolean timed, + int active_terminals, + Phase.Arrival arrival) { + phases.add( + new Phase( + benchmarkName, + id, + time, + warmup, + rate, + weights, + rateLimited, + disabled, + serial, + timed, + active_terminals, + arrival)); + } + + /** + * The number of loader threads that the framework is allowed to use. + * + * @return + */ + public int getLoaderThreads() { + return this.loaderThreads; + } + + public void setLoaderThreads(int loaderThreads) { + this.loaderThreads = loaderThreads; + } + + public double getSelectivity() { + return this.selectivity; + } + + public void setSelectivity(double selectivity) { + this.selectivity = selectivity; + } + + /** + * The random seed for this benchmark + * + * @return + */ + public int getRandomSeed() { + return this.randomSeed; + } + + /** + * Set the random seed for this benchmark + * + * @param randomSeed + */ + public void setRandomSeed(int randomSeed) { + this.randomSeed = randomSeed; + } + + /** + * Return the scale factor of the database size + * + * @return + */ + public double getScaleFactor() { + return this.scaleFactor; + } + + /** + * Set the scale factor for the database A value of 1 means the default size. A value greater than + * 1 means the database is larger A value less than 1 means the database is smaller + * + * @param scaleFactor + */ + public void setScaleFactor(double scaleFactor) { + this.scaleFactor = scaleFactor; + } + + /** + * Return the number of phases specified in the config file + * + * @return + */ + public int getNumberOfPhases() { + return phases.size(); + } + + /** + * Return the directory in which we can find the data files (for example, CSV files) for loading + * the database. + */ + public String getDataDir() { + return this.dataDir; + } + + /** + * Set the directory in which we can find the data files (for example, CSV files) for loading the + * database. + */ + public void setDataDir(String dir) { + this.dataDir = dir; + } + + /** Return the path in which we can find the ddl script. */ + public String getDDLPath() { + return this.ddlPath; + } + + /** Set the path in which we can find the ddl script. */ + public void setDDLPath(String ddlPath) { + this.ddlPath = ddlPath; + } + + /** A utility method that init the phaseIterator and dialectMap */ + public void init() { + try { + Class.forName(this.driverClass); + } catch (ClassNotFoundException ex) { + throw new RuntimeException("Failed to initialize JDBC driver '" + this.driverClass + "'", ex); + } + } + + public int getTerminals() { + return terminals; + } + + public void setTerminals(int terminals) { + this.terminals = terminals; + } + + public TransactionTypes getTransTypes() { + return transTypes; + } + + public void setTransTypes(TransactionTypes transTypes) { + this.transTypes = transTypes; + } + + public List getPhases() { + return phases; + } + + public XMLConfiguration getXmlConfig() { + return xmlConfig; + } + + public void setXmlConfig(XMLConfiguration xmlConfig) { + this.xmlConfig = xmlConfig; + } + + public int getIsolationMode() { + return isolationMode; + } + + public void setIsolationMode(String mode) { + switch (mode) { + case "TRANSACTION_SERIALIZABLE": + this.isolationMode = Connection.TRANSACTION_SERIALIZABLE; + break; + case "TRANSACTION_READ_COMMITTED": + this.isolationMode = Connection.TRANSACTION_READ_COMMITTED; + break; + case "TRANSACTION_REPEATABLE_READ": + this.isolationMode = Connection.TRANSACTION_REPEATABLE_READ; + break; + case "TRANSACTION_READ_UNCOMMITTED": + this.isolationMode = Connection.TRANSACTION_READ_UNCOMMITTED; + break; + case "TRANSACTION_NONE": + this.isolationMode = Connection.TRANSACTION_NONE; + } + } + + public String getIsolationString() { + if (this.isolationMode == Connection.TRANSACTION_SERIALIZABLE) { + return "TRANSACTION_SERIALIZABLE"; + } else if (this.isolationMode == Connection.TRANSACTION_READ_COMMITTED) { + return "TRANSACTION_READ_COMMITTED"; + } else if (this.isolationMode == Connection.TRANSACTION_REPEATABLE_READ) { + return "TRANSACTION_REPEATABLE_READ"; + } else if (this.isolationMode == Connection.TRANSACTION_READ_UNCOMMITTED) { + return "TRANSACTION_READ_UNCOMMITTED"; + } else if (this.isolationMode == Connection.TRANSACTION_NONE) { + return "TRANSACTION_NONE"; + } else { + return "TRANSACTION_SERIALIZABLE"; + } + } + + @Override + public String toString() { + return "WorkloadConfiguration{" + + "phases=" + + phases + + ", databaseType=" + + databaseType + + ", benchmarkName='" + + benchmarkName + + '\'' + + ", url='" + + url + + '\'' + + ", username='" + + username + + '\'' + + ", password='" + + password + + '\'' + + ", driverClass='" + + driverClass + + '\'' + + ", batchSize=" + + batchSize + + ", maxRetries=" + + maxRetries + + ", scaleFactor=" + + scaleFactor + + ", selectivity=" + + selectivity + + ", terminals=" + + terminals + + ", loaderThreads=" + + loaderThreads + + ", workloadState=" + + workloadState + + ", transTypes=" + + transTypes + + ", isolationMode=" + + isolationMode + + ", dataDir='" + + dataDir + + '\'' + + '}'; + } } diff --git a/src/main/java/com/oltpbenchmark/WorkloadState.java b/src/main/java/com/oltpbenchmark/WorkloadState.java index 7b5b20ff5..5da45efb3 100644 --- a/src/main/java/com/oltpbenchmark/WorkloadState.java +++ b/src/main/java/com/oltpbenchmark/WorkloadState.java @@ -18,249 +18,240 @@ package com.oltpbenchmark; import com.oltpbenchmark.types.State; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * This class is used to share a state among the workers of a single - * workload. Worker use it to ask for work and as interface to the global - * BenchmarkState + * This class is used to share a state among the workers of a single workload. Worker use it to ask + * for work and as interface to the global BenchmarkState * * @author alendit */ public class WorkloadState { - private static final int RATE_QUEUE_LIMIT = 10000; - private static final Logger LOG = LoggerFactory.getLogger(WorkloadState.class); - - private final BenchmarkState benchmarkState; - private final LinkedList workQueue = new LinkedList<>(); - private final int num_terminals; - private final Iterator phaseIterator; - - private int workersWaiting = 0; - @SuppressWarnings("unused") // never read - private int workersWorking = 0; - private int workerNeedSleep; - - private Phase currentPhase = null; - - public WorkloadState(BenchmarkState benchmarkState, List works, int num_terminals) { - this.benchmarkState = benchmarkState; - this.num_terminals = num_terminals; - this.workerNeedSleep = num_terminals; - - phaseIterator = works.iterator(); + private static final int RATE_QUEUE_LIMIT = 10000; + private static final Logger LOG = LoggerFactory.getLogger(WorkloadState.class); + + private final BenchmarkState benchmarkState; + private final LinkedList workQueue = new LinkedList<>(); + private final int num_terminals; + private final Iterator phaseIterator; + + private int workersWaiting = 0; + + @SuppressWarnings("unused") // never read + private int workersWorking = 0; + + private int workerNeedSleep; + + private Phase currentPhase = null; + + public WorkloadState(BenchmarkState benchmarkState, List works, int num_terminals) { + this.benchmarkState = benchmarkState; + this.num_terminals = num_terminals; + this.workerNeedSleep = num_terminals; + + phaseIterator = works.iterator(); + } + + /** Add a request to do work. */ + public void addToQueue(int amount, boolean resetQueues) { + int workAdded = 0; + + synchronized (this) { + if (resetQueues) { + workQueue.clear(); + } + + // Only use the work queue if the phase is enabled and rate limited. + if (currentPhase == null + || currentPhase.isDisabled() + || !currentPhase.isRateLimited() + || currentPhase.isSerial()) { + return; + } + + // Add the specified number of procedures to the end of the queue. + // If we can't keep up with current rate, truncate transactions + for (int i = 0; i < amount && workQueue.size() <= RATE_QUEUE_LIMIT; ++i) { + workQueue.add(new SubmittedProcedure(currentPhase.chooseTransaction())); + workAdded++; + } + + // Wake up sleeping workers to deal with the new work. + int numToWake = Math.min(workAdded, workersWaiting); + while (numToWake-- > 0) { + this.notify(); + } } - - /** - * Add a request to do work. - */ - public void addToQueue(int amount, boolean resetQueues) { - int workAdded = 0; - - synchronized (this) { - if (resetQueues) { - workQueue.clear(); - } - - // Only use the work queue if the phase is enabled and rate limited. - if (currentPhase == null || currentPhase.isDisabled() - || !currentPhase.isRateLimited() || currentPhase.isSerial()) { - return; - } - - // Add the specified number of procedures to the end of the queue. - // If we can't keep up with current rate, truncate transactions - for (int i = 0; i < amount && workQueue.size() <= RATE_QUEUE_LIMIT; ++i) { - workQueue.add(new SubmittedProcedure(currentPhase.chooseTransaction())); - workAdded++; - } - - // Wake up sleeping workers to deal with the new work. - int numToWake = Math.min(workAdded, workersWaiting); - while (numToWake-- > 0) { - this.notify(); - } + } + + public void signalDone() { + int current = this.benchmarkState.signalDone(); + if (current == 0) { + synchronized (this) { + if (workersWaiting > 0) { + this.notifyAll(); } + } } - - public void signalDone() { - int current = this.benchmarkState.signalDone(); - if (current == 0) { - synchronized (this) { - if (workersWaiting > 0) { - this.notifyAll(); - } - } - } - } - - /** - * Called by ThreadPoolThreads when waiting for work. - */ - public SubmittedProcedure fetchWork() { - synchronized (this) { - if (currentPhase != null && currentPhase.isSerial()) { - ++workersWaiting; - while (getGlobalState() == State.LATENCY_COMPLETE) { - try { - this.wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - --workersWaiting; - - if (getGlobalState() == State.EXIT || getGlobalState() == State.DONE) { - return null; - } - - ++workersWorking; - return new SubmittedProcedure(currentPhase.chooseTransaction(getGlobalState() == State.COLD_QUERY)); - } + } + + /** Called by ThreadPoolThreads when waiting for work. */ + public SubmittedProcedure fetchWork() { + synchronized (this) { + if (currentPhase != null && currentPhase.isSerial()) { + ++workersWaiting; + while (getGlobalState() == State.LATENCY_COMPLETE) { + try { + this.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } + --workersWaiting; - // Unlimited-rate phases don't use the work queue. - if (currentPhase != null && !currentPhase.isRateLimited()) { - synchronized (this) { - ++workersWorking; - } - return new SubmittedProcedure(currentPhase.chooseTransaction(getGlobalState() == State.COLD_QUERY)); + if (getGlobalState() == State.EXIT || getGlobalState() == State.DONE) { + return null; } - synchronized (this) { - // Sleep until work is available. - if (workQueue.peek() == null) { - workersWaiting += 1; - while (workQueue.peek() == null) { - if (this.benchmarkState.getState() == State.EXIT - || this.benchmarkState.getState() == State.DONE) { - return null; - } - - try { - this.wait(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - workersWaiting -= 1; - } - - - ++workersWorking; - - return workQueue.remove(); - } + ++workersWorking; + return new SubmittedProcedure( + currentPhase.chooseTransaction(getGlobalState() == State.COLD_QUERY)); + } } - public void finishedWork() { - synchronized (this) { - - --workersWorking; - } + // Unlimited-rate phases don't use the work queue. + if (currentPhase != null && !currentPhase.isRateLimited()) { + synchronized (this) { + ++workersWorking; + } + return new SubmittedProcedure( + currentPhase.chooseTransaction(getGlobalState() == State.COLD_QUERY)); } - public Phase getNextPhase() { - if (phaseIterator.hasNext()) { - return phaseIterator.next(); + synchronized (this) { + // Sleep until work is available. + if (workQueue.peek() == null) { + workersWaiting += 1; + while (workQueue.peek() == null) { + if (this.benchmarkState.getState() == State.EXIT + || this.benchmarkState.getState() == State.DONE) { + return null; + } + + try { + this.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - return null; + workersWaiting -= 1; + } + + ++workersWorking; + + return workQueue.remove(); } + } - public Phase getCurrentPhase() { - synchronized (benchmarkState) { - return currentPhase; - } + public void finishedWork() { + synchronized (this) { + --workersWorking; } + } - /* - * Called by workers to ask if they should stay awake in this phase - */ - public void stayAwake() { - synchronized (this) { - while (workerNeedSleep > 0) { - workerNeedSleep--; - try { - this.wait(); - } catch (InterruptedException e) { - LOG.error(e.getMessage(), e); - } - } - } + public Phase getNextPhase() { + if (phaseIterator.hasNext()) { + return phaseIterator.next(); } + return null; + } - public void switchToNextPhase() { - synchronized (this) { - this.currentPhase = this.getNextPhase(); - - // Clear the work from the previous phase. - workQueue.clear(); - - // Determine how many workers need to sleep, then make sure they - // do. - if (this.currentPhase == null) - // Benchmark is over---wake everyone up so they can terminate - { - workerNeedSleep = 0; - } else { - this.currentPhase.resetSerial(); - if (this.currentPhase.isDisabled()) - // Phase disabled---everyone should sleep - { - workerNeedSleep = this.num_terminals; - } else - // Phase running---activate the appropriate # of terminals - { - workerNeedSleep = this.num_terminals - - this.currentPhase.getActiveTerminals(); - } - - } - - - this.notifyAll(); + public Phase getCurrentPhase() { + synchronized (benchmarkState) { + return currentPhase; + } + } + + /* + * Called by workers to ask if they should stay awake in this phase + */ + public void stayAwake() { + synchronized (this) { + while (workerNeedSleep > 0) { + workerNeedSleep--; + try { + this.wait(); + } catch (InterruptedException e) { + LOG.error(e.getMessage(), e); } + } } + } + + public void switchToNextPhase() { + synchronized (this) { + this.currentPhase = this.getNextPhase(); + + // Clear the work from the previous phase. + workQueue.clear(); + + // Determine how many workers need to sleep, then make sure they + // do. + if (this.currentPhase == null) + // Benchmark is over---wake everyone up so they can terminate + { + workerNeedSleep = 0; + } else { + this.currentPhase.resetSerial(); + if (this.currentPhase.isDisabled()) + // Phase disabled---everyone should sleep + { + workerNeedSleep = this.num_terminals; + } else + // Phase running---activate the appropriate # of terminals + { + workerNeedSleep = this.num_terminals - this.currentPhase.getActiveTerminals(); + } + } - /** - * Delegates pre-start blocking to the global state handler - */ - - public void blockForStart() { - benchmarkState.blockForStart(); + this.notifyAll(); } + } - /** - * Delegates a global state query to the benchmark state handler - * - * @return global state - */ - public State getGlobalState() { - return benchmarkState.getState(); - } + /** Delegates pre-start blocking to the global state handler */ + public void blockForStart() { + benchmarkState.blockForStart(); + } - public void signalLatencyComplete() { + /** + * Delegates a global state query to the benchmark state handler + * + * @return global state + */ + public State getGlobalState() { + return benchmarkState.getState(); + } - benchmarkState.signalLatencyComplete(); - } + public void signalLatencyComplete() { - public void startColdQuery() { + benchmarkState.signalLatencyComplete(); + } - benchmarkState.startColdQuery(); - } + public void startColdQuery() { - public void startHotQuery() { + benchmarkState.startColdQuery(); + } - benchmarkState.startHotQuery(); - } + public void startHotQuery() { - public long getTestStartNs() { - return benchmarkState.getTestStartNs(); - } + benchmarkState.startHotQuery(); + } + public long getTestStartNs() { + return benchmarkState.getTestStartNs(); + } } diff --git a/src/main/java/com/oltpbenchmark/api/BenchmarkModule.java b/src/main/java/com/oltpbenchmark/api/BenchmarkModule.java index 6f5fa69f6..e36752407 100644 --- a/src/main/java/com/oltpbenchmark/api/BenchmarkModule.java +++ b/src/main/java/com/oltpbenchmark/api/BenchmarkModule.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.api; import com.oltpbenchmark.WorkloadConfiguration; @@ -25,392 +24,377 @@ import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.ScriptRunner; import com.oltpbenchmark.util.ThreadUtil; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.*; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** - * Base class for all benchmark implementations - */ +/** Base class for all benchmark implementations */ public abstract class BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(BenchmarkModule.class); - - - /** - * The workload configuration for this benchmark invocation - */ - protected final WorkloadConfiguration workConf; - - /** - * Class loader variable for this benchmark - */ - protected ClassLoader classLoader; - - /** - * These are the variations of the Procedure's Statement SQL - */ - protected final StatementDialects dialects; - - /** - * Supplemental Procedures - */ - private final Set> supplementalProcedures = new HashSet<>(); - - /** - * A single Random object that should be re-used by all a benchmark's components - */ - private static final ThreadLocal rng = new ThreadLocal<>(); - - private AbstractCatalog catalog = null; - - /** - * Constructor! - * @param workConf - */ - public BenchmarkModule(WorkloadConfiguration workConf) { - this.workConf = workConf; - this.dialects = new StatementDialects(workConf); - // setClassLoader(); - this.classLoader = ClassLoader.getSystemClassLoader(); - } - - /** - * Instantiates the classLoader variable, needs to be overwritten if - * benchmark uses a custom implementation. - */ - protected void setClassLoader() { - this.classLoader = ClassLoader.getSystemClassLoader(); - } - - // -------------------------------------------------------------------------- - // DATABASE CONNECTION - // -------------------------------------------------------------------------- - - public final Connection makeConnection() throws SQLException { - - if (StringUtils.isEmpty(workConf.getUsername())) { - return DriverManager.getConnection(workConf.getUrl()); - } else { - return DriverManager.getConnection( - workConf.getUrl(), - workConf.getUsername(), - workConf.getPassword()); - } + private static final Logger LOG = LoggerFactory.getLogger(BenchmarkModule.class); + + /** The workload configuration for this benchmark invocation */ + protected final WorkloadConfiguration workConf; + + /** Class loader variable for this benchmark */ + protected ClassLoader classLoader; + + /** These are the variations of the Procedure's Statement SQL */ + protected final StatementDialects dialects; + + /** Supplemental Procedures */ + private final Set> supplementalProcedures = new HashSet<>(); + + /** A single Random object that should be re-used by all a benchmark's components */ + private static final ThreadLocal rng = new ThreadLocal<>(); + + private AbstractCatalog catalog = null; + + /** + * Constructor! + * + * @param workConf + */ + public BenchmarkModule(WorkloadConfiguration workConf) { + this.workConf = workConf; + this.dialects = new StatementDialects(workConf); + // setClassLoader(); + this.classLoader = ClassLoader.getSystemClassLoader(); + } + + /** + * Instantiates the classLoader variable, needs to be overwritten if benchmark uses a custom + * implementation. + */ + protected void setClassLoader() { + this.classLoader = ClassLoader.getSystemClassLoader(); + } + + // -------------------------------------------------------------------------- + // DATABASE CONNECTION + // -------------------------------------------------------------------------- + + public final Connection makeConnection() throws SQLException { + + if (StringUtils.isEmpty(workConf.getUsername())) { + return DriverManager.getConnection(workConf.getUrl()); + } else { + return DriverManager.getConnection( + workConf.getUrl(), workConf.getUsername(), workConf.getPassword()); } - - private String afterLoadScriptPath = null; - - public final void setAfterLoadScriptPath(String scriptPath) { - this.afterLoadScriptPath = scriptPath; - } - - // -------------------------------------------------------------------------- - // IMPLEMENTING CLASS INTERFACE - // -------------------------------------------------------------------------- - - /** - * @return - * @throws IOException - */ - protected abstract List> makeWorkersImpl() throws IOException; - - /** - * Each BenchmarkModule needs to implement this method to load a sample - * dataset into the database. The Connection handle will already be - * configured for you, and the base class will commit+close it once this - * method returns - * - * @return TODO - */ - protected abstract Loader makeLoaderImpl(); - - protected abstract Package getProcedurePackageImpl(); - - // -------------------------------------------------------------------------- - // PUBLIC INTERFACE - // -------------------------------------------------------------------------- - - /** - * Return the Random generator that should be used by all this benchmark's components. - * We are using ThreadLocal to make this support multiple threads better. - * This will set the seed if one is specified in the workload config file - */ - public Random rng() { - Random ret = rng.get(); - if (ret == null) { - if (this.workConf.getRandomSeed() != -1) { - ret = new Random(this.workConf.getRandomSeed()); - } else { - ret = new Random(); - } - rng.set(ret); - } - return ret; + } + + private String afterLoadScriptPath = null; + + public final void setAfterLoadScriptPath(String scriptPath) { + this.afterLoadScriptPath = scriptPath; + } + + // -------------------------------------------------------------------------- + // IMPLEMENTING CLASS INTERFACE + // -------------------------------------------------------------------------- + + /** + * @return + * @throws IOException + */ + protected abstract List> makeWorkersImpl() throws IOException; + + /** + * Each BenchmarkModule needs to implement this method to load a sample dataset into the database. + * The Connection handle will already be configured for you, and the base class will commit+close + * it once this method returns + * + * @return TODO + */ + protected abstract Loader makeLoaderImpl(); + + protected abstract Package getProcedurePackageImpl(); + + // -------------------------------------------------------------------------- + // PUBLIC INTERFACE + // -------------------------------------------------------------------------- + + /** + * Return the Random generator that should be used by all this benchmark's components. We are + * using ThreadLocal to make this support multiple threads better. This will set the seed if one + * is specified in the workload config file + */ + public Random rng() { + Random ret = rng.get(); + if (ret == null) { + if (this.workConf.getRandomSeed() != -1) { + ret = new Random(this.workConf.getRandomSeed()); + } else { + ret = new Random(); + } + rng.set(ret); } - - private String convertBenchmarkClassToBenchmarkName() { - return convertBenchmarkClassToBenchmarkName(this.getClass()); + return ret; + } + + private String convertBenchmarkClassToBenchmarkName() { + return convertBenchmarkClassToBenchmarkName(this.getClass()); + } + + protected static String convertBenchmarkClassToBenchmarkName(Class clazz) { + assert (clazz != null); + String name = clazz.getSimpleName().toLowerCase(); + // Special case for "CHBenCHmark" + if (!name.equals("chbenchmark") && name.endsWith("benchmark")) { + name = name.replace("benchmark", ""); } - - protected static String convertBenchmarkClassToBenchmarkName(Class clazz) { - assert(clazz != null); - String name = clazz.getSimpleName().toLowerCase(); - // Special case for "CHBenCHmark" - if (!name.equals("chbenchmark") && name.endsWith("benchmark")) { - name = name.replace("benchmark", ""); - } - return (name); + return (name); + } + + /** + * Return the URL handle to the DDL used to load the benchmark's database schema. + * + * @param db_type + */ + public String getDatabaseDDLPath(DatabaseType db_type) { + + // The order matters! + List names = new ArrayList<>(); + if (db_type != null) { + DatabaseType ddl_db_type = db_type; + // HACK: Use MySQL if we're given MariaDB + if (ddl_db_type == DatabaseType.MARIADB) ddl_db_type = DatabaseType.MYSQL; + names.add("ddl-" + ddl_db_type.name().toLowerCase() + ".sql"); } + names.add("ddl-generic.sql"); - /** - * Return the URL handle to the DDL used to load the benchmark's database - * schema. - * - * @param db_type - */ - public String getDatabaseDDLPath(DatabaseType db_type) { - - // The order matters! - List names = new ArrayList<>(); - if (db_type != null) { - DatabaseType ddl_db_type = db_type; - // HACK: Use MySQL if we're given MariaDB - if (ddl_db_type == DatabaseType.MARIADB) ddl_db_type = DatabaseType.MYSQL; - names.add("ddl-" + ddl_db_type.name().toLowerCase() + ".sql"); - } - names.add("ddl-generic.sql"); + for (String fileName : names) { + final String benchmarkName = getBenchmarkName(); + final String path = "/benchmarks/" + benchmarkName + "/" + fileName; - for (String fileName : names) { - final String benchmarkName = getBenchmarkName(); - final String path = "/benchmarks/" + benchmarkName + "/" + fileName; - - try (InputStream stream = this.getClass().getResourceAsStream(path)) { - if (stream != null) { - return path; - } - - } catch (IOException e) { - LOG.error(e.getMessage(), e); - } + try (InputStream stream = this.getClass().getResourceAsStream(path)) { + if (stream != null) { + return path; } - - return null; + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } } + return null; + } - public final List> makeWorkers() throws IOException { - return (this.makeWorkersImpl()); - } + public final List> makeWorkers() throws IOException { + return (this.makeWorkersImpl()); + } - public final void refreshCatalog() throws SQLException { - if (this.catalog != null) { - try { - this.catalog.close(); - } catch (SQLException throwables) { - LOG.error(throwables.getMessage(), throwables); - } - } - try (Connection conn = this.makeConnection()) { - this.catalog = SQLUtil.getCatalog(this, this.getWorkloadConfiguration().getDatabaseType(), conn); - } + public final void refreshCatalog() throws SQLException { + if (this.catalog != null) { + try { + this.catalog.close(); + } catch (SQLException throwables) { + LOG.error(throwables.getMessage(), throwables); + } } - - /** - * Create the Benchmark Database - * This is the main method used to create all the database - * objects (e.g., table, indexes, etc) needed for this benchmark - */ - public final void createDatabase() throws SQLException, IOException { - try (Connection conn = this.makeConnection()) { - this.createDatabase(this.workConf.getDatabaseType(), conn); - } + try (Connection conn = this.makeConnection()) { + this.catalog = + SQLUtil.getCatalog(this, this.getWorkloadConfiguration().getDatabaseType(), conn); } - - /** - * Create the Benchmark Database - * This is the main method used to create all the database - * objects (e.g., table, indexes, etc) needed for this benchmark - */ - public final void createDatabase(DatabaseType dbType, Connection conn) throws SQLException, IOException { - - ScriptRunner runner = new ScriptRunner(conn, true, true); - - if (workConf.getDDLPath() != null) { - String ddlPath = workConf.getDDLPath(); - LOG.warn("Overriding default DDL script path"); - LOG.debug("Executing script [{}] for database type [{}]", ddlPath, dbType); - runner.runExternalScript(ddlPath); - } else { - String ddlPath = this.getDatabaseDDLPath(dbType); - LOG.debug("Executing script [{}] for database type [{}]", ddlPath, dbType); - runner.runScript(ddlPath); - } + } + + /** + * Create the Benchmark Database This is the main method used to create all the database objects + * (e.g., table, indexes, etc) needed for this benchmark + */ + public final void createDatabase() throws SQLException, IOException { + try (Connection conn = this.makeConnection()) { + this.createDatabase(this.workConf.getDatabaseType(), conn); } - - public final void runScript(String scriptPath) throws SQLException, IOException { - try (Connection conn = this.makeConnection()) { - DatabaseType dbType = this.workConf.getDatabaseType(); - ScriptRunner runner = new ScriptRunner(conn, true, true); - LOG.debug("Executing script [{}] for database type [{}]", scriptPath, dbType); - runner.runScript(scriptPath); - } + } + + /** + * Create the Benchmark Database This is the main method used to create all the database objects + * (e.g., table, indexes, etc) needed for this benchmark + */ + public final void createDatabase(DatabaseType dbType, Connection conn) + throws SQLException, IOException { + + ScriptRunner runner = new ScriptRunner(conn, true, true); + + if (workConf.getDDLPath() != null) { + String ddlPath = workConf.getDDLPath(); + LOG.warn("Overriding default DDL script path"); + LOG.debug("Executing script [{}] for database type [{}]", ddlPath, dbType); + runner.runExternalScript(ddlPath); + } else { + String ddlPath = this.getDatabaseDDLPath(dbType); + LOG.debug("Executing script [{}] for database type [{}]", ddlPath, dbType); + runner.runScript(ddlPath); } + } + + public final void runScript(String scriptPath) throws SQLException, IOException { + try (Connection conn = this.makeConnection()) { + DatabaseType dbType = this.workConf.getDatabaseType(); + ScriptRunner runner = new ScriptRunner(conn, true, true); + LOG.debug("Executing script [{}] for database type [{}]", scriptPath, dbType); + runner.runScript(scriptPath); + } + } - /** - * Invoke this benchmark's database loader - */ - public final Loader loadDatabase() throws IOException, SQLException, InterruptedException { - Loader loader; - - loader = this.makeLoaderImpl(); - if (loader != null) { + /** Invoke this benchmark's database loader */ + public final Loader loadDatabase() + throws IOException, SQLException, InterruptedException { + Loader loader; + loader = this.makeLoaderImpl(); + if (loader != null) { - try { - List loaderThreads = loader.createLoaderThreads(); - int maxConcurrent = workConf.getLoaderThreads(); + try { + List loaderThreads = loader.createLoaderThreads(); + int maxConcurrent = workConf.getLoaderThreads(); - ThreadUtil.runLoaderThreads(loaderThreads, maxConcurrent); + ThreadUtil.runLoaderThreads(loaderThreads, maxConcurrent); - if (!loader.getTableCounts().isEmpty()) { - LOG.debug("Table Counts:\n{}", loader.getTableCounts()); - } - } finally { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Finished loading the %s database", this.getBenchmarkName().toUpperCase())); - } - } + if (!loader.getTableCounts().isEmpty()) { + LOG.debug("Table Counts:\n{}", loader.getTableCounts()); } - - if (this.afterLoadScriptPath != null) { - LOG.debug("Running script after load for {} benchmark...", this.workConf.getBenchmarkName().toUpperCase()); - runScript(this.afterLoadScriptPath); - LOG.debug("Finished running script after load for {} benchmark...", this.workConf.getBenchmarkName().toUpperCase()); - } - - return loader; - } - - public final void clearDatabase() throws SQLException { - - try (Connection conn = this.makeConnection()) { - Loader loader = this.makeLoaderImpl(); - if (loader != null) { - conn.setAutoCommit(false); - loader.unload(conn, this.catalog); - conn.commit(); - } + } finally { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Finished loading the %s database", this.getBenchmarkName().toUpperCase())); } + } } - // -------------------------------------------------------------------------- - // UTILITY METHODS - // -------------------------------------------------------------------------- - - /** - * Return the unique identifier for this benchmark - */ - public final String getBenchmarkName() { - String workConfName = this.workConf.getBenchmarkName(); - return workConfName != null ? workConfName : convertBenchmarkClassToBenchmarkName(); - } - - /** - * Return the database's catalog - */ - public final AbstractCatalog getCatalog() { - - if (catalog == null) { - throw new RuntimeException("getCatalog() has been called before refreshCatalog()"); - } - - return this.catalog; + if (this.afterLoadScriptPath != null) { + LOG.debug( + "Running script after load for {} benchmark...", + this.workConf.getBenchmarkName().toUpperCase()); + runScript(this.afterLoadScriptPath); + LOG.debug( + "Finished running script after load for {} benchmark...", + this.workConf.getBenchmarkName().toUpperCase()); } + return loader; + } - /** - * Return the StatementDialects loaded for this benchmark - */ - public final StatementDialects getStatementDialects() { - return (this.dialects); - } + public final void clearDatabase() throws SQLException { - @Override - public final String toString() { - return getBenchmarkName(); + try (Connection conn = this.makeConnection()) { + Loader loader = this.makeLoaderImpl(); + if (loader != null) { + conn.setAutoCommit(false); + loader.unload(conn, this.catalog); + conn.commit(); + } } + } + // -------------------------------------------------------------------------- + // UTILITY METHODS + // -------------------------------------------------------------------------- - /** - * Initialize a TransactionType handle for the get procedure name and id - * This should only be invoked a start-up time - * - * @param procName - * @param id - * @return - */ - @SuppressWarnings("unchecked") - public final TransactionType initTransactionType(String procName, int id, long preExecutionWait, long postExecutionWait) { - if (id == TransactionType.INVALID_ID) { - throw new RuntimeException(String.format("Procedure %s.%s cannot use the reserved id '%d' for %s", getBenchmarkName(), procName, id, TransactionType.INVALID.getClass().getSimpleName())); - } - - Package pkg = this.getProcedurePackageImpl(); + /** Return the unique identifier for this benchmark */ + public final String getBenchmarkName() { + String workConfName = this.workConf.getBenchmarkName(); + return workConfName != null ? workConfName : convertBenchmarkClassToBenchmarkName(); + } - String fullName = pkg.getName() + "." + procName; - Class procClass = (Class) ClassUtil.getClass(this.classLoader, fullName); + /** Return the database's catalog */ + public final AbstractCatalog getCatalog() { - return new TransactionType(procClass, id, false, preExecutionWait, postExecutionWait); + if (catalog == null) { + throw new RuntimeException("getCatalog() has been called before refreshCatalog()"); } - public final WorkloadConfiguration getWorkloadConfiguration() { - return (this.workConf); + return this.catalog; + } + + /** Return the StatementDialects loaded for this benchmark */ + public final StatementDialects getStatementDialects() { + return (this.dialects); + } + + @Override + public final String toString() { + return getBenchmarkName(); + } + + /** + * Initialize a TransactionType handle for the get procedure name and id This should only be + * invoked a start-up time + * + * @param procName + * @param id + * @return + */ + @SuppressWarnings("unchecked") + public final TransactionType initTransactionType( + String procName, int id, long preExecutionWait, long postExecutionWait) { + if (id == TransactionType.INVALID_ID) { + throw new RuntimeException( + String.format( + "Procedure %s.%s cannot use the reserved id '%d' for %s", + getBenchmarkName(), + procName, + id, + TransactionType.INVALID.getClass().getSimpleName())); } - /** - * Return a mapping from TransactionTypes to Procedure invocations - * - * @return - */ - public Map getProcedures() { - Map proc_xref = new HashMap<>(); - TransactionTypes txns = this.workConf.getTransTypes(); - - if (txns != null) { - for (Class procClass : this.supplementalProcedures) { - TransactionType txn = txns.getType(procClass); - if (txn == null) { - txn = new TransactionType(procClass, procClass.hashCode(), true, 0, 0); - txns.add(txn); - } - } - - for (TransactionType txn : txns) { - Procedure proc = ClassUtil.newInstance(txn.getProcedureClass(), new Object[0], new Class[0]); - proc.initialize(this.workConf.getDatabaseType()); - proc_xref.put(txn, proc); - proc.loadSQLDialect(this.dialects); - } + Package pkg = this.getProcedurePackageImpl(); + + String fullName = pkg.getName() + "." + procName; + Class procClass = + (Class) ClassUtil.getClass(this.classLoader, fullName); + + return new TransactionType(procClass, id, false, preExecutionWait, postExecutionWait); + } + + public final WorkloadConfiguration getWorkloadConfiguration() { + return (this.workConf); + } + + /** + * Return a mapping from TransactionTypes to Procedure invocations + * + * @return + */ + public Map getProcedures() { + Map proc_xref = new HashMap<>(); + TransactionTypes txns = this.workConf.getTransTypes(); + + if (txns != null) { + for (Class procClass : this.supplementalProcedures) { + TransactionType txn = txns.getType(procClass); + if (txn == null) { + txn = new TransactionType(procClass, procClass.hashCode(), true, 0, 0); + txns.add(txn); } - if (proc_xref.isEmpty()) { - LOG.warn("No procedures defined for {}", this); - } - return (proc_xref); + } + + for (TransactionType txn : txns) { + Procedure proc = + ClassUtil.newInstance(txn.getProcedureClass(), new Object[0], new Class[0]); + proc.initialize(this.workConf.getDatabaseType()); + proc_xref.put(txn, proc); + proc.loadSQLDialect(this.dialects); + } } - - /** - * @param procClass - */ - public final void registerSupplementalProcedure(Class procClass) { - this.supplementalProcedures.add(procClass); + if (proc_xref.isEmpty()) { + LOG.warn("No procedures defined for {}", this); } - + return (proc_xref); + } + + /** + * @param procClass + */ + public final void registerSupplementalProcedure(Class procClass) { + this.supplementalProcedures.add(procClass); + } } diff --git a/src/main/java/com/oltpbenchmark/api/Loader.java b/src/main/java/com/oltpbenchmark/api/Loader.java index abdbd75f6..dfbeb454d 100644 --- a/src/main/java/com/oltpbenchmark/api/Loader.java +++ b/src/main/java/com/oltpbenchmark/api/Loader.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.api; import com.oltpbenchmark.WorkloadConfiguration; @@ -25,121 +24,118 @@ import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.Histogram; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author pavlo */ public abstract class Loader { - protected static final Logger LOG = LoggerFactory.getLogger(Loader.class); - - protected final T benchmark; - - protected final WorkloadConfiguration workConf; - protected final double scaleFactor; - private final Histogram tableSizes = new Histogram<>(true); - - public Loader(T benchmark) { - this.benchmark = benchmark; - this.workConf = benchmark.getWorkloadConfiguration(); - this.scaleFactor = workConf.getScaleFactor(); - } - - /** - * Each Loader will generate a list of Runnable objects that - * will perform the loading operation for the benchmark. - * The number of threads that will be launched at the same time - * depends on the number of cores that are available. But they are - * guaranteed to execute in the order specified in the list. - * You will have to use your own protections if there are dependencies between - * threads (i.e., if one table needs to be loaded before another). - *

- * Each LoaderThread will be given a Connection handle to the DBMS when - * it is invoked. - *

- * If the benchmark does not support multi-threaded loading yet, - * then this method should return null. - * - * @return The list of LoaderThreads the framework will launch. - */ - public abstract List createLoaderThreads() throws SQLException; - - public void addToTableCount(String tableName, int delta) { - this.tableSizes.put(tableName, delta); + protected static final Logger LOG = LoggerFactory.getLogger(Loader.class); + + protected final T benchmark; + + protected final WorkloadConfiguration workConf; + protected final double scaleFactor; + private final Histogram tableSizes = new Histogram<>(true); + + public Loader(T benchmark) { + this.benchmark = benchmark; + this.workConf = benchmark.getWorkloadConfiguration(); + this.scaleFactor = workConf.getScaleFactor(); + } + + /** + * Each Loader will generate a list of Runnable objects that will perform the loading operation + * for the benchmark. The number of threads that will be launched at the same time depends on the + * number of cores that are available. But they are guaranteed to execute in the order specified + * in the list. You will have to use your own protections if there are dependencies between + * threads (i.e., if one table needs to be loaded before another). + * + *

Each LoaderThread will be given a Connection handle to the DBMS when it is invoked. + * + *

If the benchmark does not support multi-threaded loading yet, then this method should + * return null. + * + * @return The list of LoaderThreads the framework will launch. + */ + public abstract List createLoaderThreads() throws SQLException; + + public void addToTableCount(String tableName, int delta) { + this.tableSizes.put(tableName, delta); + } + + public Histogram getTableCounts() { + return (this.tableSizes); + } + + public DatabaseType getDatabaseType() { + return (this.workConf.getDatabaseType()); + } + + /** + * Get the pre-seeded Random generator for this Loader invocation + * + * @return + */ + public Random rng() { + return (this.benchmark.rng()); + } + + /** + * Method that can be overriden to specifically unload the tables of the database. In the default + * implementation it checks for tables from the catalog to delete them using SQL. Any subclass can + * inject custom behavior here. + * + * @param catalog The catalog containing all loaded tables + * @throws SQLException + */ + public void unload(Connection conn, AbstractCatalog catalog) throws SQLException { + + boolean shouldEscapeNames = this.getDatabaseType().shouldEscapeNames(); + + try (Statement st = conn.createStatement()) { + for (Table catalog_tbl : catalog.getTables()) { + String tableName = shouldEscapeNames ? catalog_tbl.getEscapedName() : catalog_tbl.getName(); + LOG.debug(String.format("Deleting data from table [%s]", tableName)); + + String sql = "DELETE FROM " + tableName; + st.execute(sql); + } } - - public Histogram getTableCounts() { - return (this.tableSizes); + } + + protected void updateAutoIncrement(Connection conn, Column catalog_col, int value) + throws SQLException { + String sql = null; + String seqName = SQLUtil.getSequenceName(conn, getDatabaseType(), catalog_col); + DatabaseType dbType = getDatabaseType(); + if (seqName != null) { + if (dbType == DatabaseType.POSTGRES) { + sql = String.format("SELECT setval('%s', %d)", seqName.toLowerCase(), value); + } else if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { + sql = String.format("ALTER SEQUENCE [%s] RESTART WITH %d", seqName, value); + } } - public DatabaseType getDatabaseType() { - return (this.workConf.getDatabaseType()); - } - - /** - * Get the pre-seeded Random generator for this Loader invocation - * - * @return - */ - public Random rng() { - return (this.benchmark.rng()); - } - - - /** - * Method that can be overriden to specifically unload the tables of the - * database. In the default implementation it checks for tables from the - * catalog to delete them using SQL. Any subclass can inject custom behavior - * here. - * - * @param catalog The catalog containing all loaded tables - * @throws SQLException - */ - public void unload(Connection conn, AbstractCatalog catalog) throws SQLException { - - boolean shouldEscapeNames = this.getDatabaseType().shouldEscapeNames(); - - try (Statement st = conn.createStatement()) { - for (Table catalog_tbl : catalog.getTables()) { - String tableName = shouldEscapeNames ? catalog_tbl.getEscapedName() : catalog_tbl.getName(); - LOG.debug(String.format("Deleting data from table [%s]", tableName)); - - String sql = "DELETE FROM " + tableName; - st.execute(sql); - } - } - } - - protected void updateAutoIncrement(Connection conn, Column catalog_col, int value) throws SQLException { - String sql = null; - String seqName = SQLUtil.getSequenceName(conn, getDatabaseType(), catalog_col); - DatabaseType dbType = getDatabaseType(); - if (seqName != null) { - if (dbType == DatabaseType.POSTGRES) { - sql = String.format("SELECT setval('%s', %d)", seqName.toLowerCase(), value); - } - else if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { - sql = String.format("ALTER SEQUENCE [%s] RESTART WITH %d", seqName, value); - } - } - - if (sql != null) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Updating %s auto-increment counter %s with value '%d'", catalog_col.getName(), seqName, value)); - } - try (Statement stmt = conn.createStatement()) { - boolean result = stmt.execute(sql); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s => [%s]", sql, result)); - } - } + if (sql != null) { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Updating %s auto-increment counter %s with value '%d'", + catalog_col.getName(), seqName, value)); + } + try (Statement stmt = conn.createStatement()) { + boolean result = stmt.execute(sql); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s => [%s]", sql, result)); } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/api/LoaderThread.java b/src/main/java/com/oltpbenchmark/api/LoaderThread.java index 50f4ba9c3..f60d857eb 100644 --- a/src/main/java/com/oltpbenchmark/api/LoaderThread.java +++ b/src/main/java/com/oltpbenchmark/api/LoaderThread.java @@ -17,57 +17,57 @@ package com.oltpbenchmark.api; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * A LoaderThread is responsible for loading some portion of a - * benchmark's database. - * Note that each LoaderThread has its own database Connection handle. + * A LoaderThread is responsible for loading some portion of a benchmark's database. Note that each + * LoaderThread has its own database Connection handle. */ public abstract class LoaderThread implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger(LoaderThread.class); + private static final Logger LOG = LoggerFactory.getLogger(LoaderThread.class); - private final BenchmarkModule benchmarkModule; + private final BenchmarkModule benchmarkModule; - public LoaderThread(BenchmarkModule benchmarkModule) { - this.benchmarkModule = benchmarkModule; - } + public LoaderThread(BenchmarkModule benchmarkModule) { + this.benchmarkModule = benchmarkModule; + } - @Override - public final void run() { - beforeLoad(); - try (Connection conn = benchmarkModule.makeConnection()) { - load(conn); - } catch (SQLException ex) { - SQLException next_ex = ex.getNextException(); - String msg = String.format("Unexpected error when loading %s database", benchmarkModule.getBenchmarkName().toUpperCase()); - LOG.error(msg, next_ex); - throw new RuntimeException(ex); - } finally { - afterLoad(); - } + @Override + public final void run() { + beforeLoad(); + try (Connection conn = benchmarkModule.makeConnection()) { + load(conn); + } catch (SQLException ex) { + SQLException next_ex = ex.getNextException(); + String msg = + String.format( + "Unexpected error when loading %s database", + benchmarkModule.getBenchmarkName().toUpperCase()); + LOG.error(msg, next_ex); + throw new RuntimeException(ex); + } finally { + afterLoad(); } + } - /** - * This is the method that each LoaderThread has to implement - * - * @param conn - * @throws SQLException - */ - public abstract void load(Connection conn) throws SQLException; - - public void beforeLoad() { - // useful for implementing waits for countdown latches, this ensures we open the connection right before its used to avoid stale connections - } - - public void afterLoad() { - // useful for counting down latches - } + /** + * This is the method that each LoaderThread has to implement + * + * @param conn + * @throws SQLException + */ + public abstract void load(Connection conn) throws SQLException; + public void beforeLoad() { + // useful for implementing waits for countdown latches, this ensures we open the connection + // right before its used to avoid stale connections + } + public void afterLoad() { + // useful for counting down latches + } } diff --git a/src/main/java/com/oltpbenchmark/api/Operation.java b/src/main/java/com/oltpbenchmark/api/Operation.java index e56713dd4..cc2311aaf 100644 --- a/src/main/java/com/oltpbenchmark/api/Operation.java +++ b/src/main/java/com/oltpbenchmark/api/Operation.java @@ -17,6 +17,4 @@ package com.oltpbenchmark.api; -public abstract class Operation { - -} +public abstract class Operation {} diff --git a/src/main/java/com/oltpbenchmark/api/Procedure.java b/src/main/java/com/oltpbenchmark/api/Procedure.java index fa9c711a8..bc55a958e 100644 --- a/src/main/java/com/oltpbenchmark/api/Procedure.java +++ b/src/main/java/com/oltpbenchmark/api/Procedure.java @@ -19,9 +19,6 @@ import com.oltpbenchmark.jdbc.AutoIncrementPreparedStatement; import com.oltpbenchmark.types.DatabaseType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.sql.Connection; @@ -31,194 +28,193 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class Procedure { - private static final Logger LOG = LoggerFactory.getLogger(Procedure.class); - - private final String procName; - private DatabaseType dbType; - - public DatabaseType getDbType() { - return dbType; + private static final Logger LOG = LoggerFactory.getLogger(Procedure.class); + + private final String procName; + private DatabaseType dbType; + + public DatabaseType getDbType() { + return dbType; + } + + private Map name_stmt_xref; + + /** Constructor */ + protected Procedure() { + this.procName = this.getClass().getSimpleName(); + } + + /** + * Initialize all of the SQLStmt handles. This must be called separately from the constructor, + * otherwise we can't get access to all of our SQLStmts. + * + * @param + * @return + */ + @SuppressWarnings("unchecked") + protected final T initialize(DatabaseType dbType) { + this.dbType = dbType; + this.name_stmt_xref = Procedure.getStatements(this); + + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Initialized %s with %d SQLStmts: %s", + this, this.name_stmt_xref.size(), this.name_stmt_xref.keySet())); } - - private Map name_stmt_xref; - - /** - * Constructor - */ - protected Procedure() { - this.procName = this.getClass().getSimpleName(); + return ((T) this); + } + + /** Return the name of this Procedure */ + protected final String getProcedureName() { + return (this.procName); + } + + /** + * Return a PreparedStatement for the given SQLStmt handle The underlying Procedure API will make + * sure that the proper SQL for the target DBMS is used for this SQLStmt. This will automatically + * call setObject for all the parameters you pass in + * + * @param conn + * @param stmt + * @param params + * @return + * @throws SQLException + */ + public final PreparedStatement getPreparedStatement( + Connection conn, SQLStmt stmt, Object... params) throws SQLException { + PreparedStatement pStmt = this.getPreparedStatementReturnKeys(conn, stmt, null); + for (int i = 0; i < params.length; i++) { + pStmt.setObject(i + 1, params[i]); } - - /** - * Initialize all of the SQLStmt handles. This must be called separately from - * the constructor, otherwise we can't get access to all of our SQLStmts. - * - * @param - * @return - */ - @SuppressWarnings("unchecked") - protected final T initialize(DatabaseType dbType) { - this.dbType = dbType; - this.name_stmt_xref = Procedure.getStatements(this); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Initialized %s with %d SQLStmts: %s", - this, this.name_stmt_xref.size(), this.name_stmt_xref.keySet())); - } - return ((T) this); + return (pStmt); + } + + /** + * Return a PreparedStatement for the given SQLStmt handle The underlying Procedure API will make + * sure that the proper SQL for the target DBMS is used for this SQLStmt. + * + * @param conn + * @param stmt + * @param is + * @return + * @throws SQLException + */ + public final PreparedStatement getPreparedStatementReturnKeys( + Connection conn, SQLStmt stmt, int[] is) throws SQLException { + + PreparedStatement pStmt = null; + + // HACK: If the target system is Postgres, wrap the PreparedStatement in a special + // one that fakes the getGeneratedKeys(). + if (is != null + && (this.dbType == DatabaseType.POSTGRES + || this.dbType == DatabaseType.COCKROACHDB + || this.dbType == DatabaseType.SQLSERVER + || this.dbType == DatabaseType.SQLAZURE)) { + pStmt = new AutoIncrementPreparedStatement(this.dbType, conn.prepareStatement(stmt.getSQL())); } - - /** - * Return the name of this Procedure - */ - protected final String getProcedureName() { - return (this.procName); + // Everyone else can use the regular getGeneratedKeys() method + else if (is != null) { + pStmt = conn.prepareStatement(stmt.getSQL(), is); } - - /** - * Return a PreparedStatement for the given SQLStmt handle - * The underlying Procedure API will make sure that the proper SQL - * for the target DBMS is used for this SQLStmt. - * This will automatically call setObject for all the parameters you pass in - * - * @param conn - * @param stmt - * @param params - * @return - * @throws SQLException - */ - public final PreparedStatement getPreparedStatement(Connection conn, SQLStmt stmt, Object... params) throws SQLException { - PreparedStatement pStmt = this.getPreparedStatementReturnKeys(conn, stmt, null); - for (int i = 0; i < params.length; i++) { - pStmt.setObject(i + 1, params[i]); - } - return (pStmt); + // They don't care about keys + else { + pStmt = conn.prepareStatement(stmt.getSQL()); } - /** - * Return a PreparedStatement for the given SQLStmt handle - * The underlying Procedure API will make sure that the proper SQL - * for the target DBMS is used for this SQLStmt. - * - * @param conn - * @param stmt - * @param is - * @return - * @throws SQLException - */ - public final PreparedStatement getPreparedStatementReturnKeys(Connection conn, SQLStmt stmt, int[] is) throws SQLException { - - PreparedStatement pStmt = null; - - // HACK: If the target system is Postgres, wrap the PreparedStatement in a special - // one that fakes the getGeneratedKeys(). - if (is != null && ( - this.dbType == DatabaseType.POSTGRES - || this.dbType == DatabaseType.COCKROACHDB - || this.dbType == DatabaseType.SQLSERVER - || this.dbType == DatabaseType.SQLAZURE - ) - ) { - pStmt = new AutoIncrementPreparedStatement(this.dbType, conn.prepareStatement(stmt.getSQL())); - } - // Everyone else can use the regular getGeneratedKeys() method - else if (is != null) { - pStmt = conn.prepareStatement(stmt.getSQL(), is); - } - // They don't care about keys - else { - pStmt = conn.prepareStatement(stmt.getSQL()); - } - - return (pStmt); - } - - /** - * Fetch the SQL from the dialect map - * - * @param dialects - */ - protected final void loadSQLDialect(StatementDialects dialects) { - Collection stmtNames = dialects.getStatementNames(this.procName); - if (stmtNames == null) { - return; - } - for (String stmtName : stmtNames) { - String sql = dialects.getSQL(this.procName, stmtName); - - - SQLStmt stmt = this.name_stmt_xref.get(stmtName); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Setting %s SQL dialect for %s.%s", - dialects.getDatabaseType(), this.procName, stmtName)); - } - if (stmt == null) { - throw new RuntimeException(String.format("Dialect file contains an unknown statement: Procedure %s, Statement %s", this.procName, stmtName)); - } - stmt.setSQL(sql); - } + return (pStmt); + } + + /** + * Fetch the SQL from the dialect map + * + * @param dialects + */ + protected final void loadSQLDialect(StatementDialects dialects) { + Collection stmtNames = dialects.getStatementNames(this.procName); + if (stmtNames == null) { + return; } - - /** - * Hook for testing - * - * @return - */ - protected final Map getStatements() { - return (Collections.unmodifiableMap(this.name_stmt_xref)); + for (String stmtName : stmtNames) { + String sql = dialects.getSQL(this.procName, stmtName); + + SQLStmt stmt = this.name_stmt_xref.get(stmtName); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Setting %s SQL dialect for %s.%s", + dialects.getDatabaseType(), this.procName, stmtName)); + } + if (stmt == null) { + throw new RuntimeException( + String.format( + "Dialect file contains an unknown statement: Procedure %s, Statement %s", + this.procName, stmtName)); + } + stmt.setSQL(sql); } - - protected static Map getStatements(Procedure proc) { - Class c = proc.getClass(); - Map stmts = new HashMap<>(); - for (Field f : c.getDeclaredFields()) { - int modifiers = f.getModifiers(); - if (!Modifier.isTransient(modifiers) && - Modifier.isPublic(modifiers) && - !Modifier.isStatic(modifiers)) { - try { - Object o = f.get(proc); - if (o instanceof SQLStmt) { - stmts.put(f.getName(), (SQLStmt) o); - } - } catch (Exception ex) { - throw new RuntimeException("Failed to retrieve " + f + " from " + c.getSimpleName(), ex); - } - } + } + + /** + * Hook for testing + * + * @return + */ + protected final Map getStatements() { + return (Collections.unmodifiableMap(this.name_stmt_xref)); + } + + protected static Map getStatements(Procedure proc) { + Class c = proc.getClass(); + Map stmts = new HashMap<>(); + for (Field f : c.getDeclaredFields()) { + int modifiers = f.getModifiers(); + if (!Modifier.isTransient(modifiers) + && Modifier.isPublic(modifiers) + && !Modifier.isStatic(modifiers)) { + try { + Object o = f.get(proc); + if (o instanceof SQLStmt) { + stmts.put(f.getName(), (SQLStmt) o); + } + } catch (Exception ex) { + throw new RuntimeException("Failed to retrieve " + f + " from " + c.getSimpleName(), ex); } - return (stmts); + } } + return (stmts); + } - @Override - public String toString() { - return (this.procName); - } + @Override + public String toString() { + return (this.procName); + } + + /** + * Thrown from a Procedure to indicate to the Worker that the procedure should be aborted and + * rolled back. + */ + public static class UserAbortException extends RuntimeException { + private static final long serialVersionUID = -1L; /** - * Thrown from a Procedure to indicate to the Worker - * that the procedure should be aborted and rolled back. + * Default Constructor + * + * @param msg + * @param ex */ - public static class UserAbortException extends RuntimeException { - private static final long serialVersionUID = -1L; - - /** - * Default Constructor - * - * @param msg - * @param ex - */ - public UserAbortException(String msg, Throwable ex) { - super(msg, ex); - } + public UserAbortException(String msg, Throwable ex) { + super(msg, ex); + } - /** - * Constructs a new UserAbortException - * with the specified detail message. - */ - public UserAbortException(String msg) { - this(msg, null); - } + /** Constructs a new UserAbortException with the specified detail message. */ + public UserAbortException(String msg) { + this(msg, null); } + } } diff --git a/src/main/java/com/oltpbenchmark/api/SQLStmt.java b/src/main/java/com/oltpbenchmark/api/SQLStmt.java index f363d4e64..bdf2cdce2 100644 --- a/src/main/java/com/oltpbenchmark/api/SQLStmt.java +++ b/src/main/java/com/oltpbenchmark/api/SQLStmt.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.api; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Wrapper Class for SQL Statements @@ -30,65 +28,63 @@ * @author pavlo */ public final class SQLStmt { - private static final Logger LOG = LoggerFactory.getLogger(SQLStmt.class); + private static final Logger LOG = LoggerFactory.getLogger(SQLStmt.class); - private static final Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\?\\?"); + private static final Pattern SUBSTITUTION_PATTERN = Pattern.compile("\\?\\?"); - private String orig_sql; - private String sql; + private String orig_sql; + private String sql; - /** - * For each unique '??' that we encounter in the SQL for this Statement, - * we will substitute it with the number of '?' specified in this array. - */ - private final int[] substitutions; + /** + * For each unique '??' that we encounter in the SQL for this Statement, we will substitute it + * with the number of '?' specified in this array. + */ + private final int[] substitutions; - /** - * Constructor - * - * @param sql - * @param substitutions - */ - public SQLStmt(String sql, int... substitutions) { - this.substitutions = substitutions; - this.setSQL(sql); - } + /** + * Constructor + * + * @param sql + * @param substitutions + */ + public SQLStmt(String sql, int... substitutions) { + this.substitutions = substitutions; + this.setSQL(sql); + } - /** - * Magic SQL setter! - * Each occurrence of the pattern "??" will be replaced by a string - * of repeated ?'s - * - * @param sql - */ - public final void setSQL(String sql) { - this.orig_sql = sql.trim(); - for (int ctr : this.substitutions) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < ctr; i++) { - sb.append(i > 0 ? ", " : "").append("?"); - } - Matcher m = SUBSTITUTION_PATTERN.matcher(sql); - String replace = sb.toString(); - sql = m.replaceFirst(replace); - } - this.sql = sql; - if (LOG.isDebugEnabled()) { - LOG.debug("Initialized SQL:\n{}", this.sql); - } + /** + * Magic SQL setter! Each occurrence of the pattern "??" will be replaced by a string of repeated + * ?'s + * + * @param sql + */ + public final void setSQL(String sql) { + this.orig_sql = sql.trim(); + for (int ctr : this.substitutions) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < ctr; i++) { + sb.append(i > 0 ? ", " : "").append("?"); + } + Matcher m = SUBSTITUTION_PATTERN.matcher(sql); + String replace = sb.toString(); + sql = m.replaceFirst(replace); } - - public final String getSQL() { - return (this.sql); + this.sql = sql; + if (LOG.isDebugEnabled()) { + LOG.debug("Initialized SQL:\n{}", this.sql); } + } - protected final String getOriginalSQL() { - return (this.orig_sql); - } + public final String getSQL() { + return (this.sql); + } - @Override - public String toString() { - return "SQLStmt{" + this.sql + "}"; - } + protected final String getOriginalSQL() { + return (this.orig_sql); + } + @Override + public String toString() { + return "SQLStmt{" + this.sql + "}"; + } } diff --git a/src/main/java/com/oltpbenchmark/api/StatementDialects.java b/src/main/java/com/oltpbenchmark/api/StatementDialects.java index aed1cfbcb..6c1146223 100644 --- a/src/main/java/com/oltpbenchmark/api/StatementDialects.java +++ b/src/main/java/com/oltpbenchmark/api/StatementDialects.java @@ -20,265 +20,258 @@ import com.oltpbenchmark.WorkloadConfiguration; import com.oltpbenchmark.api.dialects.*; import com.oltpbenchmark.types.DatabaseType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.xml.sax.SAXException; - import jakarta.xml.bind.*; - -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.*; import java.util.Map.Entry; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; /** * @author pavlo */ public final class StatementDialects { - private static final Logger LOG = LoggerFactory.getLogger(StatementDialects.class); - - private static final DatabaseType DEFAULT_DB_TYPE = DatabaseType.MYSQL; + private static final Logger LOG = LoggerFactory.getLogger(StatementDialects.class); - private final WorkloadConfiguration workloadConfiguration; + private static final DatabaseType DEFAULT_DB_TYPE = DatabaseType.MYSQL; + private final WorkloadConfiguration workloadConfiguration; - /** - * ProcName -> StmtName -> SQL - */ - private final Map> dialectsMap = new HashMap<>(); + /** ProcName -> StmtName -> SQL */ + private final Map> dialectsMap = new HashMap<>(); - /** - * Constructor - * - * @param workloadConfiguration - */ - public StatementDialects(WorkloadConfiguration workloadConfiguration) { - this.workloadConfiguration = workloadConfiguration; + /** + * Constructor + * + * @param workloadConfiguration + */ + public StatementDialects(WorkloadConfiguration workloadConfiguration) { + this.workloadConfiguration = workloadConfiguration; - try { - this.load(); - } catch (JAXBException | SAXException e) { - throw new RuntimeException(String.format("Error loading dialect: %s", e.getMessage()), e); - } + try { + this.load(); + } catch (JAXBException | SAXException e) { + throw new RuntimeException(String.format("Error loading dialect: %s", e.getMessage()), e); + } + } + + /** + * Return the File handle to the SQL Dialect XML file used for this benchmark + * + * @return + */ + public String getSQLDialectPath(DatabaseType databaseType) { + String fileName = null; + + if (databaseType != null) { + fileName = "dialect-" + databaseType.name().toLowerCase() + ".xml"; } + if (fileName != null) { - /** - * Return the File handle to the SQL Dialect XML file - * used for this benchmark - * - * @return - */ - public String getSQLDialectPath(DatabaseType databaseType) { - String fileName = null; - - if (databaseType != null) { - fileName = "dialect-" + databaseType.name().toLowerCase() + ".xml"; - } - - - if (fileName != null) { - - final String path = "/benchmarks/" + workloadConfiguration.getBenchmarkName() + "/" + fileName; - - try (InputStream stream = this.getClass().getResourceAsStream(path)) { - - if (stream != null) { - return path; - } + final String path = + "/benchmarks/" + workloadConfiguration.getBenchmarkName() + "/" + fileName; - } catch (IOException e) { - LOG.error(e.getMessage(), e); - } + try (InputStream stream = this.getClass().getResourceAsStream(path)) { - LOG.debug("No dialect file in {}", path); + if (stream != null) { + return path; } + } catch (IOException e) { + LOG.error(e.getMessage(), e); + } - return (null); + LOG.debug("No dialect file in {}", path); } - /** - * Load in the assigned XML file and populate the internal dialects map - * - * @return - */ - protected boolean load() throws JAXBException, SAXException { - final DatabaseType dbType = workloadConfiguration.getDatabaseType(); - - final String sqlDialectPath = getSQLDialectPath(dbType); + return (null); + } - if (sqlDialectPath == null) { - LOG.debug("SKIP - No SQL dialect file was given."); - return (false); - } - - final String xmlContext = this.getClass().getPackage().getName() + ".dialects"; + /** + * Load in the assigned XML file and populate the internal dialects map + * + * @return + */ + protected boolean load() throws JAXBException, SAXException { + final DatabaseType dbType = workloadConfiguration.getDatabaseType(); - // COPIED FROM VoltDB's VoltCompiler.java - JAXBContext jc = JAXBContext.newInstance(xmlContext); - // This schema shot the sheriff. - SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/dialect.xsd"))); - Unmarshaller unmarshaller = jc.createUnmarshaller(); - // But did not shoot unmarshaller! - unmarshaller.setSchema(schema); - - StreamSource streamSource = new StreamSource(this.getClass().getResourceAsStream(sqlDialectPath)); - JAXBElement result = unmarshaller.unmarshal(streamSource, DialectsType.class); - DialectsType dialects = result.getValue(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Loading the SQL dialect file for path {}", sqlDialectPath); - } + final String sqlDialectPath = getSQLDialectPath(dbType); + if (sqlDialectPath == null) { + LOG.debug("SKIP - No SQL dialect file was given."); + return (false); + } - for (DialectType dialect : dialects.getDialect()) { + final String xmlContext = this.getClass().getPackage().getName() + ".dialects"; + + // COPIED FROM VoltDB's VoltCompiler.java + JAXBContext jc = JAXBContext.newInstance(xmlContext); + // This schema shot the sheriff. + SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = + sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/dialect.xsd"))); + Unmarshaller unmarshaller = jc.createUnmarshaller(); + // But did not shoot unmarshaller! + unmarshaller.setSchema(schema); + + StreamSource streamSource = + new StreamSource(this.getClass().getResourceAsStream(sqlDialectPath)); + JAXBElement result = unmarshaller.unmarshal(streamSource, DialectsType.class); + DialectsType dialects = result.getValue(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Loading the SQL dialect file for path {}", sqlDialectPath); + } + for (DialectType dialect : dialects.getDialect()) { - if (!dialect.getType().equalsIgnoreCase(dbType.name())) { - continue; - } + if (!dialect.getType().equalsIgnoreCase(dbType.name())) { + continue; + } - // For each Procedure in the XML file, go through its list of Statements - // and populate our dialects map with the mapped SQL - for (ProcedureType procedure : dialect.getProcedure()) { - String procName = procedure.getName(); + // For each Procedure in the XML file, go through its list of Statements + // and populate our dialects map with the mapped SQL + for (ProcedureType procedure : dialect.getProcedure()) { + String procName = procedure.getName(); - // Loop through all of the Statements listed for this Procedure - Map procDialects = this.dialectsMap.get(procName); - for (StatementType statement : procedure.getStatement()) { - String stmtName = statement.getName(); - String stmtSQL = statement.getValue().trim(); - if (procDialects == null) { - procDialects = new HashMap<>(); - this.dialectsMap.put(procName, procDialects); - } - procDialects.put(stmtName, stmtSQL); - LOG.debug(String.format("%s.%s.%s\n%s\n", dbType, procName, stmtName, stmtSQL)); - } - } - } - if (this.dialectsMap.isEmpty()) { - LOG.warn(String.format("No SQL dialect provided for %s. Using default %s", - dbType, DEFAULT_DB_TYPE)); - return (false); + // Loop through all of the Statements listed for this Procedure + Map procDialects = this.dialectsMap.get(procName); + for (StatementType statement : procedure.getStatement()) { + String stmtName = statement.getName(); + String stmtSQL = statement.getValue().trim(); + if (procDialects == null) { + procDialects = new HashMap<>(); + this.dialectsMap.put(procName, procDialects); + } + procDialects.put(stmtName, stmtSQL); + LOG.debug(String.format("%s.%s.%s\n%s\n", dbType, procName, stmtName, stmtSQL)); } - - return (true); + } } - - /** - * Export the original SQL for all of the SQLStmt in the given list of Procedures - * - * @param dbType - * @param procedures - * @return A well-formed XML export of the SQL for the given Procedures - */ - public String export(DatabaseType dbType, Collection procedures) { - - Marshaller marshaller = null; - JAXBContext jc = null; - - final String xmlContext = this.getClass().getPackage().getName() + ".dialects"; - - try { - jc = JAXBContext.newInstance(xmlContext); - marshaller = jc.createMarshaller(); - - SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/dialect.xsd"))); - marshaller.setSchema(schema); - } catch (Exception ex) { - throw new RuntimeException("Unable to initialize serializer", ex); - } - - List sorted = new ArrayList<>(procedures); - sorted.sort(new Comparator() { - @Override - public int compare(Procedure o1, Procedure o2) { - return (o1.getProcedureName().compareTo(o2.getProcedureName())); - } - }); - - ObjectFactory factory = new ObjectFactory(); - DialectType dType = factory.createDialectType(); - dType.setType(dbType.name()); - for (Procedure proc : sorted) { - if (proc.getStatements().isEmpty()) { - continue; - } - - ProcedureType pType = factory.createProcedureType(); - pType.setName(proc.getProcedureName()); - for (Entry e : proc.getStatements().entrySet()) { - StatementType sType = factory.createStatementType(); - sType.setName(e.getKey()); - sType.setValue(e.getValue().getOriginalSQL()); - pType.getStatement().add(sType); - } - dType.getProcedure().add(pType); - } - DialectsType dialects = factory.createDialectsType(); - dialects.getDialect().add(dType); - - StringWriter st = new StringWriter(); - try { - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); - marshaller.marshal(factory.createDialects(dialects), st); - } catch (JAXBException ex) { - throw new RuntimeException("Failed to generate XML", ex); - } - - return (st.toString()); + if (this.dialectsMap.isEmpty()) { + LOG.warn( + String.format( + "No SQL dialect provided for %s. Using default %s", dbType, DEFAULT_DB_TYPE)); + return (false); } - /** - * Return the DatabaseType loaded from the XML file - * - * @return - */ - public DatabaseType getDatabaseType() { - return workloadConfiguration.getDatabaseType(); + return (true); + } + + /** + * Export the original SQL for all of the SQLStmt in the given list of Procedures + * + * @param dbType + * @param procedures + * @return A well-formed XML export of the SQL for the given Procedures + */ + public String export(DatabaseType dbType, Collection procedures) { + + Marshaller marshaller = null; + JAXBContext jc = null; + + final String xmlContext = this.getClass().getPackage().getName() + ".dialects"; + + try { + jc = JAXBContext.newInstance(xmlContext); + marshaller = jc.createMarshaller(); + + SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = + sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/dialect.xsd"))); + marshaller.setSchema(schema); + } catch (Exception ex) { + throw new RuntimeException("Unable to initialize serializer", ex); } - /** - * Return the list of Statement names that we have dialect information - * for the given Procedure name. If there are SQL dialects for the given - * Procedure, then the result will be null. - * - * @param procName - * @return - */ - protected Collection getStatementNames(String procName) { - Map procDialects = this.dialectsMap.get(procName); - return (procDialects != null ? procDialects.keySet() : null); - } + List sorted = new ArrayList<>(procedures); + sorted.sort( + new Comparator() { + @Override + public int compare(Procedure o1, Procedure o2) { + return (o1.getProcedureName().compareTo(o2.getProcedureName())); + } + }); - /** - * Return the SQL dialect for the given Statement in the Procedure - * - * @param procName - * @param stmtName - * @return - */ - public String getSQL(String procName, String stmtName) { - Map procDialects = this.dialectsMap.get(procName); - if (procDialects != null) { - return (procDialects.get(stmtName)); - } - return (null); + ObjectFactory factory = new ObjectFactory(); + DialectType dType = factory.createDialectType(); + dType.setType(dbType.name()); + for (Procedure proc : sorted) { + if (proc.getStatements().isEmpty()) { + continue; + } + + ProcedureType pType = factory.createProcedureType(); + pType.setName(proc.getProcedureName()); + for (Entry e : proc.getStatements().entrySet()) { + StatementType sType = factory.createStatementType(); + sType.setName(e.getKey()); + sType.setValue(e.getValue().getOriginalSQL()); + pType.getStatement().add(sType); + } + dType.getProcedure().add(pType); } - - /** - * @return The list of Procedure names that we have dialect information for. - */ - protected Collection getProcedureNames() { - return (this.dialectsMap.keySet()); + DialectsType dialects = factory.createDialectsType(); + dialects.getDialect().add(dType); + + StringWriter st = new StringWriter(); + try { + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + marshaller.marshal(factory.createDialects(dialects), st); + } catch (JAXBException ex) { + throw new RuntimeException("Failed to generate XML", ex); } + return (st.toString()); + } + + /** + * Return the DatabaseType loaded from the XML file + * + * @return + */ + public DatabaseType getDatabaseType() { + return workloadConfiguration.getDatabaseType(); + } + + /** + * Return the list of Statement names that we have dialect information for the given Procedure + * name. If there are SQL dialects for the given Procedure, then the result will be null. + * + * @param procName + * @return + */ + protected Collection getStatementNames(String procName) { + Map procDialects = this.dialectsMap.get(procName); + return (procDialects != null ? procDialects.keySet() : null); + } + + /** + * Return the SQL dialect for the given Statement in the Procedure + * + * @param procName + * @param stmtName + * @return + */ + public String getSQL(String procName, String stmtName) { + Map procDialects = this.dialectsMap.get(procName); + if (procDialects != null) { + return (procDialects.get(stmtName)); + } + return (null); + } + + /** + * @return The list of Procedure names that we have dialect information for. + */ + protected Collection getProcedureNames() { + return (this.dialectsMap.keySet()); + } } diff --git a/src/main/java/com/oltpbenchmark/api/TransactionGenerator.java b/src/main/java/com/oltpbenchmark/api/TransactionGenerator.java index ab84dd350..5217a0f2b 100644 --- a/src/main/java/com/oltpbenchmark/api/TransactionGenerator.java +++ b/src/main/java/com/oltpbenchmark/api/TransactionGenerator.java @@ -17,10 +17,7 @@ package com.oltpbenchmark.api; - public interface TransactionGenerator { - /** - * Implementations *must* be thread-safe. - */ - T nextTransaction(); + /** Implementations *must* be thread-safe. */ + T nextTransaction(); } diff --git a/src/main/java/com/oltpbenchmark/api/TransactionType.java b/src/main/java/com/oltpbenchmark/api/TransactionType.java index 4086cd5b8..c2607336f 100644 --- a/src/main/java/com/oltpbenchmark/api/TransactionType.java +++ b/src/main/java/com/oltpbenchmark/api/TransactionType.java @@ -17,80 +17,87 @@ package com.oltpbenchmark.api; - import java.util.Objects; public class TransactionType implements Comparable { - public static class Invalid extends Procedure { - } - - public static final int INVALID_ID = 0; - public static final TransactionType INVALID = new TransactionType(Invalid.class, INVALID_ID, false, 0, 0); - - private final Class procedureClass; - private final int id; - private final boolean supplemental; - private final long preExecutionWait; - private final long postExecutionWait; - - protected TransactionType(Class procedureClass, int id, boolean supplemental, long preExecutionWait, long postExecutionWait) { - this.procedureClass = procedureClass; - this.id = id; - this.supplemental = supplemental; - this.preExecutionWait = preExecutionWait; - this.postExecutionWait = postExecutionWait; - } - - public Class getProcedureClass() { - return (this.procedureClass); - } - - public String getName() { - return this.procedureClass.getSimpleName(); - } - - public int getId() { - return this.id; + public static class Invalid extends Procedure {} + + public static final int INVALID_ID = 0; + public static final TransactionType INVALID = + new TransactionType(Invalid.class, INVALID_ID, false, 0, 0); + + private final Class procedureClass; + private final int id; + private final boolean supplemental; + private final long preExecutionWait; + private final long postExecutionWait; + + protected TransactionType( + Class procedureClass, + int id, + boolean supplemental, + long preExecutionWait, + long postExecutionWait) { + this.procedureClass = procedureClass; + this.id = id; + this.supplemental = supplemental; + this.preExecutionWait = preExecutionWait; + this.postExecutionWait = postExecutionWait; + } + + public Class getProcedureClass() { + return (this.procedureClass); + } + + public String getName() { + return this.procedureClass.getSimpleName(); + } + + public int getId() { + return this.id; + } + + public boolean isSupplemental() { + return this.supplemental; + } + + public long getPreExecutionWait() { + return preExecutionWait; + } + + public long getPostExecutionWait() { + return postExecutionWait; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public boolean isSupplemental() { - return this.supplemental; - } - - public long getPreExecutionWait() { - return preExecutionWait; + if (o == null || getClass() != o.getClass()) { + return false; } - - public long getPostExecutionWait() { - return postExecutionWait; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TransactionType that = (TransactionType) o; - return id == that.id && supplemental == that.supplemental && preExecutionWait == that.preExecutionWait && postExecutionWait == that.postExecutionWait && procedureClass.equals(that.procedureClass); - } - - @Override - public int hashCode() { - return Objects.hash(procedureClass, id, supplemental, preExecutionWait, postExecutionWait); - } - - @Override - public int compareTo(TransactionType o) { - return (this.id - o.id); - } - - @Override - public String toString() { - return String.format("%s/%02d", this.procedureClass.getName(), this.id); - } - + TransactionType that = (TransactionType) o; + return id == that.id + && supplemental == that.supplemental + && preExecutionWait == that.preExecutionWait + && postExecutionWait == that.postExecutionWait + && procedureClass.equals(that.procedureClass); + } + + @Override + public int hashCode() { + return Objects.hash(procedureClass, id, supplemental, preExecutionWait, postExecutionWait); + } + + @Override + public int compareTo(TransactionType o) { + return (this.id - o.id); + } + + @Override + public String toString() { + return String.format("%s/%02d", this.procedureClass.getName(), this.id); + } } diff --git a/src/main/java/com/oltpbenchmark/api/TransactionTypes.java b/src/main/java/com/oltpbenchmark/api/TransactionTypes.java index 0059b08e7..39c8dc8f2 100644 --- a/src/main/java/com/oltpbenchmark/api/TransactionTypes.java +++ b/src/main/java/com/oltpbenchmark/api/TransactionTypes.java @@ -17,106 +17,104 @@ package com.oltpbenchmark.api; -import org.apache.commons.collections4.map.ListOrderedMap; - import java.util.Collection; import java.util.Iterator; import java.util.List; +import org.apache.commons.collections4.map.ListOrderedMap; public class TransactionTypes implements Collection { - private final ListOrderedMap types = new ListOrderedMap<>(); - - public TransactionTypes(List transactiontypes) { - transactiontypes.sort(TransactionType::compareTo); - for (TransactionType tt : transactiontypes) { - String key = tt.getName().toUpperCase(); - this.types.put(key, tt); - } - } - - public TransactionType getType(String procName) { - return (this.types.get(procName.toUpperCase())); - } - - public TransactionType getType(Class procClass) { - return (this.getType(procClass.getSimpleName())); - } - - public TransactionType getType(int id) { - return (this.types.getValue(id)); - } - - @Override - public String toString() { - return this.types.values().toString(); - } - - @Override - public boolean add(TransactionType tt) { - String key = tt.getName().toUpperCase(); - this.types.put(key, tt); - return (true); - } - - @Override - public boolean addAll(Collection c) { - return false; - } - - @Override - public void clear() { - this.types.clear(); - } - - @Override - public boolean contains(Object o) { - return false; - } - - @Override - public boolean containsAll(Collection c) { - return (this.types.values().containsAll(c)); - } - - @Override - public boolean isEmpty() { - return (this.types.isEmpty()); - } - - @Override - public Iterator iterator() { - return (this.types.values().iterator()); - } - - @Override - public boolean remove(Object o) { - return false; - } - - @Override - public boolean removeAll(Collection c) { - return false; - } - - @Override - public boolean retainAll(Collection c) { - return false; - } - - @Override - public int size() { - return (this.types.size()); - } - - @Override - public Object[] toArray() { - return (this.types.values().toArray()); - } - - @Override - public T[] toArray(T[] a) { - return (this.types.values().toArray(a)); - } - + private final ListOrderedMap types = new ListOrderedMap<>(); + + public TransactionTypes(List transactiontypes) { + transactiontypes.sort(TransactionType::compareTo); + for (TransactionType tt : transactiontypes) { + String key = tt.getName().toUpperCase(); + this.types.put(key, tt); + } + } + + public TransactionType getType(String procName) { + return (this.types.get(procName.toUpperCase())); + } + + public TransactionType getType(Class procClass) { + return (this.getType(procClass.getSimpleName())); + } + + public TransactionType getType(int id) { + return (this.types.getValue(id)); + } + + @Override + public String toString() { + return this.types.values().toString(); + } + + @Override + public boolean add(TransactionType tt) { + String key = tt.getName().toUpperCase(); + this.types.put(key, tt); + return (true); + } + + @Override + public boolean addAll(Collection c) { + return false; + } + + @Override + public void clear() { + this.types.clear(); + } + + @Override + public boolean contains(Object o) { + return false; + } + + @Override + public boolean containsAll(Collection c) { + return (this.types.values().containsAll(c)); + } + + @Override + public boolean isEmpty() { + return (this.types.isEmpty()); + } + + @Override + public Iterator iterator() { + return (this.types.values().iterator()); + } + + @Override + public boolean remove(Object o) { + return false; + } + + @Override + public boolean removeAll(Collection c) { + return false; + } + + @Override + public boolean retainAll(Collection c) { + return false; + } + + @Override + public int size() { + return (this.types.size()); + } + + @Override + public Object[] toArray() { + return (this.types.values().toArray()); + } + + @Override + public T[] toArray(T[] a) { + return (this.types.values().toArray(a)); + } } diff --git a/src/main/java/com/oltpbenchmark/api/Worker.java b/src/main/java/com/oltpbenchmark/api/Worker.java index f1cdf68ee..314622026 100644 --- a/src/main/java/com/oltpbenchmark/api/Worker.java +++ b/src/main/java/com/oltpbenchmark/api/Worker.java @@ -17,15 +17,14 @@ package com.oltpbenchmark.api; +import static com.oltpbenchmark.types.State.MEASURE; + import com.oltpbenchmark.*; import com.oltpbenchmark.api.Procedure.UserAbortException; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.types.State; import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.Histogram; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; @@ -34,526 +33,542 @@ import java.util.Map.Entry; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; - -import static com.oltpbenchmark.types.State.MEASURE; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class Worker implements Runnable { - private static final Logger LOG = LoggerFactory.getLogger(Worker.class); - private static final Logger ABORT_LOG = LoggerFactory.getLogger("com.oltpbenchmark.api.ABORT_LOG"); - - private WorkloadState workloadState; - private LatencyRecord latencies; - private final Statement currStatement; - - // Interval requests used by the monitor - private final AtomicInteger intervalRequests = new AtomicInteger(0); - - private final int id; - private final T benchmark; - protected Connection conn = null; - protected final WorkloadConfiguration configuration; - protected final TransactionTypes transactionTypes; - protected final Map procedures = new HashMap<>(); - protected final Map name_procedures = new HashMap<>(); - protected final Map, Procedure> class_procedures = new HashMap<>(); - - private final Histogram txnUnknown = new Histogram<>(); - private final Histogram txnSuccess = new Histogram<>(); - private final Histogram txnAbort = new Histogram<>(); - private final Histogram txnRetry = new Histogram<>(); - private final Histogram txnErrors = new Histogram<>(); - private final Histogram txtRetryDifferent = new Histogram<>(); - - private boolean seenDone = false; - - public Worker(T benchmark, int id) { - this.id = id; - this.benchmark = benchmark; - this.configuration = this.benchmark.getWorkloadConfiguration(); - this.workloadState = this.configuration.getWorkloadState(); - this.currStatement = null; - this.transactionTypes = this.configuration.getTransTypes(); - - if (!this.configuration.getNewConnectionPerTxn()) { - try { - this.conn = this.benchmark.makeConnection(); - this.conn.setAutoCommit(false); - this.conn.setTransactionIsolation(this.configuration.getIsolationMode()); - } catch (SQLException ex) { - throw new RuntimeException("Failed to connect to database", ex); - } - } - - // Generate all the Procedures that we're going to need - this.procedures.putAll(this.benchmark.getProcedures()); - for (Entry e : this.procedures.entrySet()) { - Procedure proc = e.getValue(); - this.name_procedures.put(e.getKey().getName(), proc); - this.class_procedures.put(proc.getClass(), proc); - } + private static final Logger LOG = LoggerFactory.getLogger(Worker.class); + private static final Logger ABORT_LOG = + LoggerFactory.getLogger("com.oltpbenchmark.api.ABORT_LOG"); + + private WorkloadState workloadState; + private LatencyRecord latencies; + private final Statement currStatement; + + // Interval requests used by the monitor + private final AtomicInteger intervalRequests = new AtomicInteger(0); + + private final int id; + private final T benchmark; + protected Connection conn = null; + protected final WorkloadConfiguration configuration; + protected final TransactionTypes transactionTypes; + protected final Map procedures = new HashMap<>(); + protected final Map name_procedures = new HashMap<>(); + protected final Map, Procedure> class_procedures = new HashMap<>(); + + private final Histogram txnUnknown = new Histogram<>(); + private final Histogram txnSuccess = new Histogram<>(); + private final Histogram txnAbort = new Histogram<>(); + private final Histogram txnRetry = new Histogram<>(); + private final Histogram txnErrors = new Histogram<>(); + private final Histogram txtRetryDifferent = new Histogram<>(); + + private boolean seenDone = false; + + public Worker(T benchmark, int id) { + this.id = id; + this.benchmark = benchmark; + this.configuration = this.benchmark.getWorkloadConfiguration(); + this.workloadState = this.configuration.getWorkloadState(); + this.currStatement = null; + this.transactionTypes = this.configuration.getTransTypes(); + + if (!this.configuration.getNewConnectionPerTxn()) { + try { + this.conn = this.benchmark.makeConnection(); + this.conn.setAutoCommit(false); + this.conn.setTransactionIsolation(this.configuration.getIsolationMode()); + } catch (SQLException ex) { + throw new RuntimeException("Failed to connect to database", ex); + } } - /** - * Get the BenchmarkModule managing this Worker - */ - public final T getBenchmark() { - return (this.benchmark); + // Generate all the Procedures that we're going to need + this.procedures.putAll(this.benchmark.getProcedures()); + for (Entry e : this.procedures.entrySet()) { + Procedure proc = e.getValue(); + this.name_procedures.put(e.getKey().getName(), proc); + this.class_procedures.put(proc.getClass(), proc); } - - /** - * Get the unique thread id for this worker - */ - public final int getId() { - return this.id; + } + + /** Get the BenchmarkModule managing this Worker */ + public final T getBenchmark() { + return (this.benchmark); + } + + /** Get the unique thread id for this worker */ + public final int getId() { + return this.id; + } + + @Override + public String toString() { + return String.format("%s<%03d>", this.getClass().getSimpleName(), this.getId()); + } + + public final WorkloadConfiguration getWorkloadConfiguration() { + return (this.benchmark.getWorkloadConfiguration()); + } + + public final Random rng() { + return (this.benchmark.rng()); + } + + public final int getRequests() { + return latencies.size(); + } + + public final int getAndResetIntervalRequests() { + return intervalRequests.getAndSet(0); + } + + public final Iterable getLatencyRecords() { + return latencies; + } + + public final Procedure getProcedure(TransactionType type) { + return (this.procedures.get(type)); + } + + @Deprecated + public final Procedure getProcedure(String name) { + return (this.name_procedures.get(name)); + } + + @SuppressWarnings("unchecked") + public final

P getProcedure(Class

procClass) { + return (P) (this.class_procedures.get(procClass)); + } + + public final Histogram getTransactionSuccessHistogram() { + return (this.txnSuccess); + } + + public final Histogram getTransactionUnknownHistogram() { + return (this.txnUnknown); + } + + public final Histogram getTransactionRetryHistogram() { + return (this.txnRetry); + } + + public final Histogram getTransactionAbortHistogram() { + return (this.txnAbort); + } + + public final Histogram getTransactionErrorHistogram() { + return (this.txnErrors); + } + + public final Histogram getTransactionRetryDifferentHistogram() { + return (this.txtRetryDifferent); + } + + /** Stop executing the current statement. */ + public synchronized void cancelStatement() { + try { + if (this.currStatement != null) { + this.currStatement.cancel(); + } + } catch (SQLException e) { + LOG.error("Failed to cancel statement: {}", e.getMessage()); } + } - @Override - public String toString() { - return String.format("%s<%03d>", this.getClass().getSimpleName(), this.getId()); - } + @Override + public final void run() { + Thread t = Thread.currentThread(); + t.setName(this.toString()); - public final WorkloadConfiguration getWorkloadConfiguration() { - return (this.benchmark.getWorkloadConfiguration()); - } + // In case of reuse reset the measurements + latencies = new LatencyRecord(workloadState.getTestStartNs()); - public final Random rng() { - return (this.benchmark.rng()); + // Invoke initialize callback + try { + this.initialize(); + } catch (Throwable ex) { + throw new RuntimeException("Unexpected error when initializing " + this, ex); } - public final int getRequests() { - return latencies.size(); - } + // wait for start + workloadState.blockForStart(); - public final int getAndResetIntervalRequests() { - return intervalRequests.getAndSet(0); - } + while (true) { - public final Iterable getLatencyRecords() { - return latencies; - } + // PART 1: Init and check if done - public final Procedure getProcedure(TransactionType type) { - return (this.procedures.get(type)); - } + State preState = workloadState.getGlobalState(); - @Deprecated - public final Procedure getProcedure(String name) { - return (this.name_procedures.get(name)); - } + // Do nothing + if (preState == State.DONE) { + if (!seenDone) { + // This is the first time we have observed that the + // test is done notify the global test state, then + // continue applying load + seenDone = true; + workloadState.signalDone(); + break; + } + } - @SuppressWarnings("unchecked") - public final

P getProcedure(Class

procClass) { - return (P) (this.class_procedures.get(procClass)); - } + // PART 2: Wait for work - public final Histogram getTransactionSuccessHistogram() { - return (this.txnSuccess); - } + // Sleep if there's nothing to do. + workloadState.stayAwake(); - public final Histogram getTransactionUnknownHistogram() { - return (this.txnUnknown); - } + Phase prePhase = workloadState.getCurrentPhase(); + if (prePhase == null) { + continue; + } - public final Histogram getTransactionRetryHistogram() { - return (this.txnRetry); - } + // Grab some work and update the state, in case it changed while we + // waited. - public final Histogram getTransactionAbortHistogram() { - return (this.txnAbort); - } + SubmittedProcedure pieceOfWork = workloadState.fetchWork(); - public final Histogram getTransactionErrorHistogram() { - return (this.txnErrors); - } + prePhase = workloadState.getCurrentPhase(); + if (prePhase == null) { + continue; + } - public final Histogram getTransactionRetryDifferentHistogram() { - return (this.txtRetryDifferent); - } + preState = workloadState.getGlobalState(); - /** - * Stop executing the current statement. - */ - synchronized public void cancelStatement() { - try { - if (this.currStatement != null) { - this.currStatement.cancel(); - } - } catch (SQLException e) { - LOG.error("Failed to cancel statement: {}", e.getMessage()); + switch (preState) { + case DONE, EXIT, LATENCY_COMPLETE -> { + // Once a latency run is complete, we wait until the next + // phase or until DONE. + LOG.warn("preState is {}? will continue...", preState); + continue; } - } + default -> {} + // Do nothing + } - @Override - public final void run() { - Thread t = Thread.currentThread(); - t.setName(this.toString()); + // PART 3: Execute work - // In case of reuse reset the measurements - latencies = new LatencyRecord(workloadState.getTestStartNs()); + TransactionType transactionType = + getTransactionType(pieceOfWork, prePhase, preState, workloadState); - // Invoke initialize callback - try { - this.initialize(); - } catch (Throwable ex) { - throw new RuntimeException("Unexpected error when initializing " + this, ex); - } + if (!transactionType.equals(TransactionType.INVALID)) { - // wait for start - workloadState.blockForStart(); + // TODO: Measuring latency when not rate limited is ... a little + // weird because if you add more simultaneous clients, you will + // increase latency (queue delay) but we do this anyway since it is + // useful sometimes - while (true) { + // Wait before transaction if specified + long preExecutionWaitInMillis = getPreExecutionWaitInMillis(transactionType); - // PART 1: Init and check if done + if (preExecutionWaitInMillis > 0) { + try { + LOG.debug( + "{} will sleep for {} ms before executing", + transactionType.getName(), + preExecutionWaitInMillis); - State preState = workloadState.getGlobalState(); + Thread.sleep(preExecutionWaitInMillis); + } catch (InterruptedException e) { + LOG.error("Pre-execution sleep interrupted", e); + } + } - // Do nothing - if (preState == State.DONE) { - if (!seenDone) { - // This is the first time we have observed that the - // test is done notify the global test state, then - // continue applying load - seenDone = true; - workloadState.signalDone(); - break; - } - } + long start = System.nanoTime(); - // PART 2: Wait for work + doWork(configuration.getDatabaseType(), transactionType); - // Sleep if there's nothing to do. - workloadState.stayAwake(); + long end = System.nanoTime(); - Phase prePhase = workloadState.getCurrentPhase(); - if (prePhase == null) { - continue; - } + // PART 4: Record results - // Grab some work and update the state, in case it changed while we - // waited. + State postState = workloadState.getGlobalState(); - SubmittedProcedure pieceOfWork = workloadState.fetchWork(); + switch (postState) { + case MEASURE: + // Non-serial measurement. Only measure if the state both + // before and after was MEASURE, and the phase hasn't + // changed, otherwise we're recording results for a query + // that either started during the warmup phase or ended + // after the timer went off. + Phase postPhase = workloadState.getCurrentPhase(); - prePhase = workloadState.getCurrentPhase(); - if (prePhase == null) { - continue; + if (postPhase == null) { + // Need a null check on postPhase since current phase being null is used in + // WorkloadState + // and ThreadBench as the indication that the benchmark is over. However, there's a + // race + // condition with postState not being changed from MEASURE to DONE yet, so we entered + // the + // switch. In this scenario, just break from the switch. + break; } - - preState = workloadState.getGlobalState(); - - switch (preState) { - case DONE, EXIT, LATENCY_COMPLETE -> { - // Once a latency run is complete, we wait until the next - // phase or until DONE. - LOG.warn("preState is {}? will continue...", preState); - continue; - } - default -> { - } - // Do nothing + if (preState == MEASURE && postPhase.getId() == prePhase.getId()) { + latencies.addLatency(transactionType.getId(), start, end, this.id, prePhase.getId()); + intervalRequests.incrementAndGet(); } - - // PART 3: Execute work - - TransactionType transactionType = getTransactionType(pieceOfWork, prePhase, preState, workloadState); - - if (!transactionType.equals(TransactionType.INVALID)) { - - // TODO: Measuring latency when not rate limited is ... a little - // weird because if you add more simultaneous clients, you will - // increase latency (queue delay) but we do this anyway since it is - // useful sometimes - - // Wait before transaction if specified - long preExecutionWaitInMillis = getPreExecutionWaitInMillis(transactionType); - - if (preExecutionWaitInMillis > 0) { - try { - LOG.debug("{} will sleep for {} ms before executing", transactionType.getName(), preExecutionWaitInMillis); - - Thread.sleep(preExecutionWaitInMillis); - } catch (InterruptedException e) { - LOG.error("Pre-execution sleep interrupted", e); - } - } - - long start = System.nanoTime(); - - doWork(configuration.getDatabaseType(), transactionType); - - long end = System.nanoTime(); - - // PART 4: Record results - - State postState = workloadState.getGlobalState(); - - switch (postState) { - case MEASURE: - // Non-serial measurement. Only measure if the state both - // before and after was MEASURE, and the phase hasn't - // changed, otherwise we're recording results for a query - // that either started during the warmup phase or ended - // after the timer went off. - Phase postPhase = workloadState.getCurrentPhase(); - - if (postPhase == null) { - // Need a null check on postPhase since current phase being null is used in WorkloadState - // and ThreadBench as the indication that the benchmark is over. However, there's a race - // condition with postState not being changed from MEASURE to DONE yet, so we entered the - // switch. In this scenario, just break from the switch. - break; - } - if (preState == MEASURE && postPhase.getId() == prePhase.getId()) { - latencies.addLatency(transactionType.getId(), start, end, this.id, prePhase.getId()); - intervalRequests.incrementAndGet(); - } - if (prePhase.isLatencyRun()) { - workloadState.startColdQuery(); - } - break; - case COLD_QUERY: - // No recording for cold runs, but next time we will since - // it'll be a hot run. - if (preState == State.COLD_QUERY) { - workloadState.startHotQuery(); - } - break; - default: - // Do nothing - } - - - // wait after transaction if specified - long postExecutionWaitInMillis = getPostExecutionWaitInMillis(transactionType); - - if (postExecutionWaitInMillis > 0) { - try { - LOG.debug("{} will sleep for {} ms after executing", transactionType.getName(), postExecutionWaitInMillis); - - Thread.sleep(postExecutionWaitInMillis); - } catch (InterruptedException e) { - LOG.error("Post-execution sleep interrupted", e); - } - } + if (prePhase.isLatencyRun()) { + workloadState.startColdQuery(); } - - workloadState.finishedWork(); + break; + case COLD_QUERY: + // No recording for cold runs, but next time we will since + // it'll be a hot run. + if (preState == State.COLD_QUERY) { + workloadState.startHotQuery(); + } + break; + default: + // Do nothing } - LOG.debug("worker calling teardown"); - - tearDown(); - } + // wait after transaction if specified + long postExecutionWaitInMillis = getPostExecutionWaitInMillis(transactionType); - private TransactionType getTransactionType(SubmittedProcedure pieceOfWork, Phase phase, State state, WorkloadState workloadState) { - TransactionType type = TransactionType.INVALID; + if (postExecutionWaitInMillis > 0) { + try { + LOG.debug( + "{} will sleep for {} ms after executing", + transactionType.getName(), + postExecutionWaitInMillis); - try { - type = transactionTypes.getType(pieceOfWork.getType()); - } catch (IndexOutOfBoundsException e) { - if (phase.isThroughputRun()) { - LOG.error("Thread tried executing disabled phase!"); - throw e; - } - if (phase.getId() == workloadState.getCurrentPhase().getId()) { - switch (state) { - case WARMUP -> { - // Don't quit yet: we haven't even begun! - LOG.info("[Serial] Resetting serial for phase."); - phase.resetSerial(); - } - case COLD_QUERY, MEASURE -> { - // The serial phase is over. Finish the run early. - LOG.info("[Serial] Updating workload state to {}.", State.LATENCY_COMPLETE); - workloadState.signalLatencyComplete(); - } - default -> throw e; - } - } + Thread.sleep(postExecutionWaitInMillis); + } catch (InterruptedException e) { + LOG.error("Post-execution sleep interrupted", e); + } } + } - return type; + workloadState.finishedWork(); } - /** - * Called in a loop in the thread to exercise the system under test. Each - * implementing worker should return the TransactionType handle that was - * executed. - * - * @param databaseType TODO - * @param transactionType TODO - */ - protected final void doWork(DatabaseType databaseType, TransactionType transactionType) { - - try { - int retryCount = 0; - int maxRetryCount = configuration.getMaxRetries(); - - while (retryCount < maxRetryCount && this.workloadState.getGlobalState() != State.DONE) { - - TransactionStatus status = TransactionStatus.UNKNOWN; - - if (this.conn == null) { - try { - this.conn = this.benchmark.makeConnection(); - this.conn.setAutoCommit(false); - this.conn.setTransactionIsolation(this.configuration.getIsolationMode()); - } catch (SQLException ex) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s failed to open a connection...", this)); - } - retryCount++; - continue; - } - } - - try { - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s %s attempting...", this, transactionType)); - } - - status = this.executeWork(conn, transactionType); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s %s completed with status [%s]...", this, transactionType, status.name())); - } - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s %s committing...", this, transactionType)); - } - - conn.commit(); - - break; - - } catch (UserAbortException ex) { - conn.rollback(); + LOG.debug("worker calling teardown"); + + tearDown(); + } + + private TransactionType getTransactionType( + SubmittedProcedure pieceOfWork, Phase phase, State state, WorkloadState workloadState) { + TransactionType type = TransactionType.INVALID; + + try { + type = transactionTypes.getType(pieceOfWork.getType()); + } catch (IndexOutOfBoundsException e) { + if (phase.isThroughputRun()) { + LOG.error("Thread tried executing disabled phase!"); + throw e; + } + if (phase.getId() == workloadState.getCurrentPhase().getId()) { + switch (state) { + case WARMUP -> { + // Don't quit yet: we haven't even begun! + LOG.info("[Serial] Resetting serial for phase."); + phase.resetSerial(); + } + case COLD_QUERY, MEASURE -> { + // The serial phase is over. Finish the run early. + LOG.info("[Serial] Updating workload state to {}.", State.LATENCY_COMPLETE); + workloadState.signalLatencyComplete(); + } + default -> throw e; + } + } + } - ABORT_LOG.debug(String.format("%s Aborted", transactionType), ex); + return type; + } + + /** + * Called in a loop in the thread to exercise the system under test. Each implementing worker + * should return the TransactionType handle that was executed. + * + * @param databaseType TODO + * @param transactionType TODO + */ + protected final void doWork(DatabaseType databaseType, TransactionType transactionType) { + + try { + int retryCount = 0; + int maxRetryCount = configuration.getMaxRetries(); + + while (retryCount < maxRetryCount && this.workloadState.getGlobalState() != State.DONE) { + + TransactionStatus status = TransactionStatus.UNKNOWN; + + if (this.conn == null) { + try { + this.conn = this.benchmark.makeConnection(); + this.conn.setAutoCommit(false); + this.conn.setTransactionIsolation(this.configuration.getIsolationMode()); + } catch (SQLException ex) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s failed to open a connection...", this)); + } + retryCount++; + continue; + } + } - status = TransactionStatus.USER_ABORTED; + try { - break; + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s %s attempting...", this, transactionType)); + } - } catch (SQLException ex) { - conn.rollback(); + status = this.executeWork(conn, transactionType); - if (isRetryable(ex)) { - LOG.debug(String.format("Retryable SQLException occurred during [%s]... current retry attempt [%d], max retry attempts [%d], sql state [%s], error code [%d].", transactionType, retryCount, maxRetryCount, ex.getSQLState(), ex.getErrorCode()), ex); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s %s completed with status [%s]...", this, transactionType, status.name())); + } - status = TransactionStatus.RETRY; + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s %s committing...", this, transactionType)); + } - retryCount++; - } else { - LOG.warn(String.format("SQLException occurred during [%s] and will not be retried... sql state [%s], error code [%d].", transactionType, ex.getSQLState(), ex.getErrorCode()), ex); + conn.commit(); - status = TransactionStatus.ERROR; + break; - break; - } + } catch (UserAbortException ex) { + conn.rollback(); - } finally { - if (this.configuration.getNewConnectionPerTxn() && this.conn != null) { - try { - this.conn.close(); - this.conn = null; - } catch (SQLException e) { - LOG.error("Connection couldn't be closed.", e); - } - } + ABORT_LOG.debug(String.format("%s Aborted", transactionType), ex); - switch (status) { - case UNKNOWN -> this.txnUnknown.put(transactionType); - case SUCCESS -> this.txnSuccess.put(transactionType); - case USER_ABORTED -> this.txnAbort.put(transactionType); - case RETRY -> this.txnRetry.put(transactionType); - case RETRY_DIFFERENT -> this.txtRetryDifferent.put(transactionType); - case ERROR -> this.txnErrors.put(transactionType); - } + status = TransactionStatus.USER_ABORTED; - } + break; - } } catch (SQLException ex) { - String msg = String.format("Unexpected SQLException in '%s' when executing '%s' on [%s]", this, transactionType, databaseType.name()); - - throw new RuntimeException(msg, ex); + conn.rollback(); + + if (isRetryable(ex)) { + LOG.debug( + String.format( + "Retryable SQLException occurred during [%s]... current retry attempt [%d], max retry attempts [%d], sql state [%s], error code [%d].", + transactionType, + retryCount, + maxRetryCount, + ex.getSQLState(), + ex.getErrorCode()), + ex); + + status = TransactionStatus.RETRY; + + retryCount++; + } else { + LOG.warn( + String.format( + "SQLException occurred during [%s] and will not be retried... sql state [%s], error code [%d].", + transactionType, ex.getSQLState(), ex.getErrorCode()), + ex); + + status = TransactionStatus.ERROR; + + break; + } + + } finally { + if (this.configuration.getNewConnectionPerTxn() && this.conn != null) { + try { + this.conn.close(); + this.conn = null; + } catch (SQLException e) { + LOG.error("Connection couldn't be closed.", e); + } + } + + switch (status) { + case UNKNOWN -> this.txnUnknown.put(transactionType); + case SUCCESS -> this.txnSuccess.put(transactionType); + case USER_ABORTED -> this.txnAbort.put(transactionType); + case RETRY -> this.txnRetry.put(transactionType); + case RETRY_DIFFERENT -> this.txtRetryDifferent.put(transactionType); + case ERROR -> this.txnErrors.put(transactionType); + } } - + } + } catch (SQLException ex) { + String msg = + String.format( + "Unexpected SQLException in '%s' when executing '%s' on [%s]", + this, transactionType, databaseType.name()); + + throw new RuntimeException(msg, ex); } + } - private boolean isRetryable(SQLException ex) { + private boolean isRetryable(SQLException ex) { - String sqlState = ex.getSQLState(); - int errorCode = ex.getErrorCode(); + String sqlState = ex.getSQLState(); + int errorCode = ex.getErrorCode(); - LOG.debug("sql state [{}] and error code [{}]", sqlState, errorCode); - - if (sqlState == null) { - return false; - } + LOG.debug("sql state [{}] and error code [{}]", sqlState, errorCode); - // ------------------ - // MYSQL: https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-error-sqlstates.html - // ------------------ - if (errorCode == 1213 && sqlState.equals("40001")) { - // MySQL ER_LOCK_DEADLOCK - return true; - } else if (errorCode == 1205 && sqlState.equals("40001")) { - // MySQL ER_LOCK_WAIT_TIMEOUT - return true; - } - - // ------------------ - // POSTGRES: https://www.postgresql.org/docs/current/errcodes-appendix.html - // ------------------ - // Postgres serialization_failure - return errorCode == 0 && sqlState.equals("40001"); + if (sqlState == null) { + return false; } - /** - * Optional callback that can be used to initialize the Worker right before - * the benchmark execution begins - */ - protected void initialize() { - // The default is to do nothing - } - - /** - * Invoke a single transaction for the given TransactionType - * - * @param conn TODO - * @param txnType TODO - * @return TODO - * @throws UserAbortException TODO - * @throws SQLException TODO - */ - protected abstract TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException; - - /** - * Called at the end of the test to do any clean up that may be required. - */ - public void tearDown() { - if (!this.configuration.getNewConnectionPerTxn() && this.conn != null) { - try { - conn.close(); - } catch (SQLException e) { - LOG.error("Connection couldn't be closed.", e); - } - } + // ------------------ + // MYSQL: + // https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-error-sqlstates.html + // ------------------ + if (errorCode == 1213 && sqlState.equals("40001")) { + // MySQL ER_LOCK_DEADLOCK + return true; + } else if (errorCode == 1205 && sqlState.equals("40001")) { + // MySQL ER_LOCK_WAIT_TIMEOUT + return true; } - public void initializeState() { - this.workloadState = this.configuration.getWorkloadState(); + // ------------------ + // POSTGRES: https://www.postgresql.org/docs/current/errcodes-appendix.html + // ------------------ + // Postgres serialization_failure + return errorCode == 0 && sqlState.equals("40001"); + } + + /** + * Optional callback that can be used to initialize the Worker right before the benchmark + * execution begins + */ + protected void initialize() { + // The default is to do nothing + } + + /** + * Invoke a single transaction for the given TransactionType + * + * @param conn TODO + * @param txnType TODO + * @return TODO + * @throws UserAbortException TODO + * @throws SQLException TODO + */ + protected abstract TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException; + + /** Called at the end of the test to do any clean up that may be required. */ + public void tearDown() { + if (!this.configuration.getNewConnectionPerTxn() && this.conn != null) { + try { + conn.close(); + } catch (SQLException e) { + LOG.error("Connection couldn't be closed.", e); + } } + } - protected long getPreExecutionWaitInMillis(TransactionType type) { - return 0; - } + public void initializeState() { + this.workloadState = this.configuration.getWorkloadState(); + } - protected long getPostExecutionWaitInMillis(TransactionType type) { - return 0; - } + protected long getPreExecutionWaitInMillis(TransactionType type) { + return 0; + } + protected long getPostExecutionWaitInMillis(TransactionType type) { + return 0; + } } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/CockroachCollector.java b/src/main/java/com/oltpbenchmark/api/collectors/CockroachCollector.java index 6267a595b..7ca21c238 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/CockroachCollector.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/CockroachCollector.java @@ -21,31 +21,30 @@ public class CockroachCollector extends DBCollector { - private static final String VERSION_SQL = "SELECT version();"; - - private static final String PARAMETERS_SQL = "SHOW ALL;"; - - public CockroachCollector(String oriDBUrl, String username, String password) { - try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { - try (Statement s = conn.createStatement()) { - - // Collect DBMS version - try (ResultSet out = s.executeQuery(VERSION_SQL)) { - if (out.next()) { - this.version = out.getString(1); - } - } - - // Collect DBMS parameters - try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { - while (out.next()) { - dbParameters.put(out.getString("variable"), out.getString("value")); - } - } - - } - } catch (SQLException e) { - LOG.error("Error while collecting DB parameters: {}", e.getMessage()); + private static final String VERSION_SQL = "SELECT version();"; + + private static final String PARAMETERS_SQL = "SHOW ALL;"; + + public CockroachCollector(String oriDBUrl, String username, String password) { + try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { + try (Statement s = conn.createStatement()) { + + // Collect DBMS version + try (ResultSet out = s.executeQuery(VERSION_SQL)) { + if (out.next()) { + this.version = out.getString(1); + } + } + + // Collect DBMS parameters + try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { + while (out.next()) { + dbParameters.put(out.getString("variable"), out.getString("value")); + } } + } + } catch (SQLException e) { + LOG.error("Error while collecting DB parameters: {}", e.getMessage()); } + } } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/DBCollector.java b/src/main/java/com/oltpbenchmark/api/collectors/DBCollector.java index 0a50b2aab..12973e97f 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/DBCollector.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/DBCollector.java @@ -18,46 +18,43 @@ package com.oltpbenchmark.api.collectors; import com.oltpbenchmark.util.JSONUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Map; import java.util.TreeMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DBCollector implements DBParameterCollector { - protected static final Logger LOG = LoggerFactory.getLogger(DBCollector.class); - - protected final Map dbParameters = new TreeMap<>(); - - protected final Map dbMetrics = new TreeMap<>(); + protected static final Logger LOG = LoggerFactory.getLogger(DBCollector.class); - protected String version = null; + protected final Map dbParameters = new TreeMap<>(); - @Override - public boolean hasParameters() { - return (!dbParameters.isEmpty()); - } + protected final Map dbMetrics = new TreeMap<>(); - @Override - public boolean hasMetrics() { - return (!dbMetrics.isEmpty()); - } + protected String version = null; - @Override - public String collectParameters() { - return JSONUtil.format(JSONUtil.toJSONString(dbParameters)); - } + @Override + public boolean hasParameters() { + return (!dbParameters.isEmpty()); + } - @Override - public String collectMetrics() { - return JSONUtil.format(JSONUtil.toJSONString(dbMetrics)); - } + @Override + public boolean hasMetrics() { + return (!dbMetrics.isEmpty()); + } - @Override - public String collectVersion() { - return version; - } + @Override + public String collectParameters() { + return JSONUtil.format(JSONUtil.toJSONString(dbParameters)); + } + @Override + public String collectMetrics() { + return JSONUtil.format(JSONUtil.toJSONString(dbMetrics)); + } + @Override + public String collectVersion() { + return version; + } } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollector.java b/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollector.java index 406dd739f..69a75294b 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollector.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollector.java @@ -18,13 +18,13 @@ package com.oltpbenchmark.api.collectors; public interface DBParameterCollector { - boolean hasParameters(); + boolean hasParameters(); - boolean hasMetrics(); + boolean hasMetrics(); - String collectParameters(); + String collectParameters(); - String collectMetrics(); + String collectMetrics(); - String collectVersion(); + String collectVersion(); } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollectorGen.java b/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollectorGen.java index e5be29d05..5734e4306 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollectorGen.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/DBParameterCollectorGen.java @@ -20,18 +20,18 @@ import com.oltpbenchmark.types.DatabaseType; public class DBParameterCollectorGen { - public static DBParameterCollector getCollector(DatabaseType dbType, String dbUrl, String username, String password) { - switch (dbType) { - - case MYSQL: - case MARIADB: - return new MySQLCollector(dbUrl, username, password); - case POSTGRES: - return new PostgresCollector(dbUrl, username, password); - case COCKROACHDB: - return new CockroachCollector(dbUrl, username, password); - default: - return new DBCollector(); - } + public static DBParameterCollector getCollector( + DatabaseType dbType, String dbUrl, String username, String password) { + switch (dbType) { + case MYSQL: + case MARIADB: + return new MySQLCollector(dbUrl, username, password); + case POSTGRES: + return new PostgresCollector(dbUrl, username, password); + case COCKROACHDB: + return new CockroachCollector(dbUrl, username, password); + default: + return new DBCollector(); } + } } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/MySQLCollector.java b/src/main/java/com/oltpbenchmark/api/collectors/MySQLCollector.java index d377a062d..82c514ead 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/MySQLCollector.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/MySQLCollector.java @@ -21,39 +21,39 @@ public class MySQLCollector extends DBCollector { - private static final String VERSION_SQL = "SELECT @@GLOBAL.version;"; - - private static final String PARAMETERS_SQL = "SHOW VARIABLES;"; - - private static final String METRICS_SQL = "SHOW STATUS"; - - public MySQLCollector(String oriDBUrl, String username, String password) { - try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { - try (Statement s = conn.createStatement()) { - - // Collect DBMS version - try (ResultSet out = s.executeQuery(VERSION_SQL)) { - if (out.next()) { - this.version = out.getString(1); - } - } - - // Collect DBMS parameters - try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { - while (out.next()) { - dbParameters.put(out.getString(1).toLowerCase(), out.getString(2)); - } - } - - // Collect DBMS internal metrics - try (ResultSet out = s.executeQuery(METRICS_SQL)) { - while (out.next()) { - dbMetrics.put(out.getString(1).toLowerCase(), out.getString(2)); - } - } - } - } catch (SQLException e) { - LOG.error("Error while collecting DB parameters: {}", e.getMessage()); + private static final String VERSION_SQL = "SELECT @@GLOBAL.version;"; + + private static final String PARAMETERS_SQL = "SHOW VARIABLES;"; + + private static final String METRICS_SQL = "SHOW STATUS"; + + public MySQLCollector(String oriDBUrl, String username, String password) { + try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { + try (Statement s = conn.createStatement()) { + + // Collect DBMS version + try (ResultSet out = s.executeQuery(VERSION_SQL)) { + if (out.next()) { + this.version = out.getString(1); + } + } + + // Collect DBMS parameters + try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { + while (out.next()) { + dbParameters.put(out.getString(1).toLowerCase(), out.getString(2)); + } + } + + // Collect DBMS internal metrics + try (ResultSet out = s.executeQuery(METRICS_SQL)) { + while (out.next()) { + dbMetrics.put(out.getString(1).toLowerCase(), out.getString(2)); + } } + } + } catch (SQLException e) { + LOG.error("Error while collecting DB parameters: {}", e.getMessage()); } + } } diff --git a/src/main/java/com/oltpbenchmark/api/collectors/PostgresCollector.java b/src/main/java/com/oltpbenchmark/api/collectors/PostgresCollector.java index add037d08..ae22dfecc 100644 --- a/src/main/java/com/oltpbenchmark/api/collectors/PostgresCollector.java +++ b/src/main/java/com/oltpbenchmark/api/collectors/PostgresCollector.java @@ -18,83 +18,82 @@ package com.oltpbenchmark.api.collectors; import com.oltpbenchmark.util.JSONUtil; - import java.sql.*; import java.util.*; public class PostgresCollector extends DBCollector { - private static final String VERSION_SQL = "SELECT version();"; - - private static final String PARAMETERS_SQL = "SHOW ALL;"; - - private static final String[] PG_STAT_VIEWS = { - "pg_stat_archiver", "pg_stat_bgwriter", "pg_stat_database", - "pg_stat_database_conflicts", "pg_stat_user_tables", "pg_statio_user_tables", - "pg_stat_user_indexes", "pg_statio_user_indexes" - }; - - private final Map>> pgMetrics = new HashMap<>(); - - public PostgresCollector(String oriDBUrl, String username, String password) { - - try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { - try (Statement s = conn.createStatement()) { - - // Collect DBMS version - try (ResultSet out = s.executeQuery(VERSION_SQL)) { - if (out.next()) { - this.version = out.getString(1); - } - } - - // Collect DBMS parameters - try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { - while (out.next()) { - dbParameters.put(out.getString("name"), out.getString("setting")); - } - } - - // Collect DBMS internal metrics - for (String viewName : PG_STAT_VIEWS) { - try (ResultSet out = s.executeQuery("SELECT * FROM " + viewName)) { - pgMetrics.put(viewName, getMetrics(out)); - } catch (SQLException ex) { - LOG.error("Error while collecting DB metric view: {}", ex.getMessage()); - } - } - } - } catch (SQLException e) { - LOG.error("Error while collecting DB parameters: {}", e.getMessage()); - } - } + private static final String VERSION_SQL = "SELECT version();"; - @Override - public boolean hasMetrics() { - return (!pgMetrics.isEmpty()); - } + private static final String PARAMETERS_SQL = "SHOW ALL;"; - @Override - public String collectMetrics() { - return JSONUtil.format(JSONUtil.toJSONString(pgMetrics)); - } + private static final String[] PG_STAT_VIEWS = { + "pg_stat_archiver", "pg_stat_bgwriter", "pg_stat_database", + "pg_stat_database_conflicts", "pg_stat_user_tables", "pg_statio_user_tables", + "pg_stat_user_indexes", "pg_statio_user_indexes" + }; + + private final Map>> pgMetrics = new HashMap<>(); + + public PostgresCollector(String oriDBUrl, String username, String password) { - private List> getMetrics(ResultSet out) throws SQLException { - ResultSetMetaData metadata = out.getMetaData(); - int numColumns = metadata.getColumnCount(); - String[] columnNames = new String[numColumns]; - for (int i = 0; i < numColumns; ++i) { - columnNames[i] = metadata.getColumnName(i + 1).toLowerCase(); + try (Connection conn = DriverManager.getConnection(oriDBUrl, username, password)) { + try (Statement s = conn.createStatement()) { + + // Collect DBMS version + try (ResultSet out = s.executeQuery(VERSION_SQL)) { + if (out.next()) { + this.version = out.getString(1); + } + } + + // Collect DBMS parameters + try (ResultSet out = s.executeQuery(PARAMETERS_SQL)) { + while (out.next()) { + dbParameters.put(out.getString("name"), out.getString("setting")); + } } - List> metrics = new ArrayList<>(); - while (out.next()) { - Map metricMap = new TreeMap<>(); - for (int i = 0; i < numColumns; ++i) { - metricMap.put(columnNames[i], out.getString(i + 1)); - } - metrics.add(metricMap); + // Collect DBMS internal metrics + for (String viewName : PG_STAT_VIEWS) { + try (ResultSet out = s.executeQuery("SELECT * FROM " + viewName)) { + pgMetrics.put(viewName, getMetrics(out)); + } catch (SQLException ex) { + LOG.error("Error while collecting DB metric view: {}", ex.getMessage()); + } } - return metrics; + } + } catch (SQLException e) { + LOG.error("Error while collecting DB parameters: {}", e.getMessage()); + } + } + + @Override + public boolean hasMetrics() { + return (!pgMetrics.isEmpty()); + } + + @Override + public String collectMetrics() { + return JSONUtil.format(JSONUtil.toJSONString(pgMetrics)); + } + + private List> getMetrics(ResultSet out) throws SQLException { + ResultSetMetaData metadata = out.getMetaData(); + int numColumns = metadata.getColumnCount(); + String[] columnNames = new String[numColumns]; + for (int i = 0; i < numColumns; ++i) { + columnNames[i] = metadata.getColumnName(i + 1).toLowerCase(); + } + + List> metrics = new ArrayList<>(); + while (out.next()) { + Map metricMap = new TreeMap<>(); + for (int i = 0; i < numColumns; ++i) { + metricMap.put(columnNames[i], out.getString(i + 1)); + } + metrics.add(metricMap); } + return metrics; + } } diff --git a/src/main/java/com/oltpbenchmark/api/dialects/DialectType.java b/src/main/java/com/oltpbenchmark/api/dialects/DialectType.java index 5ddfd5092..af3ee42fa 100644 --- a/src/main/java/com/oltpbenchmark/api/dialects/DialectType.java +++ b/src/main/java/com/oltpbenchmark/api/dialects/DialectType.java @@ -16,22 +16,21 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.dialects; import jakarta.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectType complex type. + * Java class for dialectType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -49,61 +48,54 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "dialectType", propOrder = { - "procedure" -}) +@XmlType( + name = "dialectType", + propOrder = {"procedure"}) public class DialectType { - @XmlElement(required = true) - protected List procedure; - @XmlAttribute(required = true) - protected String type; + @XmlElement(required = true) + protected List procedure; - /** - * Gets the value of the procedure property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the procedure property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getProcedure().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link ProcedureType } - */ - public List getProcedure() { - if (procedure == null) { - procedure = new ArrayList<>(); - } - return this.procedure; - } + @XmlAttribute(required = true) + protected String type; - /** - * Gets the value of the type property. - * - * @return possible object is - * {@link String } - */ - public String getType() { - return type; + /** + * Gets the value of the procedure property. + * + *

This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is why + * there is not a set method for the procedure property. + * + *

For example, to add a new item, do as follows: + * + *

+   *    getProcedure().add(newItem);
+   * 
+ * + *

Objects of the following type(s) are allowed in the list {@link ProcedureType } + */ + public List getProcedure() { + if (procedure == null) { + procedure = new ArrayList<>(); } + return this.procedure; + } - /** - * Sets the value of the type property. - * - * @param value allowed object is - * {@link String } - */ - public void setType(String value) { - this.type = value; - } + /** + * Gets the value of the type property. + * + * @return possible object is {@link String } + */ + public String getType() { + return type; + } + /** + * Sets the value of the type property. + * + * @param value allowed object is {@link String } + */ + public void setType(String value) { + this.type = value; + } } diff --git a/src/main/java/com/oltpbenchmark/api/dialects/DialectsType.java b/src/main/java/com/oltpbenchmark/api/dialects/DialectsType.java index d0f7dc526..a4c4fc339 100644 --- a/src/main/java/com/oltpbenchmark/api/dialects/DialectsType.java +++ b/src/main/java/com/oltpbenchmark/api/dialects/DialectsType.java @@ -16,13 +16,13 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.dialects; import jakarta.xml.bind.annotation.XmlAccessType; @@ -32,9 +32,8 @@ import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectsType complex type. + * Java class for dialectsType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -51,39 +50,33 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "dialectsType", propOrder = { - "dialect" -}) +@XmlType( + name = "dialectsType", + propOrder = {"dialect"}) public class DialectsType { - @XmlElement(required = true) - protected List dialect; + @XmlElement(required = true) + protected List dialect; - /** - * Gets the value of the dialect property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the dialect property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDialect().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link DialectType } - */ - public List getDialect() { - if (dialect == null) { - dialect = new ArrayList<>(); - } - return this.dialect; + /** + * Gets the value of the dialect property. + * + *

This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is why + * there is not a set method for the dialect property. + * + *

For example, to add a new item, do as follows: + * + *

+   *    getDialect().add(newItem);
+   * 
+ * + *

Objects of the following type(s) are allowed in the list {@link DialectType } + */ + public List getDialect() { + if (dialect == null) { + dialect = new ArrayList<>(); } - + return this.dialect; + } } diff --git a/src/main/java/com/oltpbenchmark/api/dialects/ObjectFactory.java b/src/main/java/com/oltpbenchmark/api/dialects/ObjectFactory.java index 2c2fe5b95..6bd32321e 100644 --- a/src/main/java/com/oltpbenchmark/api/dialects/ObjectFactory.java +++ b/src/main/java/com/oltpbenchmark/api/dialects/ObjectFactory.java @@ -16,13 +16,13 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.dialects; import jakarta.xml.bind.JAXBElement; @@ -30,65 +30,49 @@ import jakarta.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; - /** - * This object contains factory methods for each - * Java content interface and Java element interface + * This object contains factory methods for each Java content interface and Java element interface * generated in the com.oltpbenchmark.api.dialects package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. + * + *

An ObjectFactory allows you to programatically construct new instances of the Java + * representation for XML content. The Java representation of XML content can consist of schema + * derived interfaces and classes representing the binding of schema type definitions, element + * declarations and model groups. Factory methods for each of these are provided in this class. */ @XmlRegistry public class ObjectFactory { - private final static QName _Dialects_QNAME = new QName("", "dialects"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.oltpbenchmark.api.dialects - */ - public ObjectFactory() { - } + private static final QName _Dialects_QNAME = new QName("", "dialects"); - /** - * Create an instance of {@link DialectType } - */ - public DialectType createDialectType() { - return new DialectType(); - } + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes + * for package: com.oltpbenchmark.api.dialects + */ + public ObjectFactory() {} - /** - * Create an instance of {@link StatementType } - */ - public StatementType createStatementType() { - return new StatementType(); - } + /** Create an instance of {@link DialectType } */ + public DialectType createDialectType() { + return new DialectType(); + } - /** - * Create an instance of {@link ProcedureType } - */ - public ProcedureType createProcedureType() { - return new ProcedureType(); - } + /** Create an instance of {@link StatementType } */ + public StatementType createStatementType() { + return new StatementType(); + } - /** - * Create an instance of {@link DialectsType } - */ - public DialectsType createDialectsType() { - return new DialectsType(); - } + /** Create an instance of {@link ProcedureType } */ + public ProcedureType createProcedureType() { + return new ProcedureType(); + } - /** - * Create an instance of {@link JAXBElement }{@code <}{@link DialectsType }{@code >}} - */ - @XmlElementDecl(namespace = "", name = "dialects") - public JAXBElement createDialects(DialectsType value) { - return new JAXBElement<>(_Dialects_QNAME, DialectsType.class, null, value); - } + /** Create an instance of {@link DialectsType } */ + public DialectsType createDialectsType() { + return new DialectsType(); + } + /** Create an instance of {@link JAXBElement }{@code <}{@link DialectsType }{@code >}} */ + @XmlElementDecl(namespace = "", name = "dialects") + public JAXBElement createDialects(DialectsType value) { + return new JAXBElement<>(_Dialects_QNAME, DialectsType.class, null, value); + } } diff --git a/src/main/java/com/oltpbenchmark/api/dialects/ProcedureType.java b/src/main/java/com/oltpbenchmark/api/dialects/ProcedureType.java index 4ab997357..25431d36d 100644 --- a/src/main/java/com/oltpbenchmark/api/dialects/ProcedureType.java +++ b/src/main/java/com/oltpbenchmark/api/dialects/ProcedureType.java @@ -16,22 +16,21 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.dialects; import jakarta.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; - /** - *

Java class for procedureType complex type. + * Java class for procedureType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -49,61 +48,54 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "procedureType", propOrder = { - "statement" -}) +@XmlType( + name = "procedureType", + propOrder = {"statement"}) public class ProcedureType { - @XmlElement(required = true) - protected List statement; - @XmlAttribute(required = true) - protected String name; + @XmlElement(required = true) + protected List statement; - /** - * Gets the value of the statement property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the statement property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getStatement().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link StatementType } - */ - public List getStatement() { - if (statement == null) { - statement = new ArrayList<>(); - } - return this.statement; - } + @XmlAttribute(required = true) + protected String name; - /** - * Gets the value of the name property. - * - * @return possible object is - * {@link String } - */ - public String getName() { - return name; + /** + * Gets the value of the statement property. + * + *

This accessor method returns a reference to the live list, not a snapshot. Therefore any + * modification you make to the returned list will be present inside the JAXB object. This is why + * there is not a set method for the statement property. + * + *

For example, to add a new item, do as follows: + * + *

+   *    getStatement().add(newItem);
+   * 
+ * + *

Objects of the following type(s) are allowed in the list {@link StatementType } + */ + public List getStatement() { + if (statement == null) { + statement = new ArrayList<>(); } + return this.statement; + } - /** - * Sets the value of the name property. - * - * @param value allowed object is - * {@link String } - */ - public void setName(String value) { - this.name = value; - } + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + */ + public String getName() { + return name; + } + /** + * Sets the value of the name property. + * + * @param value allowed object is {@link String } + */ + public void setName(String value) { + this.name = value; + } } diff --git a/src/main/java/com/oltpbenchmark/api/dialects/StatementType.java b/src/main/java/com/oltpbenchmark/api/dialects/StatementType.java index c9c1fcd02..53adc7d0a 100644 --- a/src/main/java/com/oltpbenchmark/api/dialects/StatementType.java +++ b/src/main/java/com/oltpbenchmark/api/dialects/StatementType.java @@ -16,20 +16,19 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.dialects; import jakarta.xml.bind.annotation.*; - /** - *

Java class for statementType complex type. + * Java class for statementType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -44,54 +43,49 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "statementType", propOrder = { - "value" -}) +@XmlType( + name = "statementType", + propOrder = {"value"}) public class StatementType { - @XmlValue - protected String value; - @XmlAttribute(required = true) - protected String name; + @XmlValue protected String value; - /** - * Gets the value of the value property. - * - * @return possible object is - * {@link String } - */ - public String getValue() { - return value; - } + @XmlAttribute(required = true) + protected String name; - /** - * Sets the value of the value property. - * - * @param value allowed object is - * {@link String } - */ - public void setValue(String value) { - this.value = value; - } + /** + * Gets the value of the value property. + * + * @return possible object is {@link String } + */ + public String getValue() { + return value; + } - /** - * Gets the value of the name property. - * - * @return possible object is - * {@link String } - */ - public String getName() { - return name; - } + /** + * Sets the value of the value property. + * + * @param value allowed object is {@link String } + */ + public void setValue(String value) { + this.value = value; + } - /** - * Sets the value of the name property. - * - * @param value allowed object is - * {@link String } - */ - public void setName(String value) { - this.name = value; - } + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + */ + public String getName() { + return name; + } + /** + * Sets the value of the name property. + * + * @param value allowed object is {@link String } + */ + public void setName(String value) { + this.name = value; + } } diff --git a/src/main/java/com/oltpbenchmark/api/templates/ObjectFactory.java b/src/main/java/com/oltpbenchmark/api/templates/ObjectFactory.java index 82cbd4b96..3fa4c965d 100644 --- a/src/main/java/com/oltpbenchmark/api/templates/ObjectFactory.java +++ b/src/main/java/com/oltpbenchmark/api/templates/ObjectFactory.java @@ -16,13 +16,13 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.templates; import jakarta.xml.bind.JAXBElement; @@ -30,59 +30,44 @@ import jakarta.xml.bind.annotation.XmlRegistry; import javax.xml.namespace.QName; - /** - * This object contains factory methods for each - * Java content interface and Java element interface + * This object contains factory methods for each Java content interface and Java element interface * generated in the com.oltpbenchmark.api.templates package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. + * + *

An ObjectFactory allows you to programatically construct new instances of the Java + * representation for XML content. The Java representation of XML content can consist of schema + * derived interfaces and classes representing the binding of schema type definitions, element + * declarations and model groups. Factory methods for each of these are provided in this class. */ @XmlRegistry public class ObjectFactory { - private final static QName _Templates_QNAME = new QName("", "templates"); - - /** - * Create a new ObjectFactory that can be used to create new instances of - * schema derived classes for package: com.oltpbenchmark.api.templates - */ - public ObjectFactory() { - } + private static final QName _Templates_QNAME = new QName("", "templates"); - /** - * Create an instance of {@link TemplateType } - */ - public TemplateType createTemplateType() { - return new TemplateType(); - } + /** + * Create a new ObjectFactory that can be used to create new instances of schema derived classes + * for package: com.oltpbenchmark.api.templates + */ + public ObjectFactory() {} - /** - * Create an instance of {@link TypesType } - */ - public TypesType createTypesType() { - return new TypesType(); - } + /** Create an instance of {@link TemplateType } */ + public TemplateType createTemplateType() { + return new TemplateType(); + } - /** - * Create an instance of {@link ValuesType } - */ - public ValuesType createValuesType() { - return new ValuesType(); - } + /** Create an instance of {@link TypesType } */ + public TypesType createTypesType() { + return new TypesType(); + } - /** - * Create an instance of {@link JAXBElement }{@code <}{@link TemplatesType }{@code >}} - */ - @XmlElementDecl(namespace = "", name = "templates") - public JAXBElement createDialects(TemplatesType value) { - return new JAXBElement<>(_Templates_QNAME, TemplatesType.class, null, value); - } + /** Create an instance of {@link ValuesType } */ + public ValuesType createValuesType() { + return new ValuesType(); + } + /** Create an instance of {@link JAXBElement }{@code <}{@link TemplatesType }{@code >}} */ + @XmlElementDecl(namespace = "", name = "templates") + public JAXBElement createDialects(TemplatesType value) { + return new JAXBElement<>(_Templates_QNAME, TemplatesType.class, null, value); + } } diff --git a/src/main/java/com/oltpbenchmark/api/templates/TemplateType.java b/src/main/java/com/oltpbenchmark/api/templates/TemplateType.java index 1bcba2164..427180c28 100644 --- a/src/main/java/com/oltpbenchmark/api/templates/TemplateType.java +++ b/src/main/java/com/oltpbenchmark/api/templates/TemplateType.java @@ -16,22 +16,21 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.templates; import jakarta.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectType complex type. + * Java class for dialectType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -49,54 +48,51 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "templateType", propOrder = { - "query", "types", "values" -}) +@XmlType( + name = "templateType", + propOrder = {"query", "types", "values"}) public class TemplateType { - @XmlAttribute(required = true) - protected String name; - @XmlElement(required = true) - protected String query; - @XmlElement(required = true) - protected TypesType types; - @XmlElement(required = true) - protected List values; + @XmlAttribute(required = true) + protected String name; - /** - * Gets the value of the query property. - */ - public String getQuery() { - return this.query; - } - + @XmlElement(required = true) + protected String query; - /** - * Gets the value of the types property. - */ - public TypesType getTypes() { - return this.types; - } + @XmlElement(required = true) + protected TypesType types; - /** - * Gets the value of the types property. - * - * Objects of the following type(s) are allowed in the list {@link ValuesType } - */ - public List getValues() { - if (this.values == null) { - this.values = new ArrayList<>(); - } - return this.values; - } + @XmlElement(required = true) + protected List values; + + /** Gets the value of the query property. */ + public String getQuery() { + return this.query; + } + + /** Gets the value of the types property. */ + public TypesType getTypes() { + return this.types; + } - /** - * Gets the value of the name property. - * - * @return possible object is {@link String } - */ - public String getName() { - return name; + /** + * Gets the value of the types property. + * + *

Objects of the following type(s) are allowed in the list {@link ValuesType } + */ + public List getValues() { + if (this.values == null) { + this.values = new ArrayList<>(); } + return this.values; + } + /** + * Gets the value of the name property. + * + * @return possible object is {@link String } + */ + public String getName() { + return name; + } } diff --git a/src/main/java/com/oltpbenchmark/api/templates/TemplatesType.java b/src/main/java/com/oltpbenchmark/api/templates/TemplatesType.java index 6910f5477..4773c4986 100644 --- a/src/main/java/com/oltpbenchmark/api/templates/TemplatesType.java +++ b/src/main/java/com/oltpbenchmark/api/templates/TemplatesType.java @@ -16,13 +16,13 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.templates; import jakarta.xml.bind.annotation.XmlAccessType; @@ -32,9 +32,8 @@ import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectsType complex type. + * Java class for dialectsType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -51,24 +50,23 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "templatesType", propOrder = { - "template" -}) +@XmlType( + name = "templatesType", + propOrder = {"template"}) public class TemplatesType { - @XmlElement(required = true) - protected List template; + @XmlElement(required = true) + protected List template; - /** - * Gets the value of the dialect property. - * - * Objects of the following type(s) are allowed in the list {@link TemplateType } - */ - public List getTemplateList() { - if (this.template == null) { - this.template = new ArrayList<>(); - } - return this.template; + /** + * Gets the value of the dialect property. + * + *

Objects of the following type(s) are allowed in the list {@link TemplateType } + */ + public List getTemplateList() { + if (this.template == null) { + this.template = new ArrayList<>(); } - + return this.template; + } } diff --git a/src/main/java/com/oltpbenchmark/api/templates/TypesType.java b/src/main/java/com/oltpbenchmark/api/templates/TypesType.java index 170844d78..6fec026c2 100644 --- a/src/main/java/com/oltpbenchmark/api/templates/TypesType.java +++ b/src/main/java/com/oltpbenchmark/api/templates/TypesType.java @@ -16,22 +16,21 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.templates; import jakarta.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectType complex type. + * Java class for dialectType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -48,23 +47,23 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "typesType", propOrder = {"type"}) +@XmlType( + name = "typesType", + propOrder = {"type"}) public class TypesType { - @XmlElement(required = true) - protected List type; - + @XmlElement(required = true) + protected List type; - /** - * Gets the value of the type property. - * - * Objects of the following type(s) are allowed in the list {@link String } - */ - public List getTypeList() { - if (this.type == null) { - this.type = new ArrayList<>(); - } - return this.type; + /** + * Gets the value of the type property. + * + *

Objects of the following type(s) are allowed in the list {@link String } + */ + public List getTypeList() { + if (this.type == null) { + this.type = new ArrayList<>(); } - + return this.type; + } } diff --git a/src/main/java/com/oltpbenchmark/api/templates/ValuesType.java b/src/main/java/com/oltpbenchmark/api/templates/ValuesType.java index e2120bb14..6711ff53a 100644 --- a/src/main/java/com/oltpbenchmark/api/templates/ValuesType.java +++ b/src/main/java/com/oltpbenchmark/api/templates/ValuesType.java @@ -16,22 +16,21 @@ */ // -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, vJAXB 2.1.10 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2011.12.28 at 11:42:38 PM EST +// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference +// Implementation, vJAXB 2.1.10 +// See http://java.sun.com/xml/jaxb +// Any modifications to this file will be lost upon recompilation of the source schema. +// Generated on: 2011.12.28 at 11:42:38 PM EST // - package com.oltpbenchmark.api.templates; import jakarta.xml.bind.annotation.*; import java.util.ArrayList; import java.util.List; - /** - *

Java class for dialectType complex type. + * Java class for dialectType complex type. * *

The following schema fragment specifies the expected content contained within this class. * @@ -48,23 +47,23 @@ * */ @XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "valuesType", propOrder = {"value"}) +@XmlType( + name = "valuesType", + propOrder = {"value"}) public class ValuesType { - @XmlElement(required = true) - protected List value; - + @XmlElement(required = true) + protected List value; - /** - * Gets the value of the value property. - * - * Objects of the following type(s) are allowed in the list {@link String } - */ - public List getValueList() { - if (this.value == null) { - this.value = new ArrayList<>(); - } - return this.value; + /** + * Gets the value of the value property. + * + *

Objects of the following type(s) are allowed in the list {@link String } + */ + public List getValueList() { + if (this.value == null) { + this.value = new ArrayList<>(); } - + return this.value; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java index 12703b76b..dc85797aa 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark; import com.oltpbenchmark.WorkloadConfiguration; @@ -27,46 +26,45 @@ import com.oltpbenchmark.benchmarks.auctionmark.procedures.LoadConfig; import com.oltpbenchmark.benchmarks.auctionmark.procedures.ResetDatabase; import com.oltpbenchmark.util.RandomGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class AuctionMarkBenchmark extends BenchmarkModule { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkBenchmark.class); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkBenchmark.class); - private final RandomGenerator rng = new RandomGenerator((int) System.currentTimeMillis()); + private final RandomGenerator rng = new RandomGenerator((int) System.currentTimeMillis()); - public AuctionMarkBenchmark(WorkloadConfiguration workConf) { - super(workConf); + public AuctionMarkBenchmark(WorkloadConfiguration workConf) { + super(workConf); - this.registerSupplementalProcedure(LoadConfig.class); - this.registerSupplementalProcedure(CloseAuctions.class); - this.registerSupplementalProcedure(ResetDatabase.class); - } + this.registerSupplementalProcedure(LoadConfig.class); + this.registerSupplementalProcedure(CloseAuctions.class); + this.registerSupplementalProcedure(ResetDatabase.class); + } - public RandomGenerator getRandomGenerator() { - return (this.rng); - } + public RandomGenerator getRandomGenerator() { + return (this.rng); + } - @Override - protected Package getProcedurePackageImpl() { - return (GetItem.class.getPackage()); - } + @Override + protected Package getProcedurePackageImpl() { + return (GetItem.class.getPackage()); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new AuctionMarkWorker(i, this)); - } - return (workers); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new AuctionMarkWorker(i, this)); } + return (workers); + } - @Override - protected Loader makeLoaderImpl() { - return new AuctionMarkLoader(this); - } + @Override + protected Loader makeLoaderImpl() { + return new AuctionMarkLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkConstants.java index 9957b7dfd..4f08a8664 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkConstants.java @@ -15,327 +15,295 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark; import com.oltpbenchmark.util.StringUtil; - import java.util.Collection; import java.util.HashSet; public abstract class AuctionMarkConstants { - // ---------------------------------------------------------------- - // TIME PARAMETERS - // ---------------------------------------------------------------- - - public static final long SECONDS_IN_A_DAY = 24 * 60 * 60; - public static final long MILLISECONDS_IN_A_SECOND = 1000; - public static final long MILLISECONDS_IN_A_DAY = SECONDS_IN_A_DAY * MILLISECONDS_IN_A_SECOND; - - /** - * 1 sec in real time equals this value in the benchmark's virtual time in seconds - */ - public static final long TIME_SCALE_FACTOR = 600L; // one hour - - /** - * If the amount of time in seconds remaining for an item auction - * is less than this parameter, then it will be added to a special queue - * in the client. We will increase the likelihood that a users will bid on these - * items as it gets closer to their end times - */ - public static final long ITEM_ENDING_SOON = 36000L; // 10 hours - - public static final int ITEM_ALREADY_ENDED = 100000; - - // ---------------------------------------------------------------- - // EXECUTION CONFIGURATION - // ---------------------------------------------------------------- - - public static boolean CLOSE_AUCTIONS_ENABLE = false; - - /** - * How often to execute CLOSE_AUCTIONS in virtual seconds - * - * @see "AuctionMarkConstants.TIME_SCALE_FACTOR" - */ - public static final long CLOSE_AUCTIONS_INTERVAL = 12000L; // Every 20 seconds - - /** - * If set to true, the CloseAuctions transactions will be a executed - * in a separate thread. If set to false, then these txns will be executed - * whenever the interval interrupt occurs on the first worker thread - */ - public static boolean CLOSE_AUCTIONS_SEPARATE_THREAD = false; - - /** - * If set to true, then the first client will attempt to reset the database - * before starting the benchmark execution - */ - public static final boolean RESET_DATABASE_ENABLE = false; - - - // ---------------------------------------------------------------- - // STORED PROCEDURE INFORMATION - // ---------------------------------------------------------------- - - // Non-standard txns - public static final int FREQUENCY_CLOSE_AUCTIONS = -1; // called at regular intervals - - // Regular Txn Mix - public static final int FREQUENCY_GET_ITEM = 25; - public static final int FREQUENCY_GET_USER_INFO = 15; - public static final int FREQUENCY_NEW_BID = 20; - public static final int FREQUENCY_NEW_COMMENT = 5; - public static final int FREQUENCY_NEW_COMMENT_RESPONSE = 5; - public static final int FREQUENCY_NEW_FEEDBACK = 5; - public static final int FREQUENCY_NEW_ITEM = 10; - public static final int FREQUENCY_NEW_PURCHASE = 5; - public static final int FREQUENCY_UPDATE_ITEM = 10; - - // ---------------------------------------------------------------- - // DEFAULT TABLE SIZES - // ---------------------------------------------------------------- - - public static final long TABLESIZE_REGION = 75; - public static final long TABLESIZE_GLOBAL_ATTRIBUTE_GROUP = 100; - public static final long TABLESIZE_GLOBAL_ATTRIBUTE_VALUE = 1; // HACK: IGNORE - public static final long TABLESIZE_GLOBAL_ATTRIBUTE_VALUE_PER_GROUP = 10; - public static final long TABLESIZE_USERACCT = 10000; - - // ---------------------------------------------------------------- - // USER PARAMETERS - // ---------------------------------------------------------------- - - public static final int USER_MIN_ATTRIBUTES = 0; - public static final int USER_MAX_ATTRIBUTES = 5; - - public static final long USER_MIN_BALANCE = 1000; - public static final long USER_MAX_BALANCE = 100000; - - public static final long USER_MIN_RATING = 0; - public static final long USER_MAX_RATING = 10000; - - public static final int USER_ATTRIBUTE_NAME_LENGTH_MIN = 5; - public static final int USER_ATTRIBUTE_NAME_LENGTH_MAX = 32; - - public static final int USER_ATTRIBUTE_VALUE_LENGTH_MIN = 5; - public static final int USER_ATTRIBUTE_VALUE_LENGTH_MAX = 32; - - // ---------------------------------------------------------------- - // ITEM PARAMETERS - // ---------------------------------------------------------------- - - public static final int ITEM_INITIAL_PRICE_MIN = 1; - public static final int ITEM_INITIAL_PRICE_MAX = 1000; - public static final double ITEM_INITIAL_PRICE_SIGMA = 1.25; - - public static final int ITEM_ITEMS_PER_SELLER_MIN = 0; - public static final int ITEM_ITEMS_PER_SELLER_MAX = 1000; - public static final double ITEM_ITEMS_PER_SELLER_SIGMA = 2.0; - - public static final int ITEM_BIDS_PER_DAY_MIN = 0; - public static final int ITEM_BIDS_PER_DAY_MAX = 10; - public static final double ITEM_BIDS_PER_DAY_SIGMA = 1.25; - - public static final int ITEM_WATCHES_PER_DAY_MIN = 0; - public static final int ITEM_WATCHES_PER_DAY_MAX = 5; - public static final double ITEM_WATCHES_PER_DAY_SIGMA = 1.25; - - public static final int ITEM_NUM_IMAGES_MIN = 1; - public static final int ITEM_NUM_IMAGES_MAX = 10; - public static final double ITEM_NUM_IMAGES_SIGMA = 1.25; - - public static final int ITEM_NUM_COMMENTS_MIN = 0; - public static final int ITEM_NUM_COMMENTS_MAX = 5; - public static final double ITEM_NUM_COMMENTS_SIGMA = 1.25; - - public static final int ITEM_COMMENT_LENGTH_MIN = 10; - public static final int ITEM_COMMENT_LENGTH_MAX = 128; - - public static final int ITEM_NUM_GLOBAL_ATTRS_MIN = 1; - public static final int ITEM_NUM_GLOBAL_ATTRS_MAX = 10; - public static final double ITEM_NUM_GLOBAL_ATTRS_SIGMA = 1.25; - - public static final int ITEM_NAME_LENGTH_MIN = 16; - public static final int ITEM_NAME_LENGTH_MAX = 100; - - public static final int ITEM_DESCRIPTION_LENGTH_MIN = 50; - public static final int ITEM_DESCRIPTION_LENGTH_MAX = 255; - - public static final int ITEM_USER_ATTRIBUTES_LENGTH_MIN = 20; - public static final int ITEM_USER_ATTRIBUTES_LENGTH_MAX = 255; - - /** - * When an item receives a bid we will increase its price by this amount - */ - public static final float ITEM_BID_PERCENT_STEP = 0.025f; - - /** - * How long should we wait before the buyer purchases an item that they won - */ - public static final int ITEM_PURCHASE_DURATION_DAYS_MIN = 0; - public static final int ITEM_PURCHASE_DURATION_DAYS_MAX = 7; - public static final double ITEM_PURCHASE_DURATION_DAYS_SIGMA = 1.1; - - /** - * Duration in days that expired bids are preserved - */ - public static final int ITEM_PRESERVE_DAYS = 7; - - /** - * The duration in days for each auction - */ - public static final int ITEM_DURATION_DAYS_MIN = 1; - public static final int ITEM_DURATION_DAYS_MAX = 10; - - /** - * This defines the number of items to read in when LoadConfig is invoked - */ - public static final int ITEM_LOADCONFIG_LIMIT = 5000; - - /** - * This defines the maximum size of a small cache of ItemIds that - * we maintain in the benchmark profile. For some procedures, the client will - * ItemIds out of this cache and use them as txn parameters - */ - public static final int ITEM_ID_CACHE_SIZE = 1000; - - /** - * The number of update rounds in each invocation of CloseAuctions - */ - public static final int CLOSE_AUCTIONS_ROUNDS = 1; - - /** - * The number of items to pull in for each update round in CloseAuctions - */ - public static final int CLOSE_AUCTIONS_ITEMS_PER_ROUND = 100; - - /** - * The default list of columns that we will return whenever we - * query the item table. This must match the ordering expected - * in AuctionMarkWorker.processItemRecord() - */ - public static final String[] ITEM_COLUMNS = {"i_id", - "i_u_id", - "i_name", - "i_current_price", - "i_num_bids", - "i_end_date", - "i_status"}; - public static final String ITEM_COLUMNS_STR = StringUtil.join(", ", ITEM_COLUMNS); - - // ---------------------------------------------------------------- - // TABLE NAMES - // ---------------------------------------------------------------- - public static final String TABLENAME_CONFIG_PROFILE = "config_profile"; - public static final String TABLENAME_REGION = "region"; - public static final String TABLENAME_USERACCT = "useracct"; - public static final String TABLENAME_USERACCT_ATTRIBUTES = "useracct_attributes"; - public static final String TABLENAME_USERACCT_ITEM = "useracct_item"; - public static final String TABLENAME_USERACCT_WATCH = "useracct_watch"; - public static final String TABLENAME_USERACCT_FEEDBACK = "useracct_feedback"; - public static final String TABLENAME_CATEGORY = "category"; - public static final String TABLENAME_GLOBAL_ATTRIBUTE_GROUP = "global_attribute_group"; - public static final String TABLENAME_GLOBAL_ATTRIBUTE_VALUE = "global_attribute_value"; - public static final String TABLENAME_ITEM = "item"; - public static final String TABLENAME_ITEM_ATTRIBUTE = "item_attribute"; - public static final String TABLENAME_ITEM_IMAGE = "item_image"; - public static final String TABLENAME_ITEM_COMMENT = "item_comment"; - public static final String TABLENAME_ITEM_BID = "item_bid"; - public static final String TABLENAME_ITEM_MAX_BID = "item_max_bid"; - public static final String TABLENAME_ITEM_PURCHASE = "item_purchase"; - - public static final String[] TABLENAMES = { - AuctionMarkConstants.TABLENAME_REGION, - AuctionMarkConstants.TABLENAME_CATEGORY, - AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, - AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE, - AuctionMarkConstants.TABLENAME_USERACCT, - AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES, - AuctionMarkConstants.TABLENAME_USERACCT_ITEM, - AuctionMarkConstants.TABLENAME_USERACCT_WATCH, - AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK, - AuctionMarkConstants.TABLENAME_ITEM, - AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE, - AuctionMarkConstants.TABLENAME_ITEM_IMAGE, - AuctionMarkConstants.TABLENAME_ITEM_COMMENT, - AuctionMarkConstants.TABLENAME_ITEM_BID, - AuctionMarkConstants.TABLENAME_ITEM_MAX_BID, - AuctionMarkConstants.TABLENAME_ITEM_PURCHASE, - }; - - // ---------------------------------------------------------------- - // TABLE DATA SOURCES - // ---------------------------------------------------------------- - - // If a table exists in this set, then the number of tuples loaded into the table - // should not be modified by the scale factor - public static final Collection FIXED_TABLES = new HashSet<>(); - - static { - FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_REGION); - FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP); - FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE); - } - - public static final Collection DYNAMIC_TABLES = new HashSet<>(); - - static { - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_IMAGE); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_COMMENT); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_BID); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_MAX_BID); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_ITEM); - DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_WATCH); - } - - // These tables are loaded from static data files - public static final Collection DATAFILE_TABLES = new HashSet<>(); - - static { - DATAFILE_TABLES.add(AuctionMarkConstants.TABLENAME_CATEGORY); - } - - // ---------------------------------------------------------------- - // PROBABILITIES - // ---------------------------------------------------------------- - - /** - * The probability that a buyer will leave feedback for the seller (1-100) - */ - public static final int PROB_PURCHASE_BUYER_LEAVES_FEEDBACK = 75; - /** - * The probability that a seller will leave feedback for the buyer (1-100) - */ - public static final int PROB_PURCHASE_SELLER_LEAVES_FEEDBACK = 80; - - public static final int PROB_GETUSERINFO_INCLUDE_FEEDBACK = 25; - public static final int PROB_GETUSERINFO_INCLUDE_COMMENTS = 10; - public static final int PROB_GETUSERINFO_INCLUDE_SELLER_ITEMS = 10; - public static final int PROB_GETUSERINFO_INCLUDE_BUYER_ITEMS = 10; - public static final int PROB_GETUSERINFO_INCLUDE_WATCHED_ITEMS = 10; - - public static final int PROB_UPDATEITEM_DELETE_ATTRIBUTE = 25; - public static final int PROB_UPDATEITEM_ADD_ATTRIBUTE = -1; // 25; - - /** - * The probability that a buyer will not have enough money to purchase an item (1-100) - */ - public static final int PROB_NEWPURCHASE_NOT_ENOUGH_MONEY = 1; - - /** - * The probability that the NewBid txn will try to bid on a closed item (1-100) - */ - public static final int PROB_NEWBID_CLOSED_ITEM = 5; - - /** - * The probability that a NewBid txn will target an item whose auction is ending soon (1-100) - */ - public static final int PROB_NEWBID_ENDINGSOON_ITEM = 50; + // ---------------------------------------------------------------- + // TIME PARAMETERS + // ---------------------------------------------------------------- + + public static final long SECONDS_IN_A_DAY = 24 * 60 * 60; + public static final long MILLISECONDS_IN_A_SECOND = 1000; + public static final long MILLISECONDS_IN_A_DAY = SECONDS_IN_A_DAY * MILLISECONDS_IN_A_SECOND; + + /** 1 sec in real time equals this value in the benchmark's virtual time in seconds */ + public static final long TIME_SCALE_FACTOR = 600L; // one hour + + /** + * If the amount of time in seconds remaining for an item auction is less than this parameter, + * then it will be added to a special queue in the client. We will increase the likelihood that a + * users will bid on these items as it gets closer to their end times + */ + public static final long ITEM_ENDING_SOON = 36000L; // 10 hours + + public static final int ITEM_ALREADY_ENDED = 100000; + + // ---------------------------------------------------------------- + // EXECUTION CONFIGURATION + // ---------------------------------------------------------------- + + public static boolean CLOSE_AUCTIONS_ENABLE = false; + + /** + * How often to execute CLOSE_AUCTIONS in virtual seconds + * + * @see "AuctionMarkConstants.TIME_SCALE_FACTOR" + */ + public static final long CLOSE_AUCTIONS_INTERVAL = 12000L; // Every 20 seconds + + /** + * If set to true, the CloseAuctions transactions will be a executed in a separate thread. If set + * to false, then these txns will be executed whenever the interval interrupt occurs on the first + * worker thread + */ + public static boolean CLOSE_AUCTIONS_SEPARATE_THREAD = false; + + /** + * If set to true, then the first client will attempt to reset the database before starting the + * benchmark execution + */ + public static final boolean RESET_DATABASE_ENABLE = false; + + // ---------------------------------------------------------------- + // STORED PROCEDURE INFORMATION + // ---------------------------------------------------------------- + + // Non-standard txns + public static final int FREQUENCY_CLOSE_AUCTIONS = -1; // called at regular intervals + + // Regular Txn Mix + public static final int FREQUENCY_GET_ITEM = 25; + public static final int FREQUENCY_GET_USER_INFO = 15; + public static final int FREQUENCY_NEW_BID = 20; + public static final int FREQUENCY_NEW_COMMENT = 5; + public static final int FREQUENCY_NEW_COMMENT_RESPONSE = 5; + public static final int FREQUENCY_NEW_FEEDBACK = 5; + public static final int FREQUENCY_NEW_ITEM = 10; + public static final int FREQUENCY_NEW_PURCHASE = 5; + public static final int FREQUENCY_UPDATE_ITEM = 10; + + // ---------------------------------------------------------------- + // DEFAULT TABLE SIZES + // ---------------------------------------------------------------- + + public static final long TABLESIZE_REGION = 75; + public static final long TABLESIZE_GLOBAL_ATTRIBUTE_GROUP = 100; + public static final long TABLESIZE_GLOBAL_ATTRIBUTE_VALUE = 1; // HACK: IGNORE + public static final long TABLESIZE_GLOBAL_ATTRIBUTE_VALUE_PER_GROUP = 10; + public static final long TABLESIZE_USERACCT = 10000; + + // ---------------------------------------------------------------- + // USER PARAMETERS + // ---------------------------------------------------------------- + + public static final int USER_MIN_ATTRIBUTES = 0; + public static final int USER_MAX_ATTRIBUTES = 5; + + public static final long USER_MIN_BALANCE = 1000; + public static final long USER_MAX_BALANCE = 100000; + public static final long USER_MIN_RATING = 0; + public static final long USER_MAX_RATING = 10000; + + public static final int USER_ATTRIBUTE_NAME_LENGTH_MIN = 5; + public static final int USER_ATTRIBUTE_NAME_LENGTH_MAX = 32; + + public static final int USER_ATTRIBUTE_VALUE_LENGTH_MIN = 5; + public static final int USER_ATTRIBUTE_VALUE_LENGTH_MAX = 32; + + // ---------------------------------------------------------------- + // ITEM PARAMETERS + // ---------------------------------------------------------------- + + public static final int ITEM_INITIAL_PRICE_MIN = 1; + public static final int ITEM_INITIAL_PRICE_MAX = 1000; + public static final double ITEM_INITIAL_PRICE_SIGMA = 1.25; + + public static final int ITEM_ITEMS_PER_SELLER_MIN = 0; + public static final int ITEM_ITEMS_PER_SELLER_MAX = 1000; + public static final double ITEM_ITEMS_PER_SELLER_SIGMA = 2.0; + + public static final int ITEM_BIDS_PER_DAY_MIN = 0; + public static final int ITEM_BIDS_PER_DAY_MAX = 10; + public static final double ITEM_BIDS_PER_DAY_SIGMA = 1.25; + + public static final int ITEM_WATCHES_PER_DAY_MIN = 0; + public static final int ITEM_WATCHES_PER_DAY_MAX = 5; + public static final double ITEM_WATCHES_PER_DAY_SIGMA = 1.25; + + public static final int ITEM_NUM_IMAGES_MIN = 1; + public static final int ITEM_NUM_IMAGES_MAX = 10; + public static final double ITEM_NUM_IMAGES_SIGMA = 1.25; + + public static final int ITEM_NUM_COMMENTS_MIN = 0; + public static final int ITEM_NUM_COMMENTS_MAX = 5; + public static final double ITEM_NUM_COMMENTS_SIGMA = 1.25; + + public static final int ITEM_COMMENT_LENGTH_MIN = 10; + public static final int ITEM_COMMENT_LENGTH_MAX = 128; + + public static final int ITEM_NUM_GLOBAL_ATTRS_MIN = 1; + public static final int ITEM_NUM_GLOBAL_ATTRS_MAX = 10; + public static final double ITEM_NUM_GLOBAL_ATTRS_SIGMA = 1.25; + + public static final int ITEM_NAME_LENGTH_MIN = 16; + public static final int ITEM_NAME_LENGTH_MAX = 100; + + public static final int ITEM_DESCRIPTION_LENGTH_MIN = 50; + public static final int ITEM_DESCRIPTION_LENGTH_MAX = 255; + + public static final int ITEM_USER_ATTRIBUTES_LENGTH_MIN = 20; + public static final int ITEM_USER_ATTRIBUTES_LENGTH_MAX = 255; + + /** When an item receives a bid we will increase its price by this amount */ + public static final float ITEM_BID_PERCENT_STEP = 0.025f; + + /** How long should we wait before the buyer purchases an item that they won */ + public static final int ITEM_PURCHASE_DURATION_DAYS_MIN = 0; + + public static final int ITEM_PURCHASE_DURATION_DAYS_MAX = 7; + public static final double ITEM_PURCHASE_DURATION_DAYS_SIGMA = 1.1; + + /** Duration in days that expired bids are preserved */ + public static final int ITEM_PRESERVE_DAYS = 7; + + /** The duration in days for each auction */ + public static final int ITEM_DURATION_DAYS_MIN = 1; + + public static final int ITEM_DURATION_DAYS_MAX = 10; + + /** This defines the number of items to read in when LoadConfig is invoked */ + public static final int ITEM_LOADCONFIG_LIMIT = 5000; + + /** + * This defines the maximum size of a small cache of ItemIds that we maintain in the benchmark + * profile. For some procedures, the client will ItemIds out of this cache and use them as txn + * parameters + */ + public static final int ITEM_ID_CACHE_SIZE = 1000; + + /** The number of update rounds in each invocation of CloseAuctions */ + public static final int CLOSE_AUCTIONS_ROUNDS = 1; + + /** The number of items to pull in for each update round in CloseAuctions */ + public static final int CLOSE_AUCTIONS_ITEMS_PER_ROUND = 100; + + /** + * The default list of columns that we will return whenever we query the item table. This must + * match the ordering expected in AuctionMarkWorker.processItemRecord() + */ + public static final String[] ITEM_COLUMNS = { + "i_id", "i_u_id", "i_name", "i_current_price", "i_num_bids", "i_end_date", "i_status" + }; + + public static final String ITEM_COLUMNS_STR = StringUtil.join(", ", ITEM_COLUMNS); + + // ---------------------------------------------------------------- + // TABLE NAMES + // ---------------------------------------------------------------- + public static final String TABLENAME_CONFIG_PROFILE = "config_profile"; + public static final String TABLENAME_REGION = "region"; + public static final String TABLENAME_USERACCT = "useracct"; + public static final String TABLENAME_USERACCT_ATTRIBUTES = "useracct_attributes"; + public static final String TABLENAME_USERACCT_ITEM = "useracct_item"; + public static final String TABLENAME_USERACCT_WATCH = "useracct_watch"; + public static final String TABLENAME_USERACCT_FEEDBACK = "useracct_feedback"; + public static final String TABLENAME_CATEGORY = "category"; + public static final String TABLENAME_GLOBAL_ATTRIBUTE_GROUP = "global_attribute_group"; + public static final String TABLENAME_GLOBAL_ATTRIBUTE_VALUE = "global_attribute_value"; + public static final String TABLENAME_ITEM = "item"; + public static final String TABLENAME_ITEM_ATTRIBUTE = "item_attribute"; + public static final String TABLENAME_ITEM_IMAGE = "item_image"; + public static final String TABLENAME_ITEM_COMMENT = "item_comment"; + public static final String TABLENAME_ITEM_BID = "item_bid"; + public static final String TABLENAME_ITEM_MAX_BID = "item_max_bid"; + public static final String TABLENAME_ITEM_PURCHASE = "item_purchase"; + + public static final String[] TABLENAMES = { + AuctionMarkConstants.TABLENAME_REGION, + AuctionMarkConstants.TABLENAME_CATEGORY, + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE, + AuctionMarkConstants.TABLENAME_USERACCT, + AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES, + AuctionMarkConstants.TABLENAME_USERACCT_ITEM, + AuctionMarkConstants.TABLENAME_USERACCT_WATCH, + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK, + AuctionMarkConstants.TABLENAME_ITEM, + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE, + AuctionMarkConstants.TABLENAME_ITEM_IMAGE, + AuctionMarkConstants.TABLENAME_ITEM_COMMENT, + AuctionMarkConstants.TABLENAME_ITEM_BID, + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID, + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE, + }; + + // ---------------------------------------------------------------- + // TABLE DATA SOURCES + // ---------------------------------------------------------------- + + // If a table exists in this set, then the number of tuples loaded into the table + // should not be modified by the scale factor + public static final Collection FIXED_TABLES = new HashSet<>(); + + static { + FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_REGION); + FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP); + FIXED_TABLES.add(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE); + } + + public static final Collection DYNAMIC_TABLES = new HashSet<>(); + + static { + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_IMAGE); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_COMMENT); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_BID); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_MAX_BID); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_ITEM); + DYNAMIC_TABLES.add(AuctionMarkConstants.TABLENAME_USERACCT_WATCH); + } + + // These tables are loaded from static data files + public static final Collection DATAFILE_TABLES = new HashSet<>(); + + static { + DATAFILE_TABLES.add(AuctionMarkConstants.TABLENAME_CATEGORY); + } + + // ---------------------------------------------------------------- + // PROBABILITIES + // ---------------------------------------------------------------- + + /** The probability that a buyer will leave feedback for the seller (1-100) */ + public static final int PROB_PURCHASE_BUYER_LEAVES_FEEDBACK = 75; + + /** The probability that a seller will leave feedback for the buyer (1-100) */ + public static final int PROB_PURCHASE_SELLER_LEAVES_FEEDBACK = 80; + + public static final int PROB_GETUSERINFO_INCLUDE_FEEDBACK = 25; + public static final int PROB_GETUSERINFO_INCLUDE_COMMENTS = 10; + public static final int PROB_GETUSERINFO_INCLUDE_SELLER_ITEMS = 10; + public static final int PROB_GETUSERINFO_INCLUDE_BUYER_ITEMS = 10; + public static final int PROB_GETUSERINFO_INCLUDE_WATCHED_ITEMS = 10; + + public static final int PROB_UPDATEITEM_DELETE_ATTRIBUTE = 25; + public static final int PROB_UPDATEITEM_ADD_ATTRIBUTE = -1; // 25; + + /** The probability that a buyer will not have enough money to purchase an item (1-100) */ + public static final int PROB_NEWPURCHASE_NOT_ENOUGH_MONEY = 1; + + /** The probability that the NewBid txn will try to bid on a closed item (1-100) */ + public static final int PROB_NEWBID_CLOSED_ITEM = 5; + + /** The probability that a NewBid txn will target an item whose auction is ending soon (1-100) */ + public static final int PROB_NEWBID_ENDINGSOON_ITEM = 50; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java index 5fa073cbb..ddef61bd7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkLoader.java @@ -23,12 +23,10 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.*; import com.oltpbenchmark.catalog.Column; import com.oltpbenchmark.catalog.Table; +import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.*; import com.oltpbenchmark.util.RandomDistribution.Flat; import com.oltpbenchmark.util.RandomDistribution.Zipf; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.map.ListOrderedMap; - import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; @@ -39,8 +37,8 @@ import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; - -import com.oltpbenchmark.types.DatabaseType; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.map.ListOrderedMap; /** * @author pavlo @@ -48,1497 +46,1616 @@ */ public final class AuctionMarkLoader extends Loader { - // ----------------------------------------------------------------- - // INTERNAL DATA MEMBERS - // ----------------------------------------------------------------- - - protected final AuctionMarkProfile profile; - - /** - * Data Generator Classes TableName -> AbstactTableGenerator - */ - private final Map generators = Collections.synchronizedMap(new ListOrderedMap<>()); - - - /** - * The set of tables that we have finished loading - **/ - private final transient Collection finished = Collections.synchronizedCollection(new HashSet<>()); - - private final Histogram tableSizes = new Histogram<>(); - - - // ----------------------------------------------------------------- - // INITIALIZATION - // ----------------------------------------------------------------- - - public AuctionMarkLoader(AuctionMarkBenchmark benchmark) { - super(benchmark); - - // BenchmarkProfile - this.profile = new AuctionMarkProfile(benchmark, benchmark.getRandomGenerator()); - - - try { - - // --------------------------- - // Fixed-Size Table Generators - // --------------------------- - - this.registerGenerator(new RegionGenerator()); - this.registerGenerator(new CategoryGenerator()); - this.registerGenerator(new GlobalAttributeGroupGenerator()); - this.registerGenerator(new GlobalAttributeValueGenerator()); - - // --------------------------- - // Scaling-Size Table Generators - // --------------------------- - - // depends on REGION - this.registerGenerator(new UserGenerator()); - // depends on USERACCT - this.registerGenerator(new UserAttributesGenerator()); - - // depends on USERACCT, CATEGORY - this.registerGenerator(new ItemGenerator()); - // depends on ITEM - this.registerGenerator(new ItemCommentGenerator()); - // depends on ITEM - this.registerGenerator(new ItemImageGenerator()); - // depends on ITEM - this.registerGenerator(new ItemBidGenerator()); - - // depends on ITEM, GLOBAL_ATTRIBUTE_GROUP, GLOBAL_ATTRIBUTE_VALUE - this.registerGenerator(new ItemAttributeGenerator()); - - // depends on ITEM_BID - this.registerGenerator(new ItemMaxBidGenerator()); - // depends on ITEM_BID - this.registerGenerator(new ItemPurchaseGenerator()); - // depends on ITEM_BID - this.registerGenerator(new UserItemGenerator()); - // depends on ITEM_BID - this.registerGenerator(new UserWatchGenerator()); - - // depends on ITEM_PURCHASE - this.registerGenerator(new UserFeedbackGenerator()); - } catch (SQLException e) { - throw new RuntimeException(e); - } + // ----------------------------------------------------------------- + // INTERNAL DATA MEMBERS + // ----------------------------------------------------------------- + + protected final AuctionMarkProfile profile; + + /** Data Generator Classes TableName -> AbstactTableGenerator */ + private final Map generators = + Collections.synchronizedMap(new ListOrderedMap<>()); + + /** The set of tables that we have finished loading */ + private final transient Collection finished = + Collections.synchronizedCollection(new HashSet<>()); + + private final Histogram tableSizes = new Histogram<>(); + + // ----------------------------------------------------------------- + // INITIALIZATION + // ----------------------------------------------------------------- + + public AuctionMarkLoader(AuctionMarkBenchmark benchmark) { + super(benchmark); + + // BenchmarkProfile + this.profile = new AuctionMarkProfile(benchmark, benchmark.getRandomGenerator()); + + try { + + // --------------------------- + // Fixed-Size Table Generators + // --------------------------- + + this.registerGenerator(new RegionGenerator()); + this.registerGenerator(new CategoryGenerator()); + this.registerGenerator(new GlobalAttributeGroupGenerator()); + this.registerGenerator(new GlobalAttributeValueGenerator()); + + // --------------------------- + // Scaling-Size Table Generators + // --------------------------- + + // depends on REGION + this.registerGenerator(new UserGenerator()); + // depends on USERACCT + this.registerGenerator(new UserAttributesGenerator()); + + // depends on USERACCT, CATEGORY + this.registerGenerator(new ItemGenerator()); + // depends on ITEM + this.registerGenerator(new ItemCommentGenerator()); + // depends on ITEM + this.registerGenerator(new ItemImageGenerator()); + // depends on ITEM + this.registerGenerator(new ItemBidGenerator()); + + // depends on ITEM, GLOBAL_ATTRIBUTE_GROUP, GLOBAL_ATTRIBUTE_VALUE + this.registerGenerator(new ItemAttributeGenerator()); + + // depends on ITEM_BID + this.registerGenerator(new ItemMaxBidGenerator()); + // depends on ITEM_BID + this.registerGenerator(new ItemPurchaseGenerator()); + // depends on ITEM_BID + this.registerGenerator(new UserItemGenerator()); + // depends on ITEM_BID + this.registerGenerator(new UserWatchGenerator()); + + // depends on ITEM_PURCHASE + this.registerGenerator(new UserFeedbackGenerator()); + } catch (SQLException e) { + throw new RuntimeException(e); } + } - // ----------------------------------------------------------------- - // LOADING METHODS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // LOADING METHODS + // ----------------------------------------------------------------- - private class CountdownLoaderThread extends LoaderThread { - private final AbstractTableGenerator generator; - private final CountDownLatch latch; + private class CountdownLoaderThread extends LoaderThread { + private final AbstractTableGenerator generator; + private final CountDownLatch latch; - public CountdownLoaderThread(BenchmarkModule benchmarkModule, AbstractTableGenerator generator, CountDownLatch latch) { - super(benchmarkModule); - this.generator = generator; - this.latch = latch; - } - - @Override - public void load(Connection conn) throws SQLException { - LOG.debug(String.format("Started loading %s which depends on %s", this.generator.getTableName(), this.generator.getDependencies())); - this.generator.load(conn); - LOG.debug(String.format("Finished loading %s", this.generator.getTableName())); - } - - @Override - public void beforeLoad() { - this.generator.beforeLoad(); - } - - @Override - public void afterLoad() { - this.generator.afterLoad(); - this.latch.countDown(); - } + public CountdownLoaderThread( + BenchmarkModule benchmarkModule, AbstractTableGenerator generator, CountDownLatch latch) { + super(benchmarkModule); + this.generator = generator; + this.latch = latch; } @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - - final CountDownLatch loadLatch = new CountDownLatch(this.generators.size()); - - for (AbstractTableGenerator generator : this.generators.values()) { - generator.init(); - threads.add(new CountdownLoaderThread(this.benchmark, generator, loadLatch)); - } - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - profile.saveProfile(conn); - } - - @Override - public void beforeLoad() { - try { - loadLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - - return threads; + public void load(Connection conn) throws SQLException { + LOG.debug( + String.format( + "Started loading %s which depends on %s", + this.generator.getTableName(), this.generator.getDependencies())); + this.generator.load(conn); + LOG.debug(String.format("Finished loading %s", this.generator.getTableName())); } - private void registerGenerator(AbstractTableGenerator generator) { - // Register this one as well as any sub-generators - this.generators.put(generator.getTableName(), generator); - for (AbstractTableGenerator sub_generator : generator.getSubTableGenerators()) { - this.registerGenerator(sub_generator); - } + @Override + public void beforeLoad() { + this.generator.beforeLoad(); } - protected AbstractTableGenerator getGenerator(String table_name) { - return (this.generators.get(table_name)); + @Override + public void afterLoad() { + this.generator.afterLoad(); + this.latch.countDown(); } + } - protected void generateTableData(Connection conn, String tableName) throws SQLException { - LOG.debug("*** START {}", tableName); - final AbstractTableGenerator generator = this.generators.get(tableName); + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final CountDownLatch loadLatch = new CountDownLatch(this.generators.size()); - // Generate Data - final Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - - final List volt_table = generator.getVoltTable(); - final String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - boolean shouldExecuteBatch = false; - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - final int[] types = catalog_tbl.getColumnTypes(); - - while (generator.hasMore()) { - generator.generateBatch(); - - for (Object[] row : volt_table) { - for (int i = 0; i < row.length; i++) { - if (row[i] != null) { - stmt.setObject(i + 1, row[i]); - } else { - stmt.setNull(i + 1, types[i]); - } - } - stmt.addBatch(); - shouldExecuteBatch = true; - } - - if (shouldExecuteBatch) { - stmt.executeBatch(); - stmt.clearBatch(); - shouldExecuteBatch = false; - } - - - this.tableSizes.put(tableName, volt_table.size()); - - // Release anything to the sub-generators if we have it - // We have to do this to ensure that all of the parent tuples get - // insert first for foreign-key relationships - generator.releaseHoldsToSubTableGenerators(); - } - } - - - generator.markAsFinished(); - - synchronized (this) { - this.finished.add(tableName); - LOG.debug(String.format("*** FINISH %s - %d tuples - [%d / %d]", tableName, this.tableSizes.get(tableName), this.finished.size(), this.generators.size())); - if (LOG.isDebugEnabled()) { - LOG.debug("Remaining Tables: {}", CollectionUtils.subtract(this.generators.keySet(), this.finished)); - } - } - + for (AbstractTableGenerator generator : this.generators.values()) { + generator.init(); + threads.add(new CountdownLoaderThread(this.benchmark, generator, loadLatch)); } - /********************************************************************************************** - * AbstractTableGenerator - **********************************************************************************************/ - protected abstract class AbstractTableGenerator extends LoaderThread { - private final String tableName; - private final Table catalog_tbl; - protected final List table = new ArrayList<>(); - protected Long tableSize; - protected int batchSize; - protected final CountDownLatch latch = new CountDownLatch(1); - protected final List dependencyTables = new ArrayList<>(); - - /** - * Some generators have children tables that we want to load tuples for each batch of this generator. - * The queues we need to update every time we generate a new LoaderItemInfo - */ - protected final Set> sub_generators = new HashSet<>(); - - protected final List subGenerator_hold = new ArrayList<>(); - - protected long count = 0; - - /** - * Any column with the name XX_SATTR## will automatically be filled with a random string - */ - protected final List random_str_cols = new ArrayList<>(); - protected final Pattern random_str_regex = Pattern.compile("[\\w]+\\_SATTR[\\d]+", Pattern.CASE_INSENSITIVE); - - /** - * Any column with the name XX_IATTR## will automatically be filled with a random integer - */ - protected List random_int_cols = new ArrayList<>(); - protected final Pattern random_int_regex = Pattern.compile("[\\w]+\\_IATTR[\\d]+", Pattern.CASE_INSENSITIVE); - - public AbstractTableGenerator(String tableName, String... dependencies) { - super(benchmark); - this.tableName = tableName; - this.catalog_tbl = benchmark.getCatalog().getTable(tableName); - this.batchSize = workConf.getBatchSize(); - - - boolean fixed_size = AuctionMarkConstants.FIXED_TABLES.contains(catalog_tbl.getName().toLowerCase()); - boolean dynamic_size = AuctionMarkConstants.DYNAMIC_TABLES.contains(catalog_tbl.getName().toLowerCase()); - boolean data_file = AuctionMarkConstants.DATAFILE_TABLES.contains(catalog_tbl.getName().toLowerCase()); - - // Add the dependencies so that we know what we need to block on - CollectionUtil.addAll(this.dependencyTables, dependencies); - - // Initialize dynamic parameters for tables that are not loaded from data files - if (!data_file && !dynamic_size && !tableName.equalsIgnoreCase(AuctionMarkConstants.TABLENAME_ITEM)) { - String field_name = "TABLESIZE_" + catalog_tbl.getName().toUpperCase(); - try { - - Field field_handle = AuctionMarkConstants.class.getField(field_name); - - this.tableSize = (Long) field_handle.get(null); - if (!fixed_size) { - this.tableSize = (long) Math.max(1, (int) Math.round(this.tableSize * profile.getScaleFactor())); - } - } catch (NoSuchFieldException ex) { - LOG.warn("No table size constant in AuctionMarkConstants for [{}]", field_name); - } catch (Exception ex) { - throw new RuntimeException("Missing field '" + field_name + "' needed for '" + tableName + "'", ex); - } - } - - for (Column catalog_col : this.catalog_tbl.getColumns()) { - if (random_str_regex.matcher(catalog_col.getName().toUpperCase()).matches()) { - - this.random_str_cols.add(catalog_col); - if (LOG.isTraceEnabled()) { - LOG.trace("Random String Column: {}", catalog_col.getName().toLowerCase()); - } - } else if (random_int_regex.matcher(catalog_col.getName().toUpperCase()).matches()) { - - this.random_int_cols.add(catalog_col); - if (LOG.isTraceEnabled()) { - LOG.trace("Random Integer Column: {}", catalog_col.getName().toLowerCase()); - } - } - } - if (LOG.isDebugEnabled()) { - if (this.random_str_cols.size() > 0) { - LOG.debug(String.format("%s Random String Columns: %s", tableName, this.random_str_cols)); - } - if (this.random_int_cols.size() > 0) { - LOG.debug(String.format("%s Random Integer Columns: %s", tableName, this.random_int_cols)); - } - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + profile.saveProfile(conn); + } - /** - * Initiate data that need dependencies - */ - public abstract void init(); - - /** - * Prepare to generate tuples - */ - public abstract void prepare(); - - /** - * All sub-classes must implement this. This will enter new tuple data into the row - * - * @param row TODO - */ - protected abstract int populateRow(Object[] row); - - @Override - public void load(Connection conn) { - // Then invoke the loader generation method + @Override + public void beforeLoad() { try { - AuctionMarkLoader.this.generateTableData(conn, this.tableName); - } catch (Throwable ex) { - throw new RuntimeException("Unexpected error while generating table data for '" + this.tableName + "'", ex); + loadLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - } + } + }); - @Override - public void beforeLoad() { - // First block on the CountDownLatches of all the tables that we depend on - if (this.dependencyTables.size() > 0 && LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: Table generator is blocked waiting for %d other tables: %s", this.tableName, this.dependencyTables.size(), this.dependencyTables)); - } - for (String dependency : this.dependencyTables) { - AbstractTableGenerator gen = AuctionMarkLoader.this.generators.get(dependency); - - try { - gen.latch.await(); - } catch (InterruptedException ex) { - throw new RuntimeException("Unexpected interruption for '" + this.tableName + "' waiting for '" + dependency + "'", ex); - } - } + return threads; + } - // Make sure we call prepare before we start generating table data - this.prepare(); - } + private void registerGenerator(AbstractTableGenerator generator) { + // Register this one as well as any sub-generators + this.generators.put(generator.getTableName(), generator); + for (AbstractTableGenerator sub_generator : generator.getSubTableGenerators()) { + this.registerGenerator(sub_generator); + } + } - @SuppressWarnings("unchecked") - public T addSubTableGenerator(SubTableGenerator sub_item) { - this.sub_generators.add(sub_item); - return ((T) this); - } + protected AbstractTableGenerator getGenerator(String table_name) { + return (this.generators.get(table_name)); + } - @SuppressWarnings("unchecked") - public void releaseHoldsToSubTableGenerators() { - if (!this.subGenerator_hold.isEmpty()) { - LOG.trace(String.format("%s: Releasing %d held objects to %d sub-generators", this.tableName, this.subGenerator_hold.size(), this.sub_generators.size())); - for (@SuppressWarnings("rawtypes") SubTableGenerator sub_generator : this.sub_generators) { - sub_generator.queue.addAll(this.subGenerator_hold); - } - this.subGenerator_hold.clear(); - } - } + protected void generateTableData(Connection conn, String tableName) throws SQLException { + LOG.debug("*** START {}", tableName); + final AbstractTableGenerator generator = this.generators.get(tableName); - public void updateSubTableGenerators(Object obj) { - // Queue up this item for our multi-threaded sub-generators - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("%s: Updating %d sub-generators with %s: %s", this.tableName, this.sub_generators.size(), obj, this.sub_generators)); - } - this.subGenerator_hold.add(obj); - } + // Generate Data + final Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - public Collection> getSubTableGenerators() { - return (this.sub_generators); - } - - public Collection getSubGeneratorTableNames() { - List names = new ArrayList<>(); - for (AbstractTableGenerator gen : this.sub_generators) { - names.add(gen.catalog_tbl.getName().toLowerCase()); - } - return (names); - } - - protected int populateRandomColumns(Object[] row) { - int cols = 0; + final List volt_table = generator.getVoltTable(); + final String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + boolean shouldExecuteBatch = false; + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + final int[] types = catalog_tbl.getColumnTypes(); - // STRINGS - for (Column catalog_col : this.random_str_cols) { - int size = catalog_col.getSize(); - // This (0) can generate an empty string which is treated as NULL in Oracle DB - int start = getDatabaseType() == DatabaseType.ORACLE ? 1 : 0; - row[catalog_col.getIndex()] = profile.rng.astring(profile.rng.nextInt(start, size - 1), size); - cols++; - } + while (generator.hasMore()) { + generator.generateBatch(); - // INTEGER - for (Column catalog_col : this.random_int_cols) { - row[catalog_col.getIndex()] = profile.rng.number(0, 1 << 30); - cols++; + for (Object[] row : volt_table) { + for (int i = 0; i < row.length; i++) { + if (row[i] != null) { + stmt.setObject(i + 1, row[i]); + } else { + stmt.setNull(i + 1, types[i]); } - - return (cols); + } + stmt.addBatch(); + shouldExecuteBatch = true; } - public synchronized boolean hasMore() { - return (this.count < this.tableSize); + if (shouldExecuteBatch) { + stmt.executeBatch(); + stmt.clearBatch(); + shouldExecuteBatch = false; } - public Table getTableCatalog() { - return (this.catalog_tbl); - } + this.tableSizes.put(tableName, volt_table.size()); - public List getVoltTable() { - return this.table; - } - - public Long getTableSize() { - return this.tableSize; - } + // Release anything to the sub-generators if we have it + // We have to do this to ensure that all of the parent tuples get + // insert first for foreign-key relationships + generator.releaseHoldsToSubTableGenerators(); + } + } - public int getBatchSize() { - return this.batchSize; - } + generator.markAsFinished(); + + synchronized (this) { + this.finished.add(tableName); + LOG.debug( + String.format( + "*** FINISH %s - %d tuples - [%d / %d]", + tableName, + this.tableSizes.get(tableName), + this.finished.size(), + this.generators.size())); + if (LOG.isDebugEnabled()) { + LOG.debug( + "Remaining Tables: {}", + CollectionUtils.subtract(this.generators.keySet(), this.finished)); + } + } + } + + /********************************************************************************************** + * AbstractTableGenerator + **********************************************************************************************/ + protected abstract class AbstractTableGenerator extends LoaderThread { + private final String tableName; + private final Table catalog_tbl; + protected final List table = new ArrayList<>(); + protected Long tableSize; + protected int batchSize; + protected final CountDownLatch latch = new CountDownLatch(1); + protected final List dependencyTables = new ArrayList<>(); - public String getTableName() { - return this.tableName; - } + /** + * Some generators have children tables that we want to load tuples for each batch of this + * generator. The queues we need to update every time we generate a new LoaderItemInfo + */ + protected final Set> sub_generators = new HashSet<>(); - public synchronized long getCount() { - return this.count; - } + protected final List subGenerator_hold = new ArrayList<>(); - /** - * When called, the generator will populate a new row record and append it to the underlying VoltTable - */ - public synchronized void addRow() { - Object[] row = new Object[this.catalog_tbl.getColumnCount()]; + protected long count = 0; - // Main Columns - int cols = this.populateRow(row); + /** Any column with the name XX_SATTR## will automatically be filled with a random string */ + protected final List random_str_cols = new ArrayList<>(); - // RANDOM COLS - cols += this.populateRandomColumns(row); + protected final Pattern random_str_regex = + Pattern.compile("[\\w]+\\_SATTR[\\d]+", Pattern.CASE_INSENSITIVE); - // Convert all CompositeIds into their long encodings - for (int i = 0; i < cols; i++) { - if (row[i] != null && row[i] instanceof CompositeId) { - row[i] = ((CompositeId) row[i]).encode(); - } - } + /** Any column with the name XX_IATTR## will automatically be filled with a random integer */ + protected List random_int_cols = new ArrayList<>(); - this.count++; - this.table.add(row); - } + protected final Pattern random_int_regex = + Pattern.compile("[\\w]+\\_IATTR[\\d]+", Pattern.CASE_INSENSITIVE); - /** - * - */ - public void generateBatch() { - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("%s: Generating new batch", this.getTableName())); - } - long batch_count = 0; - this.table.clear(); - while (this.hasMore() && this.table.size() < this.batchSize) { - this.addRow(); - batch_count++; - } - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("%s: Finished generating new batch of %d tuples", this.getTableName(), batch_count)); - } - } + public AbstractTableGenerator(String tableName, String... dependencies) { + super(benchmark); + this.tableName = tableName; + this.catalog_tbl = benchmark.getCatalog().getTable(tableName); + this.batchSize = workConf.getBatchSize(); - public void markAsFinished() { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: Marking as finished", this.tableName)); - } - this.latch.countDown(); - for (SubTableGenerator sub_generator : this.sub_generators) { - sub_generator.stopWhenEmpty(); - } - } + boolean fixed_size = + AuctionMarkConstants.FIXED_TABLES.contains(catalog_tbl.getName().toLowerCase()); + boolean dynamic_size = + AuctionMarkConstants.DYNAMIC_TABLES.contains(catalog_tbl.getName().toLowerCase()); + boolean data_file = + AuctionMarkConstants.DATAFILE_TABLES.contains(catalog_tbl.getName().toLowerCase()); - public boolean isFinish() { - return (this.latch.getCount() == 0); - } + // Add the dependencies so that we know what we need to block on + CollectionUtil.addAll(this.dependencyTables, dependencies); - public List getDependencies() { - return this.dependencyTables; - } + // Initialize dynamic parameters for tables that are not loaded from data files + if (!data_file + && !dynamic_size + && !tableName.equalsIgnoreCase(AuctionMarkConstants.TABLENAME_ITEM)) { + String field_name = "TABLESIZE_" + catalog_tbl.getName().toUpperCase(); + try { - @Override - public String toString() { - return String.format("Generator[%s]", this.tableName); - } + Field field_handle = AuctionMarkConstants.class.getField(field_name); + + this.tableSize = (Long) field_handle.get(null); + if (!fixed_size) { + this.tableSize = + (long) Math.max(1, (int) Math.round(this.tableSize * profile.getScaleFactor())); + } + } catch (NoSuchFieldException ex) { + LOG.warn("No table size constant in AuctionMarkConstants for [{}]", field_name); + } catch (Exception ex) { + throw new RuntimeException( + "Missing field '" + field_name + "' needed for '" + tableName + "'", ex); + } + } + + for (Column catalog_col : this.catalog_tbl.getColumns()) { + if (random_str_regex.matcher(catalog_col.getName().toUpperCase()).matches()) { + + this.random_str_cols.add(catalog_col); + if (LOG.isTraceEnabled()) { + LOG.trace("Random String Column: {}", catalog_col.getName().toLowerCase()); + } + } else if (random_int_regex.matcher(catalog_col.getName().toUpperCase()).matches()) { + + this.random_int_cols.add(catalog_col); + if (LOG.isTraceEnabled()) { + LOG.trace("Random Integer Column: {}", catalog_col.getName().toLowerCase()); + } + } + } + if (LOG.isDebugEnabled()) { + if (this.random_str_cols.size() > 0) { + LOG.debug(String.format("%s Random String Columns: %s", tableName, this.random_str_cols)); + } + if (this.random_int_cols.size() > 0) { + LOG.debug( + String.format("%s Random Integer Columns: %s", tableName, this.random_int_cols)); + } + } } - /********************************************************************************************** - * SubUserTableGenerator - * This is for tables that are based off of the USER table - **********************************************************************************************/ - protected abstract class SubTableGenerator extends AbstractTableGenerator { + /** Initiate data that need dependencies */ + public abstract void init(); - private final LinkedBlockingDeque queue = new LinkedBlockingDeque<>(); - private T current; - private int currentCounter; - private boolean stop = false; - private final String sourceTableName; + /** Prepare to generate tuples */ + public abstract void prepare(); - public SubTableGenerator(String tableName, String sourceTableName, String... dependencies) throws SQLException { - super(tableName, dependencies); - this.sourceTableName = sourceTableName; - } - - protected abstract int getElementCounter(T t); - - protected abstract int populateRow(T t, Object[] row, int remaining); - - public void stopWhenEmpty() { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: Will stop when queue is empty", this.getTableName())); - } - this.stop = true; - } - - @Override - public void init() { - // Get the AbstractTableGenerator that will feed into this generator - AbstractTableGenerator parent_gen = AuctionMarkLoader.this.generators.get(this.sourceTableName); - - parent_gen.addSubTableGenerator(this); + /** + * All sub-classes must implement this. This will enter new tuple data into the row + * + * @param row TODO + */ + protected abstract int populateRow(Object[] row); - this.current = null; - this.currentCounter = 0; - } + @Override + public void load(Connection conn) { + // Then invoke the loader generation method + try { + AuctionMarkLoader.this.generateTableData(conn, this.tableName); + } catch (Throwable ex) { + throw new RuntimeException( + "Unexpected error while generating table data for '" + this.tableName + "'", ex); + } + } - @Override - public void prepare() { - // Nothing to do... - } + @Override + public void beforeLoad() { + // First block on the CountDownLatches of all the tables that we depend on + if (this.dependencyTables.size() > 0 && LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s: Table generator is blocked waiting for %d other tables: %s", + this.tableName, this.dependencyTables.size(), this.dependencyTables)); + } + for (String dependency : this.dependencyTables) { + AbstractTableGenerator gen = AuctionMarkLoader.this.generators.get(dependency); - @Override - public final boolean hasMore() { - return (this.getNext() != null); - } + try { + gen.latch.await(); + } catch (InterruptedException ex) { + throw new RuntimeException( + "Unexpected interruption for '" + + this.tableName + + "' waiting for '" + + dependency + + "'", + ex); + } + } + + // Make sure we call prepare before we start generating table data + this.prepare(); + } - @Override - protected final int populateRow(Object[] row) { - T t = this.getNext(); + @SuppressWarnings("unchecked") + public T addSubTableGenerator( + SubTableGenerator sub_item) { + this.sub_generators.add(sub_item); + return ((T) this); + } - this.currentCounter--; - return (this.populateRow(t, row, this.currentCounter)); - } + @SuppressWarnings("unchecked") + public void releaseHoldsToSubTableGenerators() { + if (!this.subGenerator_hold.isEmpty()) { + LOG.trace( + String.format( + "%s: Releasing %d held objects to %d sub-generators", + this.tableName, this.subGenerator_hold.size(), this.sub_generators.size())); + for (@SuppressWarnings("rawtypes") SubTableGenerator sub_generator : this.sub_generators) { + sub_generator.queue.addAll(this.subGenerator_hold); + } + this.subGenerator_hold.clear(); + } + } - private T getNext() { - T last = this.current; - if (this.current == null || this.currentCounter == 0) { - while (this.currentCounter == 0) { - try { - this.current = this.queue.poll(1000, TimeUnit.MILLISECONDS); - } catch (InterruptedException ex) { - return (null); - } - // Check whether we should stop - if (this.current == null) { - if (this.stop) { - break; - } - continue; - } - this.currentCounter = this.getElementCounter(this.current); - } - } - if (last != this.current) { - if (last != null) { - this.finishElementCallback(last); - } - if (this.current != null) { - this.newElementCallback(this.current); - } - } - return this.current; - } + public void updateSubTableGenerators(Object obj) { + // Queue up this item for our multi-threaded sub-generators + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "%s: Updating %d sub-generators with %s: %s", + this.tableName, this.sub_generators.size(), obj, this.sub_generators)); + } + this.subGenerator_hold.add(obj); + } - protected void finishElementCallback(T t) { - // Nothing... - } + public Collection> getSubTableGenerators() { + return (this.sub_generators); + } - protected void newElementCallback(T t) { - // Nothing... - } + public Collection getSubGeneratorTableNames() { + List names = new ArrayList<>(); + for (AbstractTableGenerator gen : this.sub_generators) { + names.add(gen.catalog_tbl.getName().toLowerCase()); + } + return (names); } - /********************************************************************************************** - * REGION Generator - **********************************************************************************************/ - protected class RegionGenerator extends AbstractTableGenerator { + protected int populateRandomColumns(Object[] row) { + int cols = 0; + + // STRINGS + for (Column catalog_col : this.random_str_cols) { + int size = catalog_col.getSize(); + // This (0) can generate an empty string which is treated as NULL in Oracle DB + int start = getDatabaseType() == DatabaseType.ORACLE ? 1 : 0; + row[catalog_col.getIndex()] = + profile.rng.astring(profile.rng.nextInt(start, size - 1), size); + cols++; + } + + // INTEGER + for (Column catalog_col : this.random_int_cols) { + row[catalog_col.getIndex()] = profile.rng.number(0, 1 << 30); + cols++; + } + + return (cols); + } - public RegionGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_REGION); - } + public synchronized boolean hasMore() { + return (this.count < this.tableSize); + } - @Override - public void init() { - // Nothing to do - } + public Table getTableCatalog() { + return (this.catalog_tbl); + } - @Override - public void prepare() { - // Nothing to do - } + public List getVoltTable() { + return this.table; + } - @Override - protected int populateRow(Object[] row) { - int col = 0; + public Long getTableSize() { + return this.tableSize; + } - // R_ID - row[col++] = (int) this.count; - // R_NAME - row[col++] = profile.rng.astring(6, 32); + public int getBatchSize() { + return this.batchSize; + } - return (col); - } + public String getTableName() { + return this.tableName; } - /********************************************************************************************** - * CATEGORY Generator - **********************************************************************************************/ - protected class CategoryGenerator extends AbstractTableGenerator { - private final Map categoryMap; - private final LinkedList categories = new LinkedList<>(); + public synchronized long getCount() { + return this.count; + } - public CategoryGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_CATEGORY); + /** + * When called, the generator will populate a new row record and append it to the underlying + * VoltTable + */ + public synchronized void addRow() { + Object[] row = new Object[this.catalog_tbl.getColumnCount()]; - this.categoryMap = (new CategoryParser()).getCategoryMap(); - this.tableSize = (long) this.categoryMap.size(); - } + // Main Columns + int cols = this.populateRow(row); - @Override - public void init() { - for (Category category : this.categoryMap.values()) { - if (category.isLeaf()) { - profile.items_per_category.put(category.getCategoryID(), category.getItemCount()); - } - this.categories.add(category); - } - } + // RANDOM COLS + cols += this.populateRandomColumns(row); - @Override - public void prepare() { - // Nothing to do + // Convert all CompositeIds into their long encodings + for (int i = 0; i < cols; i++) { + if (row[i] != null && row[i] instanceof CompositeId) { + row[i] = ((CompositeId) row[i]).encode(); } + } - @Override - protected int populateRow(Object[] row) { - int col = 0; + this.count++; + this.table.add(row); + } - Category category = this.categories.poll(); + /** */ + public void generateBatch() { + if (LOG.isTraceEnabled()) { + LOG.trace(String.format("%s: Generating new batch", this.getTableName())); + } + long batch_count = 0; + this.table.clear(); + while (this.hasMore() && this.table.size() < this.batchSize) { + this.addRow(); + batch_count++; + } + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "%s: Finished generating new batch of %d tuples", + this.getTableName(), batch_count)); + } + } + public void markAsFinished() { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: Marking as finished", this.tableName)); + } + this.latch.countDown(); + for (SubTableGenerator sub_generator : this.sub_generators) { + sub_generator.stopWhenEmpty(); + } + } - // C_ID - row[col++] = category.getCategoryID(); - // C_NAME - row[col++] = category.getName().toLowerCase(); - // C_PARENT_ID - row[col++] = category.getParentCategoryID(); + public boolean isFinish() { + return (this.latch.getCount() == 0); + } - return (col); - } + public List getDependencies() { + return this.dependencyTables; } - /********************************************************************************************** - * GLOBAL_ATTRIBUTE_GROUP Generator - **********************************************************************************************/ - protected class GlobalAttributeGroupGenerator extends AbstractTableGenerator { - private final Histogram category_groups = new Histogram<>(); - private final LinkedList group_ids = new LinkedList<>(); + @Override + public String toString() { + return String.format("Generator[%s]", this.tableName); + } + } + + /********************************************************************************************** + * SubUserTableGenerator + * This is for tables that are based off of the USER table + **********************************************************************************************/ + protected abstract class SubTableGenerator extends AbstractTableGenerator { + + private final LinkedBlockingDeque queue = new LinkedBlockingDeque<>(); + private T current; + private int currentCounter; + private boolean stop = false; + private final String sourceTableName; + + public SubTableGenerator(String tableName, String sourceTableName, String... dependencies) + throws SQLException { + super(tableName, dependencies); + this.sourceTableName = sourceTableName; + } - public GlobalAttributeGroupGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, AuctionMarkConstants.TABLENAME_CATEGORY); - } + protected abstract int getElementCounter(T t); - @Override - public void init() { - // Nothing to do - } + protected abstract int populateRow(T t, Object[] row, int remaining); - @Override - public void prepare() { - // Grab the number of CATEGORY items that we have inserted - long num_categories = getGenerator(AuctionMarkConstants.TABLENAME_CATEGORY).tableSize; - - for (int i = 0; i < this.tableSize; i++) { - int category_id = profile.rng.number(0, ((int) num_categories - 1)); - this.category_groups.put(category_id); - int id = this.category_groups.get(category_id); - int count = (int) profile.rng.number(1, AuctionMarkConstants.TABLESIZE_GLOBAL_ATTRIBUTE_VALUE_PER_GROUP); - GlobalAttributeGroupId gag_id = new GlobalAttributeGroupId(category_id, id, count); + public void stopWhenEmpty() { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: Will stop when queue is empty", this.getTableName())); + } + this.stop = true; + } - profile.gag_ids.add(gag_id); - this.group_ids.add(gag_id); - } - } + @Override + public void init() { + // Get the AbstractTableGenerator that will feed into this generator + AbstractTableGenerator parent_gen = + AuctionMarkLoader.this.generators.get(this.sourceTableName); - @Override - protected int populateRow(Object[] row) { - int col = 0; + parent_gen.addSubTableGenerator(this); - GlobalAttributeGroupId gag_id = this.group_ids.poll(); + this.current = null; + this.currentCounter = 0; + } - // GAG_ID - row[col++] = gag_id.encode(); - // GAG_C_ID - row[col++] = gag_id.getCategoryId(); - // GAG_NAME - row[col++] = profile.rng.astring(6, 32); + @Override + public void prepare() { + // Nothing to do... + } - return (col); - } + @Override + public final boolean hasMore() { + return (this.getNext() != null); } - /********************************************************************************************** - * GLOBAL_ATTRIBUTE_VALUE Generator - **********************************************************************************************/ - protected class GlobalAttributeValueGenerator extends AbstractTableGenerator { + @Override + protected final int populateRow(Object[] row) { + T t = this.getNext(); - private final Histogram gag_counters = new Histogram<>(true); - private Iterator gag_iterator; - private GlobalAttributeGroupId gag_current; - private int gav_counter = -1; + this.currentCounter--; + return (this.populateRow(t, row, this.currentCounter)); + } - public GlobalAttributeValueGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE, AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP); + private T getNext() { + T last = this.current; + if (this.current == null || this.currentCounter == 0) { + while (this.currentCounter == 0) { + try { + this.current = this.queue.poll(1000, TimeUnit.MILLISECONDS); + } catch (InterruptedException ex) { + return (null); + } + // Check whether we should stop + if (this.current == null) { + if (this.stop) { + break; + } + continue; + } + this.currentCounter = this.getElementCounter(this.current); } - - @Override - public void init() { - // Nothing to do + } + if (last != this.current) { + if (last != null) { + this.finishElementCallback(last); } - - @Override - public void prepare() { - this.tableSize = 0L; - for (GlobalAttributeGroupId gag_id : profile.gag_ids) { - this.gag_counters.set(gag_id, 0); - this.tableSize += gag_id.getCount(); - } - this.gag_iterator = profile.gag_ids.iterator(); + if (this.current != null) { + this.newElementCallback(this.current); } + } + return this.current; + } - @Override - protected int populateRow(Object[] row) { - int col = 0; + protected void finishElementCallback(T t) { + // Nothing... + } - if (this.gav_counter == -1 || ++this.gav_counter == this.gag_current.getCount()) { - this.gag_current = this.gag_iterator.next(); + protected void newElementCallback(T t) { + // Nothing... + } + } - this.gav_counter = 0; - } + /********************************************************************************************** + * REGION Generator + **********************************************************************************************/ + protected class RegionGenerator extends AbstractTableGenerator { - GlobalAttributeValueId gav_id = new GlobalAttributeValueId(this.gag_current.encode(), this.gav_counter); + public RegionGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_REGION); + } - // GAV_ID - row[col++] = gav_id.encode(); - // GAV_GAG_ID - row[col++] = this.gag_current.encode(); - // GAV_NAME - row[col++] = profile.rng.astring(6, 32); + @Override + public void init() { + // Nothing to do + } - return (col); - } + @Override + public void prepare() { + // Nothing to do } - /********************************************************************************************** - * USER Generator - **********************************************************************************************/ - protected class UserGenerator extends AbstractTableGenerator { - private final Zipf randomBalance; - private final Flat randomRegion; - private final Zipf randomRating; - private UserIdGenerator idGenerator; - - public UserGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_USERACCT, AuctionMarkConstants.TABLENAME_REGION); - this.randomRegion = new Flat(profile.rng, 0, (int) AuctionMarkConstants.TABLESIZE_REGION); - this.randomRating = new Zipf(profile.rng, AuctionMarkConstants.USER_MIN_RATING, AuctionMarkConstants.USER_MAX_RATING, 1.0001); - this.randomBalance = new Zipf(profile.rng, AuctionMarkConstants.USER_MIN_BALANCE, AuctionMarkConstants.USER_MAX_BALANCE, 1.001); - } + @Override + protected int populateRow(Object[] row) { + int col = 0; - @Override - public void init() { - // Populate the profile's users per item count histogram so that we know how many - // items that each user should have. This will then be used to calculate the - // the user ids by placing them into numeric ranges - int max_items = Math.max(1, (int) Math.ceil(AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MAX * profile.getScaleFactor())); - - LOG.debug("Max Items Per Seller: {}", max_items); - Zipf randomNumItems = new Zipf(profile.rng, AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MIN, max_items, AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_SIGMA); - for (long i = 0; i < this.tableSize; i++) { - long num_items = randomNumItems.nextInt(); - profile.users_per_itemCount.put(num_items); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Users Per Item Count:\n{}", profile.users_per_itemCount); - } - this.idGenerator = new UserIdGenerator(profile.users_per_itemCount, benchmark.getWorkloadConfiguration().getTerminals()); + // R_ID + row[col++] = (int) this.count; + // R_NAME + row[col++] = profile.rng.astring(6, 32); - } + return (col); + } + } - @Override - public void prepare() { - // Nothing to do - } + /********************************************************************************************** + * CATEGORY Generator + **********************************************************************************************/ + protected class CategoryGenerator extends AbstractTableGenerator { + private final Map categoryMap; + private final LinkedList categories = new LinkedList<>(); - @Override - public synchronized boolean hasMore() { - return this.idGenerator.hasNext(); - } + public CategoryGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_CATEGORY); + + this.categoryMap = (new CategoryParser()).getCategoryMap(); + this.tableSize = (long) this.categoryMap.size(); + } - @Override - protected int populateRow(Object[] row) { - int col = 0; - - UserId u_id = this.idGenerator.next(); - - // U_ID - row[col++] = u_id; - // U_RATING - row[col++] = this.randomRating.nextInt(); - // U_BALANCE - row[col++] = (this.randomBalance.nextInt()) / 10.0; - // U_COMMENTS - row[col++] = 0; - // U_R_ID - row[col++] = this.randomRegion.nextInt(); - // U_CREATED - row[col++] = new Timestamp(System.currentTimeMillis()); - // U_UPDATED - row[col++] = new Timestamp(System.currentTimeMillis()); - - this.updateSubTableGenerators(u_id); - return (col); + @Override + public void init() { + for (Category category : this.categoryMap.values()) { + if (category.isLeaf()) { + profile.items_per_category.put(category.getCategoryID(), category.getItemCount()); } + this.categories.add(category); + } } - /********************************************************************************************** - * USER_ATTRIBUTES Generator - **********************************************************************************************/ - protected class UserAttributesGenerator extends SubTableGenerator { - private final Zipf randomNumUserAttributes; + @Override + public void prepare() { + // Nothing to do + } - public UserAttributesGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES, AuctionMarkConstants.TABLENAME_USERACCT); + @Override + protected int populateRow(Object[] row) { + int col = 0; - this.randomNumUserAttributes = new Zipf(profile.rng, AuctionMarkConstants.USER_MIN_ATTRIBUTES, AuctionMarkConstants.USER_MAX_ATTRIBUTES, 1.001); - } + Category category = this.categories.poll(); - @Override - protected int getElementCounter(UserId user_id) { - return randomNumUserAttributes.nextInt(); - } + // C_ID + row[col++] = category.getCategoryID(); + // C_NAME + row[col++] = category.getName().toLowerCase(); + // C_PARENT_ID + row[col++] = category.getParentCategoryID(); - @Override - protected int populateRow(UserId user_id, Object[] row, int remaining) { - int col = 0; - - // UA_ID - row[col++] = this.count; - // UA_U_ID - row[col++] = user_id; - // UA_NAME - row[col++] = profile.rng.astring(AuctionMarkConstants.USER_ATTRIBUTE_NAME_LENGTH_MIN, AuctionMarkConstants.USER_ATTRIBUTE_NAME_LENGTH_MAX); - // UA_VALUE - row[col++] = profile.rng.astring(AuctionMarkConstants.USER_ATTRIBUTE_VALUE_LENGTH_MIN, AuctionMarkConstants.USER_ATTRIBUTE_VALUE_LENGTH_MAX); - // U_CREATED - row[col++] = new Timestamp(System.currentTimeMillis()); - - return (col); - } + return (col); + } + } + + /********************************************************************************************** + * GLOBAL_ATTRIBUTE_GROUP Generator + **********************************************************************************************/ + protected class GlobalAttributeGroupGenerator extends AbstractTableGenerator { + private final Histogram category_groups = new Histogram<>(); + private final LinkedList group_ids = new LinkedList<>(); + + public GlobalAttributeGroupGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, + AuctionMarkConstants.TABLENAME_CATEGORY); } - /********************************************************************************************** - * ITEM Generator - **********************************************************************************************/ - protected class ItemGenerator extends SubTableGenerator { - - /** - * BidDurationDay -> Pair - */ - private final Map> item_bid_watch_zipfs = new HashMap<>(); + @Override + public void init() { + // Nothing to do + } - public ItemGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM, AuctionMarkConstants.TABLENAME_USERACCT, AuctionMarkConstants.TABLENAME_USERACCT, AuctionMarkConstants.TABLENAME_CATEGORY); - } + @Override + public void prepare() { + // Grab the number of CATEGORY items that we have inserted + long num_categories = getGenerator(AuctionMarkConstants.TABLENAME_CATEGORY).tableSize; + + for (int i = 0; i < this.tableSize; i++) { + int category_id = profile.rng.number(0, ((int) num_categories - 1)); + this.category_groups.put(category_id); + int id = this.category_groups.get(category_id); + int count = + (int) + profile.rng.number( + 1, AuctionMarkConstants.TABLESIZE_GLOBAL_ATTRIBUTE_VALUE_PER_GROUP); + GlobalAttributeGroupId gag_id = new GlobalAttributeGroupId(category_id, id, count); + + profile.gag_ids.add(gag_id); + this.group_ids.add(gag_id); + } + } - @Override - protected int getElementCounter(UserId user_id) { - return user_id.getItemCount(); - } + @Override + protected int populateRow(Object[] row) { + int col = 0; - @Override - public void init() { - super.init(); - this.tableSize = 0L; - for (Long size : profile.users_per_itemCount.values()) { - this.tableSize += size * profile.users_per_itemCount.get(size); - } - } + GlobalAttributeGroupId gag_id = this.group_ids.poll(); - @Override - protected int populateRow(UserId seller_id, Object[] row, int remaining) { - int col = 0; + // GAG_ID + row[col++] = gag_id.encode(); + // GAG_C_ID + row[col++] = gag_id.getCategoryId(); + // GAG_NAME + row[col++] = profile.rng.astring(6, 32); - ItemId itemId = new ItemId(seller_id, remaining); - Timestamp endDate = this.getRandomEndTimestamp(); - Timestamp startDate = this.getRandomStartTimestamp(endDate); - if (LOG.isTraceEnabled()) { - LOG.trace("endDate = {} : startDate = {}", endDate, startDate); - } - - long bidDurationDay = ((endDate.getTime() - startDate.getTime()) / AuctionMarkConstants.MILLISECONDS_IN_A_DAY); - Pair p = this.item_bid_watch_zipfs.get(bidDurationDay); - if (p == null) { - Zipf randomNumBids = new Zipf(profile.rng, AuctionMarkConstants.ITEM_BIDS_PER_DAY_MIN * bidDurationDay, AuctionMarkConstants.ITEM_BIDS_PER_DAY_MAX * bidDurationDay, AuctionMarkConstants.ITEM_BIDS_PER_DAY_SIGMA); - Zipf randomNumWatches = new Zipf(profile.rng, AuctionMarkConstants.ITEM_WATCHES_PER_DAY_MIN * bidDurationDay, AuctionMarkConstants.ITEM_WATCHES_PER_DAY_MAX * bidDurationDay, AuctionMarkConstants.ITEM_WATCHES_PER_DAY_SIGMA); - p = Pair.of(randomNumBids, randomNumWatches); - this.item_bid_watch_zipfs.put(bidDurationDay, p); - } + return (col); + } + } + + /********************************************************************************************** + * GLOBAL_ATTRIBUTE_VALUE Generator + **********************************************************************************************/ + protected class GlobalAttributeValueGenerator extends AbstractTableGenerator { + + private final Histogram gag_counters = new Histogram<>(true); + private Iterator gag_iterator; + private GlobalAttributeGroupId gag_current; + private int gav_counter = -1; + + public GlobalAttributeValueGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE, + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP); + } + @Override + public void init() { + // Nothing to do + } - // Calculate the number of bids and watches for this item - int numBids = p.first.nextInt(); - int numWatches = p.second.nextInt(); + @Override + public void prepare() { + this.tableSize = 0L; + for (GlobalAttributeGroupId gag_id : profile.gag_ids) { + this.gag_counters.set(gag_id, 0); + this.tableSize += gag_id.getCount(); + } + this.gag_iterator = profile.gag_ids.iterator(); + } - // Create the ItemInfo object that we will use to cache the local data + @Override + protected int populateRow(Object[] row) { + int col = 0; - // tables are done with it. - LoaderItemInfo itemInfo = new LoaderItemInfo(itemId, endDate, numBids); - itemInfo.setStartDate(startDate); - itemInfo.setInitialPrice(profile.randomInitialPrice.nextInt()); + if (this.gav_counter == -1 || ++this.gav_counter == this.gag_current.getCount()) { + this.gag_current = this.gag_iterator.next(); - itemInfo.setNumImages((short) profile.randomNumImages.nextInt()); - itemInfo.setNumAttributes((short) profile.randomNumAttributes.nextInt()); - itemInfo.setNumBids(numBids); - itemInfo.setNumWatches(numWatches); + this.gav_counter = 0; + } - // The auction for this item has already closed - if (itemInfo.getEndDate().getTime() <= profile.getLoaderStartTime().getTime()) { - // Somebody won a bid and bought the item - if (itemInfo.getNumBids() > 0) { - itemInfo.setLastBidderId(profile.getRandomBuyerId(itemInfo.getSellerId())); - itemInfo.setPurchaseDate(this.getRandomPurchaseTimestamp(itemInfo.getEndDate())); - itemInfo.setNumComments((short) profile.randomNumComments.nextInt()); - } - itemInfo.setStatus(ItemStatus.CLOSED); - } - // Item is still available - else if (itemInfo.getNumBids() > 0) { - itemInfo.setLastBidderId(profile.getRandomBuyerId(itemInfo.getSellerId())); - } - profile.addItemToProperQueue(itemInfo, true); - - // I_ID - row[col++] = itemInfo.getItemId(); - // I_U_ID - row[col++] = itemInfo.getSellerId(); - // I_C_ID - row[col++] = profile.getRandomCategoryId(); - // I_NAME - row[col++] = profile.rng.astring(AuctionMarkConstants.ITEM_NAME_LENGTH_MIN, AuctionMarkConstants.ITEM_NAME_LENGTH_MAX); - // I_DESCRIPTION - row[col++] = profile.rng.astring(AuctionMarkConstants.ITEM_DESCRIPTION_LENGTH_MIN, AuctionMarkConstants.ITEM_DESCRIPTION_LENGTH_MAX); - // I_USER_ATTRIBUTES - row[col++] = profile.rng.astring(AuctionMarkConstants.ITEM_USER_ATTRIBUTES_LENGTH_MIN, AuctionMarkConstants.ITEM_USER_ATTRIBUTES_LENGTH_MAX); - // I_INITIAL_PRICE - row[col++] = itemInfo.getInitialPrice(); - - // I_CURRENT_PRICE - if (itemInfo.getNumBids() > 0) { - itemInfo.setCurrentPrice(itemInfo.getInitialPrice() + (itemInfo.getNumBids() * itemInfo.getInitialPrice() * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); - row[col++] = itemInfo.getCurrentPrice(); - } else { - row[col++] = itemInfo.getInitialPrice(); - } + GlobalAttributeValueId gav_id = + new GlobalAttributeValueId(this.gag_current.encode(), this.gav_counter); - // I_NUM_BIDS - row[col++] = itemInfo.getNumBids(); - // I_NUM_IMAGES - row[col++] = itemInfo.getNumImages(); - // I_NUM_GLOBAL_ATTRS - row[col++] = itemInfo.getNumAttributes(); - // I_NUM_COMMENTS - row[col++] = itemInfo.getNumComments(); - // I_START_DATE - row[col++] = itemInfo.getStartDate(); - // I_END_DATE - row[col++] = itemInfo.getEndDate(); - // I_STATUS - row[col++] = itemInfo.getStatus().ordinal(); - // I_CREATED - row[col++] = profile.getLoaderStartTime(); - // I_UPDATED - row[col++] = itemInfo.getStartDate(); - - this.updateSubTableGenerators(itemInfo); - return (col); - } + // GAV_ID + row[col++] = gav_id.encode(); + // GAV_GAG_ID + row[col++] = this.gag_current.encode(); + // GAV_NAME + row[col++] = profile.rng.astring(6, 32); - private Timestamp getRandomStartTimestamp(Timestamp endDate) { - long duration = ((long) profile.randomDuration.nextInt()) * AuctionMarkConstants.MILLISECONDS_IN_A_DAY; - long lStartTimestamp = endDate.getTime() - duration; - return new Timestamp(lStartTimestamp); - } + return (col); + } + } + + /********************************************************************************************** + * USER Generator + **********************************************************************************************/ + protected class UserGenerator extends AbstractTableGenerator { + private final Zipf randomBalance; + private final Flat randomRegion; + private final Zipf randomRating; + private UserIdGenerator idGenerator; + + public UserGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_USERACCT, AuctionMarkConstants.TABLENAME_REGION); + this.randomRegion = new Flat(profile.rng, 0, (int) AuctionMarkConstants.TABLESIZE_REGION); + this.randomRating = + new Zipf( + profile.rng, + AuctionMarkConstants.USER_MIN_RATING, + AuctionMarkConstants.USER_MAX_RATING, + 1.0001); + this.randomBalance = + new Zipf( + profile.rng, + AuctionMarkConstants.USER_MIN_BALANCE, + AuctionMarkConstants.USER_MAX_BALANCE, + 1.001); + } - private Timestamp getRandomEndTimestamp() { - int timeDiff = profile.randomTimeDiff.nextInt(); - return new Timestamp(profile.getLoaderStartTime().getTime() + (timeDiff * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND)); - } + @Override + public void init() { + // Populate the profile's users per item count histogram so that we know how many + // items that each user should have. This will then be used to calculate the + // the user ids by placing them into numeric ranges + int max_items = + Math.max( + 1, + (int) + Math.ceil( + AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MAX * profile.getScaleFactor())); + + LOG.debug("Max Items Per Seller: {}", max_items); + Zipf randomNumItems = + new Zipf( + profile.rng, + AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MIN, + max_items, + AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_SIGMA); + for (long i = 0; i < this.tableSize; i++) { + long num_items = randomNumItems.nextInt(); + profile.users_per_itemCount.put(num_items); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Users Per Item Count:\n{}", profile.users_per_itemCount); + } + this.idGenerator = + new UserIdGenerator( + profile.users_per_itemCount, benchmark.getWorkloadConfiguration().getTerminals()); + } - private Timestamp getRandomPurchaseTimestamp(Timestamp endDate) { - long duration = profile.randomPurchaseDuration.nextInt(); - return new Timestamp(endDate.getTime() + duration * AuctionMarkConstants.MILLISECONDS_IN_A_DAY); - } + @Override + public void prepare() { + // Nothing to do } - /********************************************************************************************** - * ITEM_IMAGE Generator - **********************************************************************************************/ - protected class ItemImageGenerator extends SubTableGenerator { + @Override + public synchronized boolean hasMore() { + return this.idGenerator.hasNext(); + } - public ItemImageGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_IMAGE, AuctionMarkConstants.TABLENAME_ITEM); - } + @Override + protected int populateRow(Object[] row) { + int col = 0; + + UserId u_id = this.idGenerator.next(); + + // U_ID + row[col++] = u_id; + // U_RATING + row[col++] = this.randomRating.nextInt(); + // U_BALANCE + row[col++] = (this.randomBalance.nextInt()) / 10.0; + // U_COMMENTS + row[col++] = 0; + // U_R_ID + row[col++] = this.randomRegion.nextInt(); + // U_CREATED + row[col++] = new Timestamp(System.currentTimeMillis()); + // U_UPDATED + row[col++] = new Timestamp(System.currentTimeMillis()); + + this.updateSubTableGenerators(u_id); + return (col); + } + } + + /********************************************************************************************** + * USER_ATTRIBUTES Generator + **********************************************************************************************/ + protected class UserAttributesGenerator extends SubTableGenerator { + private final Zipf randomNumUserAttributes; + + public UserAttributesGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_USERACCT_ATTRIBUTES, + AuctionMarkConstants.TABLENAME_USERACCT); + + this.randomNumUserAttributes = + new Zipf( + profile.rng, + AuctionMarkConstants.USER_MIN_ATTRIBUTES, + AuctionMarkConstants.USER_MAX_ATTRIBUTES, + 1.001); + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getNumImages(); - } + @Override + protected int getElementCounter(UserId user_id) { + return randomNumUserAttributes.nextInt(); + } - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; + @Override + protected int populateRow(UserId user_id, Object[] row, int remaining) { + int col = 0; + + // UA_ID + row[col++] = this.count; + // UA_U_ID + row[col++] = user_id; + // UA_NAME + row[col++] = + profile.rng.astring( + AuctionMarkConstants.USER_ATTRIBUTE_NAME_LENGTH_MIN, + AuctionMarkConstants.USER_ATTRIBUTE_NAME_LENGTH_MAX); + // UA_VALUE + row[col++] = + profile.rng.astring( + AuctionMarkConstants.USER_ATTRIBUTE_VALUE_LENGTH_MIN, + AuctionMarkConstants.USER_ATTRIBUTE_VALUE_LENGTH_MAX); + // U_CREATED + row[col++] = new Timestamp(System.currentTimeMillis()); + + return (col); + } + } + + /********************************************************************************************** + * ITEM Generator + **********************************************************************************************/ + protected class ItemGenerator extends SubTableGenerator { + + /** BidDurationDay -> Pair */ + private final Map> item_bid_watch_zipfs = new HashMap<>(); + + public ItemGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_ITEM, + AuctionMarkConstants.TABLENAME_USERACCT, + AuctionMarkConstants.TABLENAME_USERACCT, + AuctionMarkConstants.TABLENAME_CATEGORY); + } - // II_ID - row[col++] = this.count; - // II_I_ID - row[col++] = itemInfo.getItemId(); - // II_U_ID - row[col++] = itemInfo.getSellerId(); + @Override + protected int getElementCounter(UserId user_id) { + return user_id.getItemCount(); + } - return (col); - } + @Override + public void init() { + super.init(); + this.tableSize = 0L; + for (Long size : profile.users_per_itemCount.values()) { + this.tableSize += size * profile.users_per_itemCount.get(size); + } } - /********************************************************************************************** - * ITEM_ATTRIBUTE Generator - **********************************************************************************************/ - protected class ItemAttributeGenerator extends SubTableGenerator { + @Override + protected int populateRow(UserId seller_id, Object[] row, int remaining) { + int col = 0; + + ItemId itemId = new ItemId(seller_id, remaining); + Timestamp endDate = this.getRandomEndTimestamp(); + Timestamp startDate = this.getRandomStartTimestamp(endDate); + if (LOG.isTraceEnabled()) { + LOG.trace("endDate = {} : startDate = {}", endDate, startDate); + } + + long bidDurationDay = + ((endDate.getTime() - startDate.getTime()) / AuctionMarkConstants.MILLISECONDS_IN_A_DAY); + Pair p = this.item_bid_watch_zipfs.get(bidDurationDay); + if (p == null) { + Zipf randomNumBids = + new Zipf( + profile.rng, + AuctionMarkConstants.ITEM_BIDS_PER_DAY_MIN * bidDurationDay, + AuctionMarkConstants.ITEM_BIDS_PER_DAY_MAX * bidDurationDay, + AuctionMarkConstants.ITEM_BIDS_PER_DAY_SIGMA); + Zipf randomNumWatches = + new Zipf( + profile.rng, + AuctionMarkConstants.ITEM_WATCHES_PER_DAY_MIN * bidDurationDay, + AuctionMarkConstants.ITEM_WATCHES_PER_DAY_MAX * bidDurationDay, + AuctionMarkConstants.ITEM_WATCHES_PER_DAY_SIGMA); + p = Pair.of(randomNumBids, randomNumWatches); + this.item_bid_watch_zipfs.put(bidDurationDay, p); + } + + // Calculate the number of bids and watches for this item + int numBids = p.first.nextInt(); + int numWatches = p.second.nextInt(); + + // Create the ItemInfo object that we will use to cache the local data + + // tables are done with it. + LoaderItemInfo itemInfo = new LoaderItemInfo(itemId, endDate, numBids); + itemInfo.setStartDate(startDate); + itemInfo.setInitialPrice(profile.randomInitialPrice.nextInt()); + + itemInfo.setNumImages((short) profile.randomNumImages.nextInt()); + itemInfo.setNumAttributes((short) profile.randomNumAttributes.nextInt()); + itemInfo.setNumBids(numBids); + itemInfo.setNumWatches(numWatches); + + // The auction for this item has already closed + if (itemInfo.getEndDate().getTime() <= profile.getLoaderStartTime().getTime()) { + // Somebody won a bid and bought the item + if (itemInfo.getNumBids() > 0) { + itemInfo.setLastBidderId(profile.getRandomBuyerId(itemInfo.getSellerId())); + itemInfo.setPurchaseDate(this.getRandomPurchaseTimestamp(itemInfo.getEndDate())); + itemInfo.setNumComments((short) profile.randomNumComments.nextInt()); + } + itemInfo.setStatus(ItemStatus.CLOSED); + } + // Item is still available + else if (itemInfo.getNumBids() > 0) { + itemInfo.setLastBidderId(profile.getRandomBuyerId(itemInfo.getSellerId())); + } + profile.addItemToProperQueue(itemInfo, true); + + // I_ID + row[col++] = itemInfo.getItemId(); + // I_U_ID + row[col++] = itemInfo.getSellerId(); + // I_C_ID + row[col++] = profile.getRandomCategoryId(); + // I_NAME + row[col++] = + profile.rng.astring( + AuctionMarkConstants.ITEM_NAME_LENGTH_MIN, AuctionMarkConstants.ITEM_NAME_LENGTH_MAX); + // I_DESCRIPTION + row[col++] = + profile.rng.astring( + AuctionMarkConstants.ITEM_DESCRIPTION_LENGTH_MIN, + AuctionMarkConstants.ITEM_DESCRIPTION_LENGTH_MAX); + // I_USER_ATTRIBUTES + row[col++] = + profile.rng.astring( + AuctionMarkConstants.ITEM_USER_ATTRIBUTES_LENGTH_MIN, + AuctionMarkConstants.ITEM_USER_ATTRIBUTES_LENGTH_MAX); + // I_INITIAL_PRICE + row[col++] = itemInfo.getInitialPrice(); + + // I_CURRENT_PRICE + if (itemInfo.getNumBids() > 0) { + itemInfo.setCurrentPrice( + itemInfo.getInitialPrice() + + (itemInfo.getNumBids() + * itemInfo.getInitialPrice() + * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); + row[col++] = itemInfo.getCurrentPrice(); + } else { + row[col++] = itemInfo.getInitialPrice(); + } + + // I_NUM_BIDS + row[col++] = itemInfo.getNumBids(); + // I_NUM_IMAGES + row[col++] = itemInfo.getNumImages(); + // I_NUM_GLOBAL_ATTRS + row[col++] = itemInfo.getNumAttributes(); + // I_NUM_COMMENTS + row[col++] = itemInfo.getNumComments(); + // I_START_DATE + row[col++] = itemInfo.getStartDate(); + // I_END_DATE + row[col++] = itemInfo.getEndDate(); + // I_STATUS + row[col++] = itemInfo.getStatus().ordinal(); + // I_CREATED + row[col++] = profile.getLoaderStartTime(); + // I_UPDATED + row[col++] = itemInfo.getStartDate(); + + this.updateSubTableGenerators(itemInfo); + return (col); + } - public ItemAttributeGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE, AuctionMarkConstants.TABLENAME_ITEM, AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE); - } + private Timestamp getRandomStartTimestamp(Timestamp endDate) { + long duration = + ((long) profile.randomDuration.nextInt()) * AuctionMarkConstants.MILLISECONDS_IN_A_DAY; + long lStartTimestamp = endDate.getTime() - duration; + return new Timestamp(lStartTimestamp); + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getNumAttributes(); - } + private Timestamp getRandomEndTimestamp() { + int timeDiff = profile.randomTimeDiff.nextInt(); + return new Timestamp( + profile.getLoaderStartTime().getTime() + + (timeDiff * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND)); + } - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); + private Timestamp getRandomPurchaseTimestamp(Timestamp endDate) { + long duration = profile.randomPurchaseDuration.nextInt(); + return new Timestamp( + endDate.getTime() + duration * AuctionMarkConstants.MILLISECONDS_IN_A_DAY); + } + } + /********************************************************************************************** + * ITEM_IMAGE Generator + **********************************************************************************************/ + protected class ItemImageGenerator extends SubTableGenerator { - // IA_ID - row[col++] = this.count; - // IA_I_ID - row[col++] = itemInfo.getItemId(); - // IA_U_ID - row[col++] = itemInfo.getSellerId(); - // IA_GAV_ID - row[col++] = gav_id.encode(); - // IA_GAG_ID - row[col++] = gav_id.getGlobalAttributeGroup().encode(); + public ItemImageGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_ITEM_IMAGE, AuctionMarkConstants.TABLENAME_ITEM); + } - return (col); - } + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getNumImages(); } - /********************************************************************************************** - * ITEM_COMMENT Generator - **********************************************************************************************/ - protected class ItemCommentGenerator extends SubTableGenerator { + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; - public ItemCommentGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_COMMENT, AuctionMarkConstants.TABLENAME_ITEM); - } + // II_ID + row[col++] = this.count; + // II_I_ID + row[col++] = itemInfo.getItemId(); + // II_U_ID + row[col++] = itemInfo.getSellerId(); - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getPurchaseDate() != null ? itemInfo.getNumComments() : 0; - } + return (col); + } + } + + /********************************************************************************************** + * ITEM_ATTRIBUTE Generator + **********************************************************************************************/ + protected class ItemAttributeGenerator extends SubTableGenerator { + + public ItemAttributeGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE, + AuctionMarkConstants.TABLENAME_ITEM, + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP, + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE); + } - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - - // IC_ID - row[col++] = (int) this.count; - // IC_I_ID - row[col++] = itemInfo.getItemId(); - // IC_U_ID - row[col++] = itemInfo.getSellerId(); - // IC_BUYER_ID - row[col++] = itemInfo.getLastBidderId(); - // IC_QUESTION - row[col++] = profile.rng.astring(AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); - // IC_RESPONSE - row[col++] = profile.rng.astring(AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); - // IC_CREATED - row[col++] = this.getRandomCommentDate(itemInfo.getStartDate(), itemInfo.getEndDate()); - // IC_UPDATED - row[col++] = this.getRandomCommentDate(itemInfo.getStartDate(), itemInfo.getEndDate()); - - return (col); - } + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getNumAttributes(); + } - private Timestamp getRandomCommentDate(Timestamp startDate, Timestamp endDate) { - int start = Math.round(startDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - int end = Math.round(endDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - return new Timestamp((profile.rng.number(start, end)) * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - } + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); + + // IA_ID + row[col++] = this.count; + // IA_I_ID + row[col++] = itemInfo.getItemId(); + // IA_U_ID + row[col++] = itemInfo.getSellerId(); + // IA_GAV_ID + row[col++] = gav_id.encode(); + // IA_GAG_ID + row[col++] = gav_id.getGlobalAttributeGroup().encode(); + + return (col); } + } - /********************************************************************************************** - * ITEM_BID Generator - **********************************************************************************************/ - protected class ItemBidGenerator extends SubTableGenerator { + /********************************************************************************************** + * ITEM_COMMENT Generator + **********************************************************************************************/ + protected class ItemCommentGenerator extends SubTableGenerator { - private LoaderItemInfo.Bid bid = null; - private float currentBidPriceAdvanceStep; - private long currentCreateDateAdvanceStep; - @SuppressWarnings("unused") // only ever assigned - private float currentPrice; - private boolean new_item; + public ItemCommentGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_ITEM_COMMENT, AuctionMarkConstants.TABLENAME_ITEM); + } - public ItemBidGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_BID, AuctionMarkConstants.TABLENAME_ITEM); - } + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getPurchaseDate() != null ? itemInfo.getNumComments() : 0; + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return ((int) itemInfo.getNumBids()); - } + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + + // IC_ID + row[col++] = (int) this.count; + // IC_I_ID + row[col++] = itemInfo.getItemId(); + // IC_U_ID + row[col++] = itemInfo.getSellerId(); + // IC_BUYER_ID + row[col++] = itemInfo.getLastBidderId(); + // IC_QUESTION + row[col++] = + profile.rng.astring( + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + // IC_RESPONSE + row[col++] = + profile.rng.astring( + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + // IC_CREATED + row[col++] = this.getRandomCommentDate(itemInfo.getStartDate(), itemInfo.getEndDate()); + // IC_UPDATED + row[col++] = this.getRandomCommentDate(itemInfo.getStartDate(), itemInfo.getEndDate()); + + return (col); + } - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - - - UserId bidderId = null; - - // Figure out the UserId for the person bidding on this item now - if (this.new_item) { - // If this is a new item and there is more than one bid, then - // we'll choose the bidder's UserId at random. - // If there is only one bid, then it will have to be the last bidder - bidderId = (itemInfo.getNumBids() == 1 ? itemInfo.getLastBidderId() : profile.getRandomBuyerId(itemInfo.getSellerId())); - Timestamp endDate; - if (itemInfo.getStatus().equals(ItemStatus.OPEN)) { - endDate = profile.getLoaderStartTime(); - } else { - endDate = itemInfo.getEndDate(); - } - this.currentCreateDateAdvanceStep = (endDate.getTime() - itemInfo.getStartDate().getTime()) / (remaining + 1); - this.currentBidPriceAdvanceStep = itemInfo.getInitialPrice() * AuctionMarkConstants.ITEM_BID_PERCENT_STEP; - this.currentPrice = itemInfo.getInitialPrice(); - } - // The last bid must always be the item's lastBidderId - else if (remaining == 0) { - bidderId = itemInfo.getLastBidderId(); - this.currentPrice = itemInfo.getCurrentPrice(); - } - // The first bid for a two-bid item must always be different than the lastBidderId - else if (itemInfo.getNumBids() == 2) { + private Timestamp getRandomCommentDate(Timestamp startDate, Timestamp endDate) { + int start = Math.round(startDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + int end = Math.round(endDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + return new Timestamp( + (profile.rng.number(start, end)) * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + } + } - bidderId = profile.getRandomBuyerId(itemInfo.getLastBidderId(), itemInfo.getSellerId()); - } - // Since there are multiple bids, we want randomly select one based on the previous bidders - // We will get the histogram of bidders so that we are more likely to select - // an existing bidder rather than a completely random one - else { - - Histogram bidderHistogram = itemInfo.getBidderHistogram(); - bidderId = profile.getRandomBuyerId(bidderHistogram, this.bid.getBidderId(), itemInfo.getSellerId()); - this.currentPrice += this.currentBidPriceAdvanceStep; - } + /********************************************************************************************** + * ITEM_BID Generator + **********************************************************************************************/ + protected class ItemBidGenerator extends SubTableGenerator { + private LoaderItemInfo.Bid bid = null; + private float currentBidPriceAdvanceStep; + private long currentCreateDateAdvanceStep; - float last_bid = (this.new_item ? itemInfo.getInitialPrice() : this.bid.getMaxBid()); - this.bid = itemInfo.getNextBid(this.count, bidderId); - this.bid.setCreateDate(new Timestamp(itemInfo.getStartDate().getTime() + this.currentCreateDateAdvanceStep)); - this.bid.setUpdateDate(this.bid.getCreateDate()); + @SuppressWarnings("unused") // only ever assigned + private float currentPrice; - if (remaining == 0) { - this.bid.setMaxBid(itemInfo.getCurrentPrice()); - } else { - this.bid.setMaxBid(last_bid + this.currentBidPriceAdvanceStep); - } + private boolean new_item; - // IB_ID - row[col++] = this.bid.getId(); - // IB_I_ID - row[col++] = itemInfo.getItemId(); - // IB_U_ID - row[col++] = itemInfo.getSellerId(); - // IB_BUYER_ID - row[col++] = this.bid.getBidderId(); - // IB_BID - row[col++] = this.bid.getMaxBid() - (remaining > 0 ? (this.currentBidPriceAdvanceStep / 2.0f) : 0); -// row[col++] = this.currentPrice; - // IB_MAX_BID - row[col++] = this.bid.getMaxBid(); - // IB_CREATED - row[col++] = this.bid.getCreateDate(); - // IB_UPDATED - row[col++] = this.bid.getUpdateDate(); - - if (remaining == 0) { - this.updateSubTableGenerators(itemInfo); - } - return (col); - } + public ItemBidGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_ITEM_BID, AuctionMarkConstants.TABLENAME_ITEM); + } - @Override - protected void newElementCallback(LoaderItemInfo itemInfo) { - this.new_item = true; - this.bid = null; - } + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return ((int) itemInfo.getNumBids()); } - /********************************************************************************************** - * ITEM_BID_MAX Generator - **********************************************************************************************/ - protected class ItemMaxBidGenerator extends SubTableGenerator { + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + + UserId bidderId = null; + + // Figure out the UserId for the person bidding on this item now + if (this.new_item) { + // If this is a new item and there is more than one bid, then + // we'll choose the bidder's UserId at random. + // If there is only one bid, then it will have to be the last bidder + bidderId = + (itemInfo.getNumBids() == 1 + ? itemInfo.getLastBidderId() + : profile.getRandomBuyerId(itemInfo.getSellerId())); + Timestamp endDate; + if (itemInfo.getStatus().equals(ItemStatus.OPEN)) { + endDate = profile.getLoaderStartTime(); + } else { + endDate = itemInfo.getEndDate(); + } + this.currentCreateDateAdvanceStep = + (endDate.getTime() - itemInfo.getStartDate().getTime()) / (remaining + 1); + this.currentBidPriceAdvanceStep = + itemInfo.getInitialPrice() * AuctionMarkConstants.ITEM_BID_PERCENT_STEP; + this.currentPrice = itemInfo.getInitialPrice(); + } + // The last bid must always be the item's lastBidderId + else if (remaining == 0) { + bidderId = itemInfo.getLastBidderId(); + this.currentPrice = itemInfo.getCurrentPrice(); + } + // The first bid for a two-bid item must always be different than the lastBidderId + else if (itemInfo.getNumBids() == 2) { + + bidderId = profile.getRandomBuyerId(itemInfo.getLastBidderId(), itemInfo.getSellerId()); + } + // Since there are multiple bids, we want randomly select one based on the previous bidders + // We will get the histogram of bidders so that we are more likely to select + // an existing bidder rather than a completely random one + else { + + Histogram bidderHistogram = itemInfo.getBidderHistogram(); + bidderId = + profile.getRandomBuyerId( + bidderHistogram, this.bid.getBidderId(), itemInfo.getSellerId()); + this.currentPrice += this.currentBidPriceAdvanceStep; + } + + float last_bid = (this.new_item ? itemInfo.getInitialPrice() : this.bid.getMaxBid()); + this.bid = itemInfo.getNextBid(this.count, bidderId); + this.bid.setCreateDate( + new Timestamp(itemInfo.getStartDate().getTime() + this.currentCreateDateAdvanceStep)); + this.bid.setUpdateDate(this.bid.getCreateDate()); + + if (remaining == 0) { + this.bid.setMaxBid(itemInfo.getCurrentPrice()); + } else { + this.bid.setMaxBid(last_bid + this.currentBidPriceAdvanceStep); + } + + // IB_ID + row[col++] = this.bid.getId(); + // IB_I_ID + row[col++] = itemInfo.getItemId(); + // IB_U_ID + row[col++] = itemInfo.getSellerId(); + // IB_BUYER_ID + row[col++] = this.bid.getBidderId(); + // IB_BID + row[col++] = + this.bid.getMaxBid() - (remaining > 0 ? (this.currentBidPriceAdvanceStep / 2.0f) : 0); + // row[col++] = this.currentPrice; + // IB_MAX_BID + row[col++] = this.bid.getMaxBid(); + // IB_CREATED + row[col++] = this.bid.getCreateDate(); + // IB_UPDATED + row[col++] = this.bid.getUpdateDate(); + + if (remaining == 0) { + this.updateSubTableGenerators(itemInfo); + } + return (col); + } - public ItemMaxBidGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_MAX_BID, AuctionMarkConstants.TABLENAME_ITEM_BID); - } + @Override + protected void newElementCallback(LoaderItemInfo itemInfo) { + this.new_item = true; + this.bid = null; + } + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getBidCount() > 0 ? 1 : 0; - } + /********************************************************************************************** + * ITEM_BID_MAX Generator + **********************************************************************************************/ + protected class ItemMaxBidGenerator extends SubTableGenerator { - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - LoaderItemInfo.Bid bid = itemInfo.getLastBid(); - - - // IMB_I_ID - row[col++] = itemInfo.getItemId(); - // IMB_U_ID - row[col++] = itemInfo.getSellerId(); - // IMB_IB_ID - row[col++] = bid.getId(); - // IMB_IB_I_ID - row[col++] = itemInfo.getItemId(); - // IMB_IB_U_ID - row[col++] = itemInfo.getSellerId(); - // IMB_CREATED - row[col++] = bid.getCreateDate(); - // IMB_UPDATED - row[col++] = bid.getUpdateDate(); - - return (col); - } + public ItemMaxBidGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_ITEM_MAX_BID, AuctionMarkConstants.TABLENAME_ITEM_BID); } - /********************************************************************************************** - * ITEM_PURCHASE Generator - **********************************************************************************************/ - protected class ItemPurchaseGenerator extends SubTableGenerator { - - public ItemPurchaseGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE, AuctionMarkConstants.TABLENAME_ITEM_BID); - } + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getBidCount() > 0 ? 1 : 0; + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getBidCount() > 0 && itemInfo.getPurchaseDate() != null ? 1 : 0; - } + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + LoaderItemInfo.Bid bid = itemInfo.getLastBid(); + + // IMB_I_ID + row[col++] = itemInfo.getItemId(); + // IMB_U_ID + row[col++] = itemInfo.getSellerId(); + // IMB_IB_ID + row[col++] = bid.getId(); + // IMB_IB_I_ID + row[col++] = itemInfo.getItemId(); + // IMB_IB_U_ID + row[col++] = itemInfo.getSellerId(); + // IMB_CREATED + row[col++] = bid.getCreateDate(); + // IMB_UPDATED + row[col++] = bid.getUpdateDate(); + + return (col); + } + } - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - LoaderItemInfo.Bid bid = itemInfo.getLastBid(); - - - // IP_ID - row[col++] = this.count; - // IP_IB_ID - row[col++] = bid.getId(); - // IP_IB_I_ID - row[col++] = itemInfo.getItemId(); - // IP_IB_U_ID - row[col++] = itemInfo.getSellerId(); - // IP_DATE - row[col++] = itemInfo.getPurchaseDate(); - - if (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_PURCHASE_BUYER_LEAVES_FEEDBACK) { - bid.setBuyer_feedback(true); - } - if (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_PURCHASE_SELLER_LEAVES_FEEDBACK) { - bid.setSeller_feedback(true); - } + /********************************************************************************************** + * ITEM_PURCHASE Generator + **********************************************************************************************/ + protected class ItemPurchaseGenerator extends SubTableGenerator { - if (remaining == 0) { - this.updateSubTableGenerators(bid); - } - return (col); - } + public ItemPurchaseGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE, AuctionMarkConstants.TABLENAME_ITEM_BID); } - /********************************************************************************************** - * USER_FEEDBACK Generator - **********************************************************************************************/ - protected class UserFeedbackGenerator extends SubTableGenerator { + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getBidCount() > 0 && itemInfo.getPurchaseDate() != null ? 1 : 0; + } - public UserFeedbackGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK, AuctionMarkConstants.TABLENAME_ITEM_PURCHASE); - } + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + LoaderItemInfo.Bid bid = itemInfo.getLastBid(); + + // IP_ID + row[col++] = this.count; + // IP_IB_ID + row[col++] = bid.getId(); + // IP_IB_I_ID + row[col++] = itemInfo.getItemId(); + // IP_IB_U_ID + row[col++] = itemInfo.getSellerId(); + // IP_DATE + row[col++] = itemInfo.getPurchaseDate(); + + if (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_PURCHASE_BUYER_LEAVES_FEEDBACK) { + bid.setBuyer_feedback(true); + } + if (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_PURCHASE_SELLER_LEAVES_FEEDBACK) { + bid.setSeller_feedback(true); + } + + if (remaining == 0) { + this.updateSubTableGenerators(bid); + } + return (col); + } + } - @Override - protected int getElementCounter(LoaderItemInfo.Bid bid) { - return (bid.isBuyer_feedback() ? 1 : 0) + (bid.isSeller_feedback() ? 1 : 0); - } + /********************************************************************************************** + * USER_FEEDBACK Generator + **********************************************************************************************/ + protected class UserFeedbackGenerator extends SubTableGenerator { - @Override - protected int populateRow(LoaderItemInfo.Bid bid, Object[] row, int remaining) { - int col = 0; - - boolean is_buyer = false; - is_buyer = remaining == 1 || (bid.isBuyer_feedback() && !bid.isSeller_feedback()); - LoaderItemInfo itemInfo = bid.getLoaderItemInfo(); - - // UF_U_ID - row[col++] = (is_buyer ? bid.getBidderId() : itemInfo.getSellerId()); - // UF_I_ID - row[col++] = itemInfo.getItemId(); - // UF_I_U_ID - row[col++] = itemInfo.getSellerId(); - // UF_FROM_ID - row[col++] = (is_buyer ? itemInfo.getSellerId() : bid.getBidderId()); - // UF_RATING - row[col++] = 1; // TODO - // UF_DATE - row[col++] = profile.getLoaderStartTime(); // Does this matter? - - return (col); - } + public UserFeedbackGenerator() throws SQLException { + super( + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK, + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE); } - /********************************************************************************************** - * USER_ITEM Generator - **********************************************************************************************/ - protected class UserItemGenerator extends SubTableGenerator { + @Override + protected int getElementCounter(LoaderItemInfo.Bid bid) { + return (bid.isBuyer_feedback() ? 1 : 0) + (bid.isSeller_feedback() ? 1 : 0); + } - public UserItemGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_USERACCT_ITEM, AuctionMarkConstants.TABLENAME_ITEM_BID); - } + @Override + protected int populateRow(LoaderItemInfo.Bid bid, Object[] row, int remaining) { + int col = 0; + + boolean is_buyer = false; + is_buyer = remaining == 1 || (bid.isBuyer_feedback() && !bid.isSeller_feedback()); + LoaderItemInfo itemInfo = bid.getLoaderItemInfo(); + + // UF_U_ID + row[col++] = (is_buyer ? bid.getBidderId() : itemInfo.getSellerId()); + // UF_I_ID + row[col++] = itemInfo.getItemId(); + // UF_I_U_ID + row[col++] = itemInfo.getSellerId(); + // UF_FROM_ID + row[col++] = (is_buyer ? itemInfo.getSellerId() : bid.getBidderId()); + // UF_RATING + row[col++] = 1; // TODO + // UF_DATE + row[col++] = profile.getLoaderStartTime(); // Does this matter? + + return (col); + } + } - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getBidCount() > 0 && itemInfo.getPurchaseDate() != null ? 1 : 0; - } + /********************************************************************************************** + * USER_ITEM Generator + **********************************************************************************************/ + protected class UserItemGenerator extends SubTableGenerator { - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; - LoaderItemInfo.Bid bid = itemInfo.getLastBid(); - - - // UI_U_ID - row[col++] = bid.getBidderId(); - // UI_I_ID - row[col++] = itemInfo.getItemId(); - // UI_I_U_ID - row[col++] = itemInfo.getSellerId(); - // UI_IP_ID - row[col++] = null; - // UI_IP_IB_ID - row[col++] = null; - // UI_IP_IB_I_ID - row[col++] = null; - // UI_IP_IB_U_ID - row[col++] = null; - // UI_CREATED - row[col++] = itemInfo.getEndDate(); - - return (col); - } + public UserItemGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_USERACCT_ITEM, AuctionMarkConstants.TABLENAME_ITEM_BID); } - /********************************************************************************************** - * USER_WATCH Generator - **********************************************************************************************/ - protected class UserWatchGenerator extends SubTableGenerator { + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getBidCount() > 0 && itemInfo.getPurchaseDate() != null ? 1 : 0; + } - final Set watchers = new HashSet<>(); + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + LoaderItemInfo.Bid bid = itemInfo.getLastBid(); + + // UI_U_ID + row[col++] = bid.getBidderId(); + // UI_I_ID + row[col++] = itemInfo.getItemId(); + // UI_I_U_ID + row[col++] = itemInfo.getSellerId(); + // UI_IP_ID + row[col++] = null; + // UI_IP_IB_ID + row[col++] = null; + // UI_IP_IB_I_ID + row[col++] = null; + // UI_IP_IB_U_ID + row[col++] = null; + // UI_CREATED + row[col++] = itemInfo.getEndDate(); + + return (col); + } + } - public UserWatchGenerator() throws SQLException { - super(AuctionMarkConstants.TABLENAME_USERACCT_WATCH, AuctionMarkConstants.TABLENAME_ITEM_BID); - } + /********************************************************************************************** + * USER_WATCH Generator + **********************************************************************************************/ + protected class UserWatchGenerator extends SubTableGenerator { - @Override - public int getElementCounter(LoaderItemInfo itemInfo) { - return itemInfo.getNumWatches(); - } + final Set watchers = new HashSet<>(); - @Override - protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { - int col = 0; + public UserWatchGenerator() throws SQLException { + super(AuctionMarkConstants.TABLENAME_USERACCT_WATCH, AuctionMarkConstants.TABLENAME_ITEM_BID); + } - // Make it more likely that a user that has bid on an item is watching it - Histogram bidderHistogram = itemInfo.getBidderHistogram(); - UserId buyerId = null; - int num_watchers = this.watchers.size(); - boolean use_random = (num_watchers == bidderHistogram.getValueCount()); - long num_users = tableSizes.get(AuctionMarkConstants.TABLENAME_USERACCT); + @Override + public int getElementCounter(LoaderItemInfo itemInfo) { + return itemInfo.getNumWatches(); + } - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Selecting USER_WATCH buyerId [useRandom=%s, watchers=%d]", use_random, this.watchers.size())); - } - int tries = 1000; - while (num_watchers < num_users && tries-- > 0) { - try { - if (use_random) { - buyerId = profile.getRandomBuyerId(); - } else { - buyerId = profile.getRandomBuyerId(bidderHistogram, itemInfo.getSellerId()); - } - } catch (NullPointerException ex) { - LOG.error("Busted Bidder Histogram:\n{}", bidderHistogram); - throw ex; - } - if (!this.watchers.contains(buyerId)) { - break; - } - buyerId = null; - - // If for some reason we unable to find a buyer from our bidderHistogram, - // then just give up and get a random one - if (!use_random && tries == 0) { - use_random = true; - tries = 500; - } - } - this.watchers.add(buyerId); - - // UW_U_ID - row[col++] = buyerId; - // UW_I_ID - row[col++] = itemInfo.getItemId(); - // UW_I_U_ID - row[col++] = itemInfo.getSellerId(); - // UW_CREATED - row[col++] = this.getRandomDate(itemInfo.getStartDate(), itemInfo.getEndDate()); - - return (col); - } + @Override + protected int populateRow(LoaderItemInfo itemInfo, Object[] row, int remaining) { + int col = 0; + + // Make it more likely that a user that has bid on an item is watching it + Histogram bidderHistogram = itemInfo.getBidderHistogram(); + UserId buyerId = null; + int num_watchers = this.watchers.size(); + boolean use_random = (num_watchers == bidderHistogram.getValueCount()); + long num_users = tableSizes.get(AuctionMarkConstants.TABLENAME_USERACCT); + + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Selecting USER_WATCH buyerId [useRandom=%s, watchers=%d]", + use_random, this.watchers.size())); + } + int tries = 1000; + while (num_watchers < num_users && tries-- > 0) { + try { + if (use_random) { + buyerId = profile.getRandomBuyerId(); + } else { + buyerId = profile.getRandomBuyerId(bidderHistogram, itemInfo.getSellerId()); + } + } catch (NullPointerException ex) { + LOG.error("Busted Bidder Histogram:\n{}", bidderHistogram); + throw ex; + } + if (!this.watchers.contains(buyerId)) { + break; + } + buyerId = null; + + // If for some reason we unable to find a buyer from our bidderHistogram, + // then just give up and get a random one + if (!use_random && tries == 0) { + use_random = true; + tries = 500; + } + } + this.watchers.add(buyerId); + + // UW_U_ID + row[col++] = buyerId; + // UW_I_ID + row[col++] = itemInfo.getItemId(); + // UW_I_U_ID + row[col++] = itemInfo.getSellerId(); + // UW_CREATED + row[col++] = this.getRandomDate(itemInfo.getStartDate(), itemInfo.getEndDate()); + + return (col); + } - @Override - protected void finishElementCallback(LoaderItemInfo t) { - if (LOG.isTraceEnabled()) { - LOG.trace("Clearing watcher cache [size={}]", this.watchers.size()); - } - this.watchers.clear(); - } + @Override + protected void finishElementCallback(LoaderItemInfo t) { + if (LOG.isTraceEnabled()) { + LOG.trace("Clearing watcher cache [size={}]", this.watchers.size()); + } + this.watchers.clear(); + } - private Timestamp getRandomDate(Timestamp startDate, Timestamp endDate) { - int start = Math.round(startDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - int end = Math.round(endDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - long offset = profile.rng.number(start, end); - return new Timestamp(offset * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - } + private Timestamp getRandomDate(Timestamp startDate, Timestamp endDate) { + int start = Math.round(startDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + int end = Math.round(endDate.getTime() / AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + long offset = profile.rng.number(start, end); + return new Timestamp(offset * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java index 3b2777cf6..c1a84b63d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkProfile.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark; import com.oltpbenchmark.benchmarks.auctionmark.procedures.Config; @@ -28,16 +27,14 @@ import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; import com.oltpbenchmark.util.RandomDistribution.Gaussian; import com.oltpbenchmark.util.RandomDistribution.Zipf; -import org.apache.commons.collections4.map.ListOrderedMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.*; - +import org.apache.commons.collections4.map.ListOrderedMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AuctionMark Profile Information @@ -45,994 +42,994 @@ * @author pavlo */ public class AuctionMarkProfile { - private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkProfile.class); - - /** - * We maintain a cached version of the profile that we will copy from - * This prevents the need to have every single client thread load up a separate copy - */ - private static AuctionMarkProfile cachedProfile; + private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkProfile.class); - // ---------------------------------------------------------------- - // REQUIRED REFERENCES - // ---------------------------------------------------------------- + /** + * We maintain a cached version of the profile that we will copy from This prevents the need to + * have every single client thread load up a separate copy + */ + private static AuctionMarkProfile cachedProfile; - private final AuctionMarkBenchmark benchmark; + // ---------------------------------------------------------------- + // REQUIRED REFERENCES + // ---------------------------------------------------------------- - private int client_id; + private final AuctionMarkBenchmark benchmark; - /** - * Specialized random number generator - */ - protected transient final RandomGenerator rng; + private int client_id; - /** - * The total number of clients in this benchmark invocation. Each - * client will be responsible for adding new auctions for unique set of sellers - * This may change per benchmark invocation. - */ - private transient final int num_clients; + /** Specialized random number generator */ + protected final transient RandomGenerator rng; - // ---------------------------------------------------------------- - // SERIALIZABLE DATA MEMBERS - // ---------------------------------------------------------------- - static final long serialVersionUID = 0; - - /** - * Database Scale Factor - */ - protected double scale_factor; - - /** - * The start time used when creating the data for this benchmark - */ - private Timestamp loaderStartTime; - - /** - * The stop time for when the loader was finished - * We can reset anything that has a timestamp after this one - */ - private Timestamp loaderStopTime; - - /** - * A histogram for the number of users that have the number of items listed - * ItemCount -> # of Users - */ - protected Histogram users_per_itemCount = new Histogram<>(); - - // ---------------------------------------------------------------- - // TRANSIENT DATA MEMBERS - // ---------------------------------------------------------------- - - /** - * Histogram for number of items per category (stored as category_id) - */ - protected transient Histogram items_per_category = new Histogram<>(); - - /** - * Simple generic class overload to avoid some cast warnings below. - */ - class ItemInfoList extends LinkedList { - // Required serialization field. - static final long serialVersionUID = 0; - } + /** + * The total number of clients in this benchmark invocation. Each client will be responsible for + * adding new auctions for unique set of sellers This may change per benchmark invocation. + */ + private final transient int num_clients; - /** - * Three status types for an item: - * (1) Available - The auction of this item is still open - * (2) Ending Soon - * (2) Wait for Purchase - The auction of this item is still open. - * There is a bid winner and the bid winner has not purchased the item. - * (3) Complete (The auction is closed and (There is no bid winner or - * the bid winner has already purchased the item) - */ - private transient final ItemInfoList items_available = new ItemInfoList(); - private transient final ItemInfoList items_endingSoon = new ItemInfoList(); - private transient final ItemInfoList items_waitingForPurchase = new ItemInfoList(); - private transient final ItemInfoList items_completed = new ItemInfoList(); - - - protected transient final ItemInfoList allItemSets[] = new ItemInfoList[]{ - this.items_available, - this.items_endingSoon, - this.items_waitingForPurchase, - this.items_completed, - }; - - /** - * Internal list of GlobalAttributeGroupIds - */ - protected transient List gag_ids = new ArrayList<>(); - - /** - * Internal map of UserIdGenerators - */ - private transient UserIdGenerator userIdGenerator; - - /** - * Random time different in seconds - */ - public transient final DiscreteRNG randomTimeDiff; - - /** - * Random duration in days - */ - public transient final Gaussian randomDuration; - - protected transient final Zipf randomNumImages; - protected transient final Zipf randomNumAttributes; - protected transient final Zipf randomPurchaseDuration; - protected transient final Zipf randomNumComments; - protected transient final Zipf randomInitialPrice; - - private transient FlatHistogram randomCategory; - private transient FlatHistogram randomItemCount; - - /** - * The last time that we called CHECK_WINNING_BIDS on this client - */ - private transient final Timestamp lastCloseAuctionsTime = new Timestamp(0); - /** - * When this client started executing - */ - private transient final Timestamp clientStartTime = new Timestamp(0); - /** - * Current Timestamp - */ - private transient final Timestamp currentTime = new Timestamp(0); - - /** - * TODO - */ - protected transient final Histogram seller_item_cnt = new Histogram<>(); - - /** - * TODO - */ - protected transient final List pending_commentResponses = new ArrayList<>(); - - // ----------------------------------------------------------------- - // TEMPORARY VARIABLES - // ----------------------------------------------------------------- - - private transient final Set tmp_seenItems = new HashSet<>(); - private transient final Histogram tmp_userIdHistogram = new Histogram<>(true); - private transient final Timestamp tmp_now = new Timestamp(System.currentTimeMillis()); - - // ----------------------------------------------------------------- - // CONSTRUCTOR - // ----------------------------------------------------------------- - - /** - * Constructor - Keep your pimp hand strong! - */ - public AuctionMarkProfile(AuctionMarkBenchmark benchmark, RandomGenerator rng) { - this(benchmark, -1, rng); - } + // ---------------------------------------------------------------- + // SERIALIZABLE DATA MEMBERS + // ---------------------------------------------------------------- + static final long serialVersionUID = 0; - private AuctionMarkProfile(AuctionMarkBenchmark benchmark, int client_id, RandomGenerator rng) { - this.benchmark = benchmark; - this.client_id = client_id; - this.rng = rng; - this.scale_factor = benchmark.getWorkloadConfiguration().getScaleFactor(); - this.num_clients = benchmark.getWorkloadConfiguration().getTerminals(); - this.loaderStartTime = new Timestamp(System.currentTimeMillis()); - - this.randomInitialPrice = new Zipf(this.rng, - AuctionMarkConstants.ITEM_INITIAL_PRICE_MIN, - AuctionMarkConstants.ITEM_INITIAL_PRICE_MAX, - AuctionMarkConstants.ITEM_INITIAL_PRICE_SIGMA); - - // Random time difference in a second scale - this.randomTimeDiff = new Gaussian(this.rng, - AuctionMarkConstants.ITEM_PRESERVE_DAYS * 24 * 60 * 60 * -1, - AuctionMarkConstants.ITEM_DURATION_DAYS_MAX * 24 * 60 * 60); - - this.randomDuration = new Gaussian(this.rng, - AuctionMarkConstants.ITEM_DURATION_DAYS_MIN, - AuctionMarkConstants.ITEM_DURATION_DAYS_MAX); - - this.randomPurchaseDuration = new Zipf(this.rng, - AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_MIN, - AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_MAX, - AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_SIGMA); - - this.randomNumImages = new Zipf(this.rng, - AuctionMarkConstants.ITEM_NUM_IMAGES_MIN, - AuctionMarkConstants.ITEM_NUM_IMAGES_MAX, - AuctionMarkConstants.ITEM_NUM_IMAGES_SIGMA); - - this.randomNumAttributes = new Zipf(this.rng, - AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_MIN, - AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_MAX, - AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_SIGMA); - - this.randomNumComments = new Zipf(this.rng, - AuctionMarkConstants.ITEM_NUM_COMMENTS_MIN, - AuctionMarkConstants.ITEM_NUM_COMMENTS_MAX, - AuctionMarkConstants.ITEM_NUM_COMMENTS_SIGMA); + /** Database Scale Factor */ + protected double scale_factor; - if (LOG.isTraceEnabled()) { - LOG.trace("AuctionMarkBenchmarkProfile :: constructor"); - } - } + /** The start time used when creating the data for this benchmark */ + private Timestamp loaderStartTime; - // ----------------------------------------------------------------- - // SERIALIZATION METHODS - // ----------------------------------------------------------------- + /** + * The stop time for when the loader was finished We can reset anything that has a timestamp after + * this one + */ + private Timestamp loaderStopTime; - protected final void saveProfile(Connection conn) throws SQLException { - this.loaderStopTime = new Timestamp(System.currentTimeMillis()); + /** + * A histogram for the number of users that have the number of items listed ItemCount -> # of + * Users + */ + protected Histogram users_per_itemCount = new Histogram<>(); - // CONFIG_PROFILE - Table catalog_tbl = this.benchmark.getCatalog().getTable(AuctionMarkConstants.TABLENAME_CONFIG_PROFILE); - - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.benchmark.getWorkloadConfiguration().getDatabaseType()); - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - int param_idx = 1; - stmt.setObject(param_idx++, this.scale_factor); // CFP_SCALE_FACTOR - stmt.setObject(param_idx++, this.loaderStartTime); // CFP_LOADER_START - stmt.setObject(param_idx++, this.loaderStopTime); // CFP_LOADER_STOP - stmt.setObject(param_idx++, this.users_per_itemCount.toJSONString()); // CFP_USER_ITEM_HISTOGRAM - int result = stmt.executeUpdate(); - if (result != 1) { - throw new RuntimeException("Bad update!"); - } - } + // ---------------------------------------------------------------- + // TRANSIENT DATA MEMBERS + // ---------------------------------------------------------------- + /** Histogram for number of items per category (stored as category_id) */ + protected transient Histogram items_per_category = new Histogram<>(); - if (LOG.isDebugEnabled()) { - LOG.debug("Saving profile information into {}", catalog_tbl); - } + /** Simple generic class overload to avoid some cast warnings below. */ + class ItemInfoList extends LinkedList { + // Required serialization field. + static final long serialVersionUID = 0; + } + + /** + * Three status types for an item: (1) Available - The auction of this item is still open (2) + * Ending Soon (2) Wait for Purchase - The auction of this item is still open. There is a bid + * winner and the bid winner has not purchased the item. (3) Complete (The auction is closed and + * (There is no bid winner or the bid winner has already purchased the item) + */ + private final transient ItemInfoList items_available = new ItemInfoList(); + + private final transient ItemInfoList items_endingSoon = new ItemInfoList(); + private final transient ItemInfoList items_waitingForPurchase = new ItemInfoList(); + private final transient ItemInfoList items_completed = new ItemInfoList(); + + protected final transient ItemInfoList allItemSets[] = + new ItemInfoList[] { + this.items_available, + this.items_endingSoon, + this.items_waitingForPurchase, + this.items_completed, + }; + + /** Internal list of GlobalAttributeGroupIds */ + protected transient List gag_ids = new ArrayList<>(); + + /** Internal map of UserIdGenerators */ + private transient UserIdGenerator userIdGenerator; + + /** Random time different in seconds */ + public final transient DiscreteRNG randomTimeDiff; + + /** Random duration in days */ + public final transient Gaussian randomDuration; + + protected final transient Zipf randomNumImages; + protected final transient Zipf randomNumAttributes; + protected final transient Zipf randomPurchaseDuration; + protected final transient Zipf randomNumComments; + protected final transient Zipf randomInitialPrice; + + private transient FlatHistogram randomCategory; + private transient FlatHistogram randomItemCount; + + /** The last time that we called CHECK_WINNING_BIDS on this client */ + private final transient Timestamp lastCloseAuctionsTime = new Timestamp(0); + + /** When this client started executing */ + private final transient Timestamp clientStartTime = new Timestamp(0); + + /** Current Timestamp */ + private final transient Timestamp currentTime = new Timestamp(0); + + /** TODO */ + protected final transient Histogram seller_item_cnt = new Histogram<>(); + + /** TODO */ + protected final transient List pending_commentResponses = new ArrayList<>(); + + // ----------------------------------------------------------------- + // TEMPORARY VARIABLES + // ----------------------------------------------------------------- + + private final transient Set tmp_seenItems = new HashSet<>(); + private final transient Histogram tmp_userIdHistogram = new Histogram<>(true); + private final transient Timestamp tmp_now = new Timestamp(System.currentTimeMillis()); + + // ----------------------------------------------------------------- + // CONSTRUCTOR + // ----------------------------------------------------------------- + + /** Constructor - Keep your pimp hand strong! */ + public AuctionMarkProfile(AuctionMarkBenchmark benchmark, RandomGenerator rng) { + this(benchmark, -1, rng); + } + + private AuctionMarkProfile(AuctionMarkBenchmark benchmark, int client_id, RandomGenerator rng) { + this.benchmark = benchmark; + this.client_id = client_id; + this.rng = rng; + this.scale_factor = benchmark.getWorkloadConfiguration().getScaleFactor(); + this.num_clients = benchmark.getWorkloadConfiguration().getTerminals(); + this.loaderStartTime = new Timestamp(System.currentTimeMillis()); + + this.randomInitialPrice = + new Zipf( + this.rng, + AuctionMarkConstants.ITEM_INITIAL_PRICE_MIN, + AuctionMarkConstants.ITEM_INITIAL_PRICE_MAX, + AuctionMarkConstants.ITEM_INITIAL_PRICE_SIGMA); + + // Random time difference in a second scale + this.randomTimeDiff = + new Gaussian( + this.rng, + AuctionMarkConstants.ITEM_PRESERVE_DAYS * 24 * 60 * 60 * -1, + AuctionMarkConstants.ITEM_DURATION_DAYS_MAX * 24 * 60 * 60); + + this.randomDuration = + new Gaussian( + this.rng, + AuctionMarkConstants.ITEM_DURATION_DAYS_MIN, + AuctionMarkConstants.ITEM_DURATION_DAYS_MAX); + + this.randomPurchaseDuration = + new Zipf( + this.rng, + AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_MIN, + AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_MAX, + AuctionMarkConstants.ITEM_PURCHASE_DURATION_DAYS_SIGMA); + + this.randomNumImages = + new Zipf( + this.rng, + AuctionMarkConstants.ITEM_NUM_IMAGES_MIN, + AuctionMarkConstants.ITEM_NUM_IMAGES_MAX, + AuctionMarkConstants.ITEM_NUM_IMAGES_SIGMA); + + this.randomNumAttributes = + new Zipf( + this.rng, + AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_MIN, + AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_MAX, + AuctionMarkConstants.ITEM_NUM_GLOBAL_ATTRS_SIGMA); + + this.randomNumComments = + new Zipf( + this.rng, + AuctionMarkConstants.ITEM_NUM_COMMENTS_MIN, + AuctionMarkConstants.ITEM_NUM_COMMENTS_MAX, + AuctionMarkConstants.ITEM_NUM_COMMENTS_SIGMA); + + if (LOG.isTraceEnabled()) { + LOG.trace("AuctionMarkBenchmarkProfile :: constructor"); + } + } + + // ----------------------------------------------------------------- + // SERIALIZATION METHODS + // ----------------------------------------------------------------- + + protected final void saveProfile(Connection conn) throws SQLException { + this.loaderStopTime = new Timestamp(System.currentTimeMillis()); + + // CONFIG_PROFILE + Table catalog_tbl = + this.benchmark.getCatalog().getTable(AuctionMarkConstants.TABLENAME_CONFIG_PROFILE); + + String sql = + SQLUtil.getInsertSQL( + catalog_tbl, this.benchmark.getWorkloadConfiguration().getDatabaseType()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int param_idx = 1; + stmt.setObject(param_idx++, this.scale_factor); // CFP_SCALE_FACTOR + stmt.setObject(param_idx++, this.loaderStartTime); // CFP_LOADER_START + stmt.setObject(param_idx++, this.loaderStopTime); // CFP_LOADER_STOP + stmt.setObject( + param_idx++, this.users_per_itemCount.toJSONString()); // CFP_USER_ITEM_HISTOGRAM + int result = stmt.executeUpdate(); + if (result != 1) { + throw new RuntimeException("Bad update!"); + } } - private AuctionMarkProfile copyProfile(AuctionMarkWorker worker, AuctionMarkProfile other) { - this.client_id = worker.getId(); - this.scale_factor = other.scale_factor; - this.loaderStartTime = other.loaderStartTime; - this.loaderStopTime = other.loaderStopTime; - this.users_per_itemCount = other.users_per_itemCount; - this.items_per_category = other.items_per_category; - this.gag_ids = other.gag_ids; - - // Initialize the UserIdGenerator so we can figure out whether our - // client should even have these ids - this.initializeUserIdGenerator(this.client_id); - - - for (int i = 0; i < this.allItemSets.length; i++) { - LinkedList list = this.allItemSets[i]; - - LinkedList origList = other.allItemSets[i]; - - - for (ItemInfo itemInfo : origList) { - UserId sellerId = itemInfo.getSellerId(); - if (this.userIdGenerator.checkClient(sellerId)) { - this.seller_item_cnt.set(sellerId, sellerId.getItemCount()); - list.add(itemInfo); - } - } - Collections.shuffle(list); - } - - for (ItemCommentResponse cr : other.pending_commentResponses) { - UserId sellerId = new UserId(cr.getSellerId()); - if (this.userIdGenerator.checkClient(sellerId)) { - this.pending_commentResponses.add(cr); - } - } - - if (LOG.isTraceEnabled()) { - LOG.trace("SellerItemCounts:\n{}", this.seller_item_cnt); + if (LOG.isDebugEnabled()) { + LOG.debug("Saving profile information into {}", catalog_tbl); + } + } + + private AuctionMarkProfile copyProfile(AuctionMarkWorker worker, AuctionMarkProfile other) { + this.client_id = worker.getId(); + this.scale_factor = other.scale_factor; + this.loaderStartTime = other.loaderStartTime; + this.loaderStopTime = other.loaderStopTime; + this.users_per_itemCount = other.users_per_itemCount; + this.items_per_category = other.items_per_category; + this.gag_ids = other.gag_ids; + + // Initialize the UserIdGenerator so we can figure out whether our + // client should even have these ids + this.initializeUserIdGenerator(this.client_id); + + for (int i = 0; i < this.allItemSets.length; i++) { + LinkedList list = this.allItemSets[i]; + + LinkedList origList = other.allItemSets[i]; + + for (ItemInfo itemInfo : origList) { + UserId sellerId = itemInfo.getSellerId(); + if (this.userIdGenerator.checkClient(sellerId)) { + this.seller_item_cnt.set(sellerId, sellerId.getItemCount()); + list.add(itemInfo); } - - return (this); + } + Collections.shuffle(list); } - protected static void clearCachedProfile() { - cachedProfile = null; + for (ItemCommentResponse cr : other.pending_commentResponses) { + UserId sellerId = new UserId(cr.getSellerId()); + if (this.userIdGenerator.checkClient(sellerId)) { + this.pending_commentResponses.add(cr); + } } - /** - * Load the profile information stored in the database - * - * @param - */ - protected void loadProfile(AuctionMarkWorker worker) throws SQLException { - synchronized (AuctionMarkProfile.class) { - // Check whether we have a cached Profile we can copy from - if (cachedProfile == null) { - - // Store everything in the cached profile. - // We can then copy from that and extract out only the records - // that we need for each AuctionMarkWorker - cachedProfile = new AuctionMarkProfile(this.benchmark, this.rng); - - // Otherwise we have to go fetch everything again - // So first we want to reset the database - try (Connection conn = benchmark.makeConnection()) { - - if (AuctionMarkConstants.RESET_DATABASE_ENABLE) { - if (LOG.isDebugEnabled()) { - LOG.debug("Resetting database from last execution run"); - } - worker.getProcedure(ResetDatabase.class).run(conn); - } - - } - - - // Then invoke LoadConfig to pull down the profile information we need - if (LOG.isDebugEnabled()) { - LOG.debug("Loading AuctionMarkProfile for the first time"); - } - - Config results; - try (Connection conn = benchmark.makeConnection()) { - results = worker.getProcedure(LoadConfig.class).run(conn); - } - - // CONFIG_PROFILE - loadConfigProfile(cachedProfile, results.getConfigProfile()); - - // IMPORTANT: We need to set these timestamps here. It must be done - // after we have loaded benchmarkStartTime - cachedProfile.setAndGetClientStartTime(); - cachedProfile.updateAndGetCurrentTime(); - - // ITEM CATEGORY COUNTS - loadItemCategoryCounts(cachedProfile, results.getCategoryCounts()); - - // GLOBAL_ATTRIBUTE_GROUPS - loadGlobalAttributeGroups(cachedProfile, results.getAttributes()); - - // PENDING COMMENTS - loadPendingItemComments(cachedProfile, results.getPendingComments()); - - - loadItems(cachedProfile, results.getOpenItems()); - loadItems(cachedProfile, results.getWaitingForPurchaseItems()); - loadItems(cachedProfile, results.getClosedItems()); - + if (LOG.isTraceEnabled()) { + LOG.trace("SellerItemCounts:\n{}", this.seller_item_cnt); + } - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded profile:\n{}", cachedProfile.toString()); - } + return (this); + } + + protected static void clearCachedProfile() { + cachedProfile = null; + } + + /** + * Load the profile information stored in the database + * + * @param + */ + protected void loadProfile(AuctionMarkWorker worker) throws SQLException { + synchronized (AuctionMarkProfile.class) { + // Check whether we have a cached Profile we can copy from + if (cachedProfile == null) { + + // Store everything in the cached profile. + // We can then copy from that and extract out only the records + // that we need for each AuctionMarkWorker + cachedProfile = new AuctionMarkProfile(this.benchmark, this.rng); + + // Otherwise we have to go fetch everything again + // So first we want to reset the database + try (Connection conn = benchmark.makeConnection()) { + + if (AuctionMarkConstants.RESET_DATABASE_ENABLE) { + if (LOG.isDebugEnabled()) { + LOG.debug("Resetting database from last execution run"); } + worker.getProcedure(ResetDatabase.class).run(conn); + } } - if (LOG.isTraceEnabled()) { - LOG.trace("Using cached AuctionMarkProfile"); + // Then invoke LoadConfig to pull down the profile information we need + if (LOG.isDebugEnabled()) { + LOG.debug("Loading AuctionMarkProfile for the first time"); } - this.copyProfile(worker, cachedProfile); - } + Config results; + try (Connection conn = benchmark.makeConnection()) { + results = worker.getProcedure(LoadConfig.class).run(conn); + } - private void initializeUserIdGenerator(int clientId) { + // CONFIG_PROFILE + loadConfigProfile(cachedProfile, results.getConfigProfile()); + // IMPORTANT: We need to set these timestamps here. It must be done + // after we have loaded benchmarkStartTime + cachedProfile.setAndGetClientStartTime(); + cachedProfile.updateAndGetCurrentTime(); - this.userIdGenerator = new UserIdGenerator(this.users_per_itemCount, - this.num_clients, - (clientId < 0 ? null : clientId)); - } + // ITEM CATEGORY COUNTS + loadItemCategoryCounts(cachedProfile, results.getCategoryCounts()); - private static void loadConfigProfile(AuctionMarkProfile profile, List vt) { - for (Object[] row : vt) { - profile.scale_factor = SQLUtil.getDouble(row[0]); - profile.loaderStartTime = SQLUtil.getTimestamp(row[1]); - profile.loaderStopTime = SQLUtil.getTimestamp(row[2]); - JSONUtil.fromJSONString(profile.users_per_itemCount, SQLUtil.getString(row[3])); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %s data", AuctionMarkConstants.TABLENAME_CONFIG_PROFILE)); - } - } + // GLOBAL_ATTRIBUTE_GROUPS + loadGlobalAttributeGroups(cachedProfile, results.getAttributes()); - private static void loadItemCategoryCounts(AuctionMarkProfile profile, List vt) { - for (Object[] row : vt) { - long i_c_id = SQLUtil.getLong(row[0]); - int count = SQLUtil.getInteger(row[1]); - profile.items_per_category.put((int) i_c_id, count); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d CATEGORY records from %s", - profile.items_per_category.getValueCount(), AuctionMarkConstants.TABLENAME_ITEM)); - } - } + // PENDING COMMENTS + loadPendingItemComments(cachedProfile, results.getPendingComments()); - private static void loadItems(AuctionMarkProfile profile, List vt) { - int ctr = 0; - for (Object[] row : vt) { - ItemId i_id = new ItemId(SQLUtil.getString(row[0])); - double i_current_price = SQLUtil.getDouble(row[1]); - Timestamp i_end_date = SQLUtil.getTimestamp(row[2]); - int i_num_bids = SQLUtil.getInteger(row[3]); - - // IMPORTANT: Do not set the status here so that we make sure that - // it is added to the right queue - ItemInfo itemInfo = new ItemInfo(i_id, i_current_price, i_end_date, i_num_bids); - profile.addItemToProperQueue(itemInfo, false); - ctr++; - } + loadItems(cachedProfile, results.getOpenItems()); + loadItems(cachedProfile, results.getWaitingForPurchaseItems()); + loadItems(cachedProfile, results.getClosedItems()); if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d records from %s", - ctr, AuctionMarkConstants.TABLENAME_ITEM)); + LOG.debug("Loaded profile:\n{}", cachedProfile.toString()); } + } } - private static void loadPendingItemComments(AuctionMarkProfile profile, List vt) { - for (Object[] row : vt) { - long ic_id = SQLUtil.getLong(row[0]); - String ic_i_id = SQLUtil.getString(row[1]); - String ic_u_id = SQLUtil.getString(row[2]); - ItemCommentResponse cr = new ItemCommentResponse(ic_id, ic_i_id, ic_u_id); - profile.pending_commentResponses.add(cr); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d records from %s", - profile.pending_commentResponses.size(), AuctionMarkConstants.TABLENAME_ITEM_COMMENT)); - } + if (LOG.isTraceEnabled()) { + LOG.trace("Using cached AuctionMarkProfile"); } - - private static void loadGlobalAttributeGroups(AuctionMarkProfile profile, List vt) { - for (Object[] row : vt) { - String gag_id = SQLUtil.getString(row[0]); - profile.gag_ids.add(new GlobalAttributeGroupId(gag_id)); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d records from %s", - profile.gag_ids.size(), AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP)); - } + this.copyProfile(worker, cachedProfile); + } + + private void initializeUserIdGenerator(int clientId) { + + this.userIdGenerator = + new UserIdGenerator( + this.users_per_itemCount, this.num_clients, (clientId < 0 ? null : clientId)); + } + + private static void loadConfigProfile(AuctionMarkProfile profile, List vt) { + for (Object[] row : vt) { + profile.scale_factor = SQLUtil.getDouble(row[0]); + profile.loaderStartTime = SQLUtil.getTimestamp(row[1]); + profile.loaderStopTime = SQLUtil.getTimestamp(row[2]); + JSONUtil.fromJSONString(profile.users_per_itemCount, SQLUtil.getString(row[3])); } - - // ----------------------------------------------------------------- - // TIME METHODS - // ----------------------------------------------------------------- - - private Timestamp getScaledCurrentTimestamp(Timestamp time) { - - tmp_now.setTime(System.currentTimeMillis()); - time.setTime(AuctionMarkUtil.getScaledTimestamp(this.loaderStartTime, this.clientStartTime, tmp_now)); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Scaled:%d / Now:%d / BenchmarkStart:%d / ClientStart:%d", - time.getTime(), tmp_now.getTime(), this.loaderStartTime.getTime(), this.clientStartTime.getTime())); - } - return (time); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %s data", AuctionMarkConstants.TABLENAME_CONFIG_PROFILE)); } + } - public synchronized Timestamp updateAndGetCurrentTime() { - this.getScaledCurrentTimestamp(this.currentTime); - if (LOG.isTraceEnabled()) { - LOG.trace("CurrentTime: {}", currentTime); - } - return this.currentTime; + private static void loadItemCategoryCounts(AuctionMarkProfile profile, List vt) { + for (Object[] row : vt) { + long i_c_id = SQLUtil.getLong(row[0]); + int count = SQLUtil.getInteger(row[1]); + profile.items_per_category.put((int) i_c_id, count); } - - public Timestamp getCurrentTime() { - return this.currentTime; + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Loaded %d CATEGORY records from %s", + profile.items_per_category.getValueCount(), AuctionMarkConstants.TABLENAME_ITEM)); } - - public Timestamp getLoaderStartTime() { - return (this.loaderStartTime); + } + + private static void loadItems(AuctionMarkProfile profile, List vt) { + int ctr = 0; + for (Object[] row : vt) { + ItemId i_id = new ItemId(SQLUtil.getString(row[0])); + double i_current_price = SQLUtil.getDouble(row[1]); + Timestamp i_end_date = SQLUtil.getTimestamp(row[2]); + int i_num_bids = SQLUtil.getInteger(row[3]); + + // IMPORTANT: Do not set the status here so that we make sure that + // it is added to the right queue + ItemInfo itemInfo = new ItemInfo(i_id, i_current_price, i_end_date, i_num_bids); + profile.addItemToProperQueue(itemInfo, false); + ctr++; } - public Timestamp getLoaderStopTime() { - return (this.loaderStopTime); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format("Loaded %d records from %s", ctr, AuctionMarkConstants.TABLENAME_ITEM)); } - - public Timestamp setAndGetClientStartTime() { - - this.clientStartTime.setTime(System.currentTimeMillis()); - return (this.clientStartTime); + } + + private static void loadPendingItemComments(AuctionMarkProfile profile, List vt) { + for (Object[] row : vt) { + long ic_id = SQLUtil.getLong(row[0]); + String ic_i_id = SQLUtil.getString(row[1]); + String ic_u_id = SQLUtil.getString(row[2]); + ItemCommentResponse cr = new ItemCommentResponse(ic_id, ic_i_id, ic_u_id); + profile.pending_commentResponses.add(cr); } - - public Timestamp getClientStartTime() { - return (this.clientStartTime); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Loaded %d records from %s", + profile.pending_commentResponses.size(), + AuctionMarkConstants.TABLENAME_ITEM_COMMENT)); } + } - public boolean hasClientStartTime() { - return (this.clientStartTime.getTime() != 0); + private static void loadGlobalAttributeGroups(AuctionMarkProfile profile, List vt) { + for (Object[] row : vt) { + String gag_id = SQLUtil.getString(row[0]); + profile.gag_ids.add(new GlobalAttributeGroupId(gag_id)); } - - public synchronized Timestamp updateAndGetLastCloseAuctionsTime() { - this.getScaledCurrentTimestamp(this.lastCloseAuctionsTime); - return this.lastCloseAuctionsTime; + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Loaded %d records from %s", + profile.gag_ids.size(), AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP)); } - - public Timestamp getLastCloseAuctionsTime() { - return this.lastCloseAuctionsTime; + } + + // ----------------------------------------------------------------- + // TIME METHODS + // ----------------------------------------------------------------- + + private Timestamp getScaledCurrentTimestamp(Timestamp time) { + + tmp_now.setTime(System.currentTimeMillis()); + time.setTime( + AuctionMarkUtil.getScaledTimestamp(this.loaderStartTime, this.clientStartTime, tmp_now)); + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Scaled:%d / Now:%d / BenchmarkStart:%d / ClientStart:%d", + time.getTime(), + tmp_now.getTime(), + this.loaderStartTime.getTime(), + this.clientStartTime.getTime())); } + return (time); + } - - // ----------------------------------------------------------------- - // GENERAL METHODS - // ----------------------------------------------------------------- - - /** - * Get the scale factor value for this benchmark profile - * - * @return - */ - public double getScaleFactor() { - return (this.scale_factor); + public synchronized Timestamp updateAndGetCurrentTime() { + this.getScaledCurrentTimestamp(this.currentTime); + if (LOG.isTraceEnabled()) { + LOG.trace("CurrentTime: {}", currentTime); } - - /** - * Set the scale factor for this benchmark profile - * - * @param scale_factor - */ - public void setScaleFactor(double scale_factor) { - - this.scale_factor = scale_factor; + return this.currentTime; + } + + public Timestamp getCurrentTime() { + return this.currentTime; + } + + public Timestamp getLoaderStartTime() { + return (this.loaderStartTime); + } + + public Timestamp getLoaderStopTime() { + return (this.loaderStopTime); + } + + public Timestamp setAndGetClientStartTime() { + + this.clientStartTime.setTime(System.currentTimeMillis()); + return (this.clientStartTime); + } + + public Timestamp getClientStartTime() { + return (this.clientStartTime); + } + + public boolean hasClientStartTime() { + return (this.clientStartTime.getTime() != 0); + } + + public synchronized Timestamp updateAndGetLastCloseAuctionsTime() { + this.getScaledCurrentTimestamp(this.lastCloseAuctionsTime); + return this.lastCloseAuctionsTime; + } + + public Timestamp getLastCloseAuctionsTime() { + return this.lastCloseAuctionsTime; + } + + // ----------------------------------------------------------------- + // GENERAL METHODS + // ----------------------------------------------------------------- + + /** + * Get the scale factor value for this benchmark profile + * + * @return + */ + public double getScaleFactor() { + return (this.scale_factor); + } + + /** + * Set the scale factor for this benchmark profile + * + * @param scale_factor + */ + public void setScaleFactor(double scale_factor) { + + this.scale_factor = scale_factor; + } + + // ---------------------------------------------------------------- + // USER METHODS + // ---------------------------------------------------------------- + + /** + * Note that this synchronization block only matters for the loader + * + * @param min_item_count + * @param clientId - Will use null if less than zero + * @param exclude + * @return + */ + private synchronized UserId getRandomUserId(int min_item_count, int clientId, UserId... exclude) { + // We use the UserIdGenerator to ensure that we always select the next UserId for + // a given client from the same set of UserIds + if (this.randomItemCount == null) { + this.randomItemCount = new FlatHistogram<>(this.rng, this.users_per_itemCount); + } + if (this.userIdGenerator == null) { + this.initializeUserIdGenerator(clientId); } - // ---------------------------------------------------------------- - // USER METHODS - // ---------------------------------------------------------------- - - /** - * Note that this synchronization block only matters for the loader - * - * @param min_item_count - * @param clientId - Will use null if less than zero - * @param exclude - * @return - */ - private synchronized UserId getRandomUserId(int min_item_count, int clientId, UserId... exclude) { - // We use the UserIdGenerator to ensure that we always select the next UserId for - // a given client from the same set of UserIds - if (this.randomItemCount == null) { - this.randomItemCount = new FlatHistogram<>(this.rng, this.users_per_itemCount); - } - if (this.userIdGenerator == null) { - this.initializeUserIdGenerator(clientId); - } - - UserId user_id = null; - int tries = 1000; - final long num_users = this.userIdGenerator.getTotalUsers() - 1; - while (user_id == null && tries-- > 0) { - // We first need to figure out how many items our seller needs to have - long itemCount = -1; - // assert(min_item_count < this.users_per_item_count.getMaxValue()); - while (itemCount < min_item_count) { - itemCount = this.randomItemCount.nextValue(); - } - - // Set the current item count and then choose a random position - // between where the generator is currently at and where it ends - this.userIdGenerator.setCurrentItemCount((int) itemCount); - long cur_position = this.userIdGenerator.getCurrentPosition(); - long new_position = rng.number(cur_position, num_users); - user_id = this.userIdGenerator.seekToPosition((int) new_position); - if (user_id == null) { - continue; - } - - // Make sure that we didn't select the same UserId as the one we were - // told to exclude. - if (exclude != null && exclude.length > 0) { - for (UserId ex : exclude) { - if (ex != null && ex.equals(user_id)) { - if (LOG.isTraceEnabled()) { - LOG.trace("Excluding {}", user_id); - } - user_id = null; - break; - } - } - if (user_id == null) { - continue; - } - } - - // If we don't care about skew, then we're done right here + UserId user_id = null; + int tries = 1000; + final long num_users = this.userIdGenerator.getTotalUsers() - 1; + while (user_id == null && tries-- > 0) { + // We first need to figure out how many items our seller needs to have + long itemCount = -1; + // assert(min_item_count < this.users_per_item_count.getMaxValue()); + while (itemCount < min_item_count) { + itemCount = this.randomItemCount.nextValue(); + } + + // Set the current item count and then choose a random position + // between where the generator is currently at and where it ends + this.userIdGenerator.setCurrentItemCount((int) itemCount); + long cur_position = this.userIdGenerator.getCurrentPosition(); + long new_position = rng.number(cur_position, num_users); + user_id = this.userIdGenerator.seekToPosition((int) new_position); + if (user_id == null) { + continue; + } + + // Make sure that we didn't select the same UserId as the one we were + // told to exclude. + if (exclude != null && exclude.length > 0) { + for (UserId ex : exclude) { + if (ex != null && ex.equals(user_id)) { if (LOG.isTraceEnabled()) { - LOG.trace("Selected {}", user_id); + LOG.trace("Excluding {}", user_id); } + user_id = null; break; + } } - if (user_id == null && LOG.isDebugEnabled()) { - LOG.warn(String.format("Failed to select a random UserId " + - "[minItemCount=%d, clientId=%d, exclude=%s, totalPossible=%d, currentPosition=%d]", - min_item_count, clientId, Arrays.toString(exclude), - this.userIdGenerator.getTotalUsers(), this.userIdGenerator.getCurrentPosition())); + if (user_id == null) { + continue; } - return (user_id); - } + } - /** - * Gets a random buyer ID for all clients - * - * @return - */ - public UserId getRandomBuyerId(UserId... exclude) { - // We don't care about skewing the buyerIds at this point, so just get one from getRandomUserId - return (this.getRandomUserId(0, -1, exclude)); + // If we don't care about skew, then we're done right here + if (LOG.isTraceEnabled()) { + LOG.trace("Selected {}", user_id); + } + break; } - - /** - * Get a random buyer UserId, where the probability that a particular user is selected - * increases based on the number of bids that they have made in the past. We won't allow - * the last bidder to be selected again - * - * @param previousBidders - * @return - */ - public UserId getRandomBuyerId(Histogram previousBidders, UserId... exclude) { - // This is very inefficient, but it's probably good enough for now - tmp_userIdHistogram.clear(); - tmp_userIdHistogram.putHistogram(previousBidders); - for (UserId ex : exclude) { - tmp_userIdHistogram.removeAll(ex); - } - tmp_userIdHistogram.put(this.getRandomBuyerId(exclude)); - - - LOG.trace("New Histogram:\n{}", tmp_userIdHistogram); - - FlatHistogram rand_h = new FlatHistogram<>(rng, tmp_userIdHistogram); - return (rand_h.nextValue()); + if (user_id == null && LOG.isDebugEnabled()) { + LOG.warn( + String.format( + "Failed to select a random UserId " + + "[minItemCount=%d, clientId=%d, exclude=%s, totalPossible=%d, currentPosition=%d]", + min_item_count, + clientId, + Arrays.toString(exclude), + this.userIdGenerator.getTotalUsers(), + this.userIdGenerator.getCurrentPosition())); } - - /** - * Gets a random SellerID for the given client - * - * @return - */ - public UserId getRandomSellerId(int client) { - return (this.getRandomUserId(1, client)); + return (user_id); + } + + /** + * Gets a random buyer ID for all clients + * + * @return + */ + public UserId getRandomBuyerId(UserId... exclude) { + // We don't care about skewing the buyerIds at this point, so just get one from getRandomUserId + return (this.getRandomUserId(0, -1, exclude)); + } + + /** + * Get a random buyer UserId, where the probability that a particular user is selected increases + * based on the number of bids that they have made in the past. We won't allow the last bidder to + * be selected again + * + * @param previousBidders + * @return + */ + public UserId getRandomBuyerId(Histogram previousBidders, UserId... exclude) { + // This is very inefficient, but it's probably good enough for now + tmp_userIdHistogram.clear(); + tmp_userIdHistogram.putHistogram(previousBidders); + for (UserId ex : exclude) { + tmp_userIdHistogram.removeAll(ex); } - - public void addPendingItemCommentResponse(ItemCommentResponse cr) { - if (this.client_id != -1) { - UserId sellerId = new UserId(cr.getSellerId()); - if (!this.userIdGenerator.checkClient(sellerId)) { - return; - } - } - this.pending_commentResponses.add(cr); + tmp_userIdHistogram.put(this.getRandomBuyerId(exclude)); + + LOG.trace("New Histogram:\n{}", tmp_userIdHistogram); + + FlatHistogram rand_h = new FlatHistogram<>(rng, tmp_userIdHistogram); + return (rand_h.nextValue()); + } + + /** + * Gets a random SellerID for the given client + * + * @return + */ + public UserId getRandomSellerId(int client) { + return (this.getRandomUserId(1, client)); + } + + public void addPendingItemCommentResponse(ItemCommentResponse cr) { + if (this.client_id != -1) { + UserId sellerId = new UserId(cr.getSellerId()); + if (!this.userIdGenerator.checkClient(sellerId)) { + return; + } } - - // ---------------------------------------------------------------- - // ITEM METHODS - // ---------------------------------------------------------------- - - - public ItemId getNextItemId(UserId seller_id) { - Integer cnt = this.seller_item_cnt.get(seller_id); - if (cnt == null || cnt == 0) { - cnt = seller_id.getItemCount(); - this.seller_item_cnt.put(seller_id, cnt); - } - this.seller_item_cnt.put(seller_id, 1); - return (new ItemId(seller_id, cnt)); + this.pending_commentResponses.add(cr); + } + + // ---------------------------------------------------------------- + // ITEM METHODS + // ---------------------------------------------------------------- + + public ItemId getNextItemId(UserId seller_id) { + Integer cnt = this.seller_item_cnt.get(seller_id); + if (cnt == null || cnt == 0) { + cnt = seller_id.getItemCount(); + this.seller_item_cnt.put(seller_id, cnt); } + this.seller_item_cnt.put(seller_id, 1); + return (new ItemId(seller_id, cnt)); + } - private boolean addItem(LinkedList items, ItemInfo itemInfo) { - boolean added = false; - - int idx = items.indexOf(itemInfo); - if (idx != -1) { - // HACK: Always swap existing ItemInfos with our new one, since it will - // more up-to-date information - ItemInfo existing = items.set(idx, itemInfo); - assert existing != null; - - return (true); - } - if (itemInfo.hasCurrentPrice()) - + private boolean addItem(LinkedList items, ItemInfo itemInfo) { + boolean added = false; - // If we have room, shove it right in - // We'll throw it in the back because we know it hasn't been used yet - { - if (items.size() < AuctionMarkConstants.ITEM_ID_CACHE_SIZE) { - items.addLast(itemInfo); - added = true; + int idx = items.indexOf(itemInfo); + if (idx != -1) { + // HACK: Always swap existing ItemInfos with our new one, since it will + // more up-to-date information + ItemInfo existing = items.set(idx, itemInfo); + assert existing != null; - // Otherwise, we can will randomly decide whether to pop one out - } else if (this.rng.nextBoolean()) { - items.pop(); - items.addLast(itemInfo); - added = true; - } - } - return (added); + return (true); } - - public void updateItemQueues() { - Timestamp currentTime = this.updateAndGetCurrentTime(); - - - for (LinkedList items : allItemSets) { - // If the items is already in the completed queue, then we don't need - // to do anything with it. - if (items == this.items_completed) { - continue; - } - - for (Iterator it = items.iterator(); it.hasNext();) { - this.addItemToProperQueue(it.next(), currentTime, it); - } - } - - if (LOG.isDebugEnabled()) { - Map m = new HashMap<>(); - m.put(ItemStatus.OPEN, this.items_available.size()); - m.put(ItemStatus.ENDING_SOON, this.items_endingSoon.size()); - m.put(ItemStatus.WAITING_FOR_PURCHASE, this.items_waitingForPurchase.size()); - m.put(ItemStatus.CLOSED, this.items_completed.size()); - LOG.debug(String.format("Updated Item Queues [%s]:\n%s", - currentTime, StringUtil.formatMaps(m))); - } + if (itemInfo.hasCurrentPrice()) + + // If we have room, shove it right in + // We'll throw it in the back because we know it hasn't been used yet + { + if (items.size() < AuctionMarkConstants.ITEM_ID_CACHE_SIZE) { + items.addLast(itemInfo); + added = true; + + // Otherwise, we can will randomly decide whether to pop one out + } else if (this.rng.nextBoolean()) { + items.pop(); + items.addLast(itemInfo); + added = true; + } } - - public ItemStatus addItemToProperQueue(ItemInfo itemInfo, boolean is_loader) { - // Calculate how much time is left for this auction - Timestamp baseTime = (is_loader ? this.getLoaderStartTime() : this.getCurrentTime()); - - - return addItemToProperQueue(itemInfo, baseTime, null); + return (added); + } + + public void updateItemQueues() { + Timestamp currentTime = this.updateAndGetCurrentTime(); + + for (LinkedList items : allItemSets) { + // If the items is already in the completed queue, then we don't need + // to do anything with it. + if (items == this.items_completed) { + continue; + } + + for (Iterator it = items.iterator(); it.hasNext(); ) { + this.addItemToProperQueue(it.next(), currentTime, it); + } } - private ItemStatus addItemToProperQueue(ItemInfo itemInfo, Timestamp baseTime, Iterator currentQueueIterator) { - // Always check whether we even want it for this client - // The loader's profile and the cache profile will always have a negative client_id, - // which means that we always want to keep it - if (this.client_id != -1) { - if (this.userIdGenerator == null) { - this.initializeUserIdGenerator(this.client_id); - } - if (!this.userIdGenerator.checkClient(itemInfo.getSellerId())) { - return (null); - } - } - - long remaining = itemInfo.getEndDate().getTime() - baseTime.getTime(); - - - ItemStatus existingStatus = itemInfo.getStatus(); - ItemStatus new_status = (existingStatus != null ? existingStatus : ItemStatus.OPEN); - - if (remaining <= 0) { - new_status = ItemStatus.CLOSED; - } else if (remaining < AuctionMarkConstants.ITEM_ENDING_SOON) { - new_status = ItemStatus.ENDING_SOON; - } else if (itemInfo.getNumBids() > 0 && existingStatus != ItemStatus.CLOSED) { - new_status = ItemStatus.WAITING_FOR_PURCHASE; - } - - - if (!new_status.equals(existingStatus)) { - // Remove the item from the current queue - if (currentQueueIterator != null) { - currentQueueIterator.remove(); - } - - switch (new_status) { - case OPEN: - this.addItem(this.items_available, itemInfo); - break; - case ENDING_SOON: - this.addItem(this.items_endingSoon, itemInfo); - break; - case WAITING_FOR_PURCHASE: - this.addItem(this.items_waitingForPurchase, itemInfo); - break; - case CLOSED: - this.addItem(this.items_completed, itemInfo); - break; - default: - } - itemInfo.setStatus(new_status); - } - - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("%s - #%s [%s]", new_status, itemInfo.getItemId().encode(), itemInfo.getEndDate())); - } - - return (new_status); - } - - /** - * @param itemSet - * @param needCurrentPrice - * @param needFutureEndDate TODO - * @return - */ - private ItemInfo getRandomItem(LinkedList itemSet, boolean needCurrentPrice, boolean needFutureEndDate) { - Timestamp currentTime = this.updateAndGetCurrentTime(); - int num_items = itemSet.size(); - int idx = -1; - ItemInfo itemInfo = null; - - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Getting random ItemInfo [numItems=%d, currentTime=%s, needCurrentPrice=%s]", - num_items, currentTime, needCurrentPrice)); - } - long tries = 1000; - tmp_seenItems.clear(); - while (num_items > 0 && tries-- > 0 && tmp_seenItems.size() < num_items) { - idx = this.rng.nextInt(num_items); - ItemInfo temp = itemSet.get(idx); - - if (tmp_seenItems.contains(temp)) { - continue; - } - tmp_seenItems.add(temp); - - // Needs to have an embedded currentPrice - if (needCurrentPrice && !temp.hasCurrentPrice()) { - continue; - } - - // If they want an item that is ending in the future, then we compare it with - // the current timestamp - if (needFutureEndDate) { - boolean compareTo = (temp.getEndDate().compareTo(currentTime) < 0); - if (LOG.isTraceEnabled()) { - LOG.trace("CurrentTime:{} / EndTime:{} [compareTo={}]", currentTime, temp.getEndDate(), compareTo); - } - if (!temp.hasEndDate() || compareTo) { - continue; - } - } - - // Uniform - itemInfo = temp; - break; - } - if (itemInfo == null) { - if (LOG.isDebugEnabled()) { - LOG.debug("Failed to find ItemInfo [hasCurrentPrice={}, needFutureEndDate={}]", needCurrentPrice, needFutureEndDate); - } - return (null); - } - - - // Take the item out of the set and insert back to the front - // This is so that we can maintain MRU->LRU ordering - itemSet.remove(idx); - itemSet.addFirst(itemInfo); - - return itemInfo; - } - - /********************************************************************************************** - * AVAILABLE ITEMS - **********************************************************************************************/ - public ItemInfo getRandomAvailableItemId() { - return this.getRandomItem(this.items_available, false, false); + if (LOG.isDebugEnabled()) { + Map m = new HashMap<>(); + m.put(ItemStatus.OPEN, this.items_available.size()); + m.put(ItemStatus.ENDING_SOON, this.items_endingSoon.size()); + m.put(ItemStatus.WAITING_FOR_PURCHASE, this.items_waitingForPurchase.size()); + m.put(ItemStatus.CLOSED, this.items_completed.size()); + LOG.debug( + String.format("Updated Item Queues [%s]:\n%s", currentTime, StringUtil.formatMaps(m))); } - - public ItemInfo getRandomAvailableItem(boolean hasCurrentPrice) { - return this.getRandomItem(this.items_available, hasCurrentPrice, false); - } - - public int getAvailableItemsCount() { - return this.items_available.size(); - } - - /********************************************************************************************** - * ENDING SOON ITEMS - **********************************************************************************************/ - public ItemInfo getRandomEndingSoonItem() { - return this.getRandomItem(this.items_endingSoon, false, true); + } + + public ItemStatus addItemToProperQueue(ItemInfo itemInfo, boolean is_loader) { + // Calculate how much time is left for this auction + Timestamp baseTime = (is_loader ? this.getLoaderStartTime() : this.getCurrentTime()); + + return addItemToProperQueue(itemInfo, baseTime, null); + } + + private ItemStatus addItemToProperQueue( + ItemInfo itemInfo, Timestamp baseTime, Iterator currentQueueIterator) { + // Always check whether we even want it for this client + // The loader's profile and the cache profile will always have a negative client_id, + // which means that we always want to keep it + if (this.client_id != -1) { + if (this.userIdGenerator == null) { + this.initializeUserIdGenerator(this.client_id); + } + if (!this.userIdGenerator.checkClient(itemInfo.getSellerId())) { + return (null); + } } - public ItemInfo getRandomEndingSoonItem(boolean hasCurrentPrice) { - return this.getRandomItem(this.items_endingSoon, hasCurrentPrice, true); - } + long remaining = itemInfo.getEndDate().getTime() - baseTime.getTime(); - public int getEndingSoonItemsCount() { - return this.items_endingSoon.size(); - } + ItemStatus existingStatus = itemInfo.getStatus(); + ItemStatus new_status = (existingStatus != null ? existingStatus : ItemStatus.OPEN); - /********************************************************************************************** - * WAITING FOR PURCHASE ITEMS - **********************************************************************************************/ - public ItemInfo getRandomWaitForPurchaseItem() { - return this.getRandomItem(this.items_waitingForPurchase, false, false); + if (remaining <= 0) { + new_status = ItemStatus.CLOSED; + } else if (remaining < AuctionMarkConstants.ITEM_ENDING_SOON) { + new_status = ItemStatus.ENDING_SOON; + } else if (itemInfo.getNumBids() > 0 && existingStatus != ItemStatus.CLOSED) { + new_status = ItemStatus.WAITING_FOR_PURCHASE; } - public int getWaitForPurchaseItemsCount() { - return this.items_waitingForPurchase.size(); + if (!new_status.equals(existingStatus)) { + // Remove the item from the current queue + if (currentQueueIterator != null) { + currentQueueIterator.remove(); + } + + switch (new_status) { + case OPEN: + this.addItem(this.items_available, itemInfo); + break; + case ENDING_SOON: + this.addItem(this.items_endingSoon, itemInfo); + break; + case WAITING_FOR_PURCHASE: + this.addItem(this.items_waitingForPurchase, itemInfo); + break; + case CLOSED: + this.addItem(this.items_completed, itemInfo); + break; + default: + } + itemInfo.setStatus(new_status); } - /********************************************************************************************** - * COMPLETED ITEMS - **********************************************************************************************/ - public ItemInfo getRandomCompleteItem() { - return this.getRandomItem(this.items_completed, false, false); + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "%s - #%s [%s]", new_status, itemInfo.getItemId().encode(), itemInfo.getEndDate())); } - public int getCompleteItemsCount() { - return this.items_completed.size(); + return (new_status); + } + + /** + * @param itemSet + * @param needCurrentPrice + * @param needFutureEndDate TODO + * @return + */ + private ItemInfo getRandomItem( + LinkedList itemSet, boolean needCurrentPrice, boolean needFutureEndDate) { + Timestamp currentTime = this.updateAndGetCurrentTime(); + int num_items = itemSet.size(); + int idx = -1; + ItemInfo itemInfo = null; + + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Getting random ItemInfo [numItems=%d, currentTime=%s, needCurrentPrice=%s]", + num_items, currentTime, needCurrentPrice)); } + long tries = 1000; + tmp_seenItems.clear(); + while (num_items > 0 && tries-- > 0 && tmp_seenItems.size() < num_items) { + idx = this.rng.nextInt(num_items); + ItemInfo temp = itemSet.get(idx); + + if (tmp_seenItems.contains(temp)) { + continue; + } + tmp_seenItems.add(temp); + + // Needs to have an embedded currentPrice + if (needCurrentPrice && !temp.hasCurrentPrice()) { + continue; + } + + // If they want an item that is ending in the future, then we compare it with + // the current timestamp + if (needFutureEndDate) { + boolean compareTo = (temp.getEndDate().compareTo(currentTime) < 0); + if (LOG.isTraceEnabled()) { + LOG.trace( + "CurrentTime:{} / EndTime:{} [compareTo={}]", + currentTime, + temp.getEndDate(), + compareTo); + } + if (!temp.hasEndDate() || compareTo) { + continue; + } + } - /********************************************************************************************** - * ALL ITEMS - **********************************************************************************************/ - public int getAllItemsCount() { - return (this.getAvailableItemsCount() + - this.getEndingSoonItemsCount() + - this.getWaitForPurchaseItemsCount() + - this.getCompleteItemsCount()); + // Uniform + itemInfo = temp; + break; } - - public ItemInfo getRandomItem() { - - int idx = -1; - while (idx == -1 || allItemSets[idx].isEmpty()) { - idx = rng.nextInt(allItemSets.length); - } - return (this.getRandomItem(allItemSets[idx], false, false)); + if (itemInfo == null) { + if (LOG.isDebugEnabled()) { + LOG.debug( + "Failed to find ItemInfo [hasCurrentPrice={}, needFutureEndDate={}]", + needCurrentPrice, + needFutureEndDate); + } + return (null); } - // ---------------------------------------------------------------- - // GLOBAL ATTRIBUTE METHODS - // ---------------------------------------------------------------- - - /** - * Return a random GlobalAttributeValueId - * - * @return - */ - public GlobalAttributeValueId getRandomGlobalAttributeValue() { - int offset = rng.nextInt(this.gag_ids.size()); - GlobalAttributeGroupId gag_id = this.gag_ids.get(offset); - - int count = rng.nextInt(gag_id.getCount()); - return new GlobalAttributeValueId(gag_id, count); + // Take the item out of the set and insert back to the front + // This is so that we can maintain MRU->LRU ordering + itemSet.remove(idx); + itemSet.addFirst(itemInfo); + + return itemInfo; + } + + /********************************************************************************************** + * AVAILABLE ITEMS + **********************************************************************************************/ + public ItemInfo getRandomAvailableItemId() { + return this.getRandomItem(this.items_available, false, false); + } + + public ItemInfo getRandomAvailableItem(boolean hasCurrentPrice) { + return this.getRandomItem(this.items_available, hasCurrentPrice, false); + } + + public int getAvailableItemsCount() { + return this.items_available.size(); + } + + /********************************************************************************************** + * ENDING SOON ITEMS + **********************************************************************************************/ + public ItemInfo getRandomEndingSoonItem() { + return this.getRandomItem(this.items_endingSoon, false, true); + } + + public ItemInfo getRandomEndingSoonItem(boolean hasCurrentPrice) { + return this.getRandomItem(this.items_endingSoon, hasCurrentPrice, true); + } + + public int getEndingSoonItemsCount() { + return this.items_endingSoon.size(); + } + + /********************************************************************************************** + * WAITING FOR PURCHASE ITEMS + **********************************************************************************************/ + public ItemInfo getRandomWaitForPurchaseItem() { + return this.getRandomItem(this.items_waitingForPurchase, false, false); + } + + public int getWaitForPurchaseItemsCount() { + return this.items_waitingForPurchase.size(); + } + + /********************************************************************************************** + * COMPLETED ITEMS + **********************************************************************************************/ + public ItemInfo getRandomCompleteItem() { + return this.getRandomItem(this.items_completed, false, false); + } + + public int getCompleteItemsCount() { + return this.items_completed.size(); + } + + /********************************************************************************************** + * ALL ITEMS + **********************************************************************************************/ + public int getAllItemsCount() { + return (this.getAvailableItemsCount() + + this.getEndingSoonItemsCount() + + this.getWaitForPurchaseItemsCount() + + this.getCompleteItemsCount()); + } + + public ItemInfo getRandomItem() { + + int idx = -1; + while (idx == -1 || allItemSets[idx].isEmpty()) { + idx = rng.nextInt(allItemSets.length); } - - public int getRandomCategoryId() { - if (this.randomCategory == null) { - this.randomCategory = new FlatHistogram<>(this.rng, this.items_per_category); - } - return randomCategory.nextInt(); + return (this.getRandomItem(allItemSets[idx], false, false)); + } + + // ---------------------------------------------------------------- + // GLOBAL ATTRIBUTE METHODS + // ---------------------------------------------------------------- + + /** + * Return a random GlobalAttributeValueId + * + * @return + */ + public GlobalAttributeValueId getRandomGlobalAttributeValue() { + int offset = rng.nextInt(this.gag_ids.size()); + GlobalAttributeGroupId gag_id = this.gag_ids.get(offset); + + int count = rng.nextInt(gag_id.getCount()); + return new GlobalAttributeValueId(gag_id, count); + } + + public int getRandomCategoryId() { + if (this.randomCategory == null) { + this.randomCategory = new FlatHistogram<>(this.rng, this.items_per_category); } - - @Override - public String toString() { - Map m = new ListOrderedMap<>(); - m.put("Scale Factor", this.scale_factor); - m.put("Loader Start", this.loaderStartTime); - m.put("Loader Stop", this.loaderStopTime); - m.put("Last CloseAuctions", (this.lastCloseAuctionsTime.getTime() > 0 ? this.lastCloseAuctionsTime : null)); - m.put("Client Start", this.clientStartTime); - m.put("Current Virtual Time", this.currentTime); - m.put("Pending ItemCommentResponses", this.pending_commentResponses.size()); - - // Item Queues - Histogram itemCounts = new Histogram<>(true); - for (ItemStatus status : ItemStatus.values()) { - int cnt = 0; - switch (status) { - case OPEN: - cnt = this.items_available.size(); - break; - case ENDING_SOON: - cnt = this.items_endingSoon.size(); - break; - case WAITING_FOR_PURCHASE: - cnt = this.items_waitingForPurchase.size(); - break; - case CLOSED: - cnt = this.items_completed.size(); - break; - default: - - } - itemCounts.put(status, cnt); - } - m.put("Item Queues", itemCounts); - - return (StringUtil.formatMaps(m)); + return randomCategory.nextInt(); + } + + @Override + public String toString() { + Map m = new ListOrderedMap<>(); + m.put("Scale Factor", this.scale_factor); + m.put("Loader Start", this.loaderStartTime); + m.put("Loader Stop", this.loaderStopTime); + m.put( + "Last CloseAuctions", + (this.lastCloseAuctionsTime.getTime() > 0 ? this.lastCloseAuctionsTime : null)); + m.put("Client Start", this.clientStartTime); + m.put("Current Virtual Time", this.currentTime); + m.put("Pending ItemCommentResponses", this.pending_commentResponses.size()); + + // Item Queues + Histogram itemCounts = new Histogram<>(true); + for (ItemStatus status : ItemStatus.values()) { + int cnt = 0; + switch (status) { + case OPEN: + cnt = this.items_available.size(); + break; + case ENDING_SOON: + cnt = this.items_endingSoon.size(); + break; + case WAITING_FOR_PURCHASE: + cnt = this.items_waitingForPurchase.size(); + break; + case CLOSED: + cnt = this.items_completed.size(); + break; + default: + } + itemCounts.put(status, cnt); } + m.put("Item Queues", itemCounts); + return (StringUtil.formatMaps(m)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java index 55074346e..9d75a4a4a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/AuctionMarkWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark; import com.oltpbenchmark.api.Procedure; @@ -28,819 +27,869 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.*; import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class AuctionMarkWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkWorker.class); + private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkWorker.class); + + // ----------------------------------------------------------------- + // INTERNAL DATA MEMBERS + // ----------------------------------------------------------------- - // ----------------------------------------------------------------- - // INTERNAL DATA MEMBERS - // ----------------------------------------------------------------- + protected final AuctionMarkProfile profile; - protected final AuctionMarkProfile profile; + private final AtomicBoolean closeAuctions_flag = new AtomicBoolean(); - private final AtomicBoolean closeAuctions_flag = new AtomicBoolean(); + private final Thread closeAuctions_checker; - private final Thread closeAuctions_checker; + protected static final Map ip_id_cntrs = new HashMap<>(); - protected static final Map ip_id_cntrs = new HashMap<>(); + // -------------------------------------------------------------------- + // CLOSE_AUCTIONS CHECKER + // -------------------------------------------------------------------- + private class CloseAuctionsChecker extends Thread { + { + this.setDaemon(true); + } + + @Override + public void run() { + Thread.currentThread().setName(this.getClass().getSimpleName()); - // -------------------------------------------------------------------- - // CLOSE_AUCTIONS CHECKER - // -------------------------------------------------------------------- - private class CloseAuctionsChecker extends Thread { - { - this.setDaemon(true); + TransactionTypes txnTypes = AuctionMarkWorker.this.getWorkloadConfiguration().getTransTypes(); + TransactionType txnType = txnTypes.getType(CloseAuctions.class); + + Procedure proc = AuctionMarkWorker.this.getProcedure(txnType); + + long sleepTime = + AuctionMarkConstants.CLOSE_AUCTIONS_INTERVAL / AuctionMarkConstants.TIME_SCALE_FACTOR; + while (true) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Sleeping for %d seconds", sleepTime)); } - @Override - public void run() { - Thread.currentThread().setName(this.getClass().getSimpleName()); - - TransactionTypes txnTypes = AuctionMarkWorker.this.getWorkloadConfiguration().getTransTypes(); - TransactionType txnType = txnTypes.getType(CloseAuctions.class); - - - Procedure proc = AuctionMarkWorker.this.getProcedure(txnType); - - - long sleepTime = AuctionMarkConstants.CLOSE_AUCTIONS_INTERVAL / AuctionMarkConstants.TIME_SCALE_FACTOR; - while (true) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Sleeping for %d seconds", sleepTime)); - } - - // Always sleep until the next time that we need to check - try { - Thread.sleep(sleepTime * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - - if (AuctionMarkConstants.CLOSE_AUCTIONS_SEPARATE_THREAD) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Executing %s in separate thread", txnType)); - } - try (Connection conn = getBenchmark().makeConnection()) { - executeCloseAuctions(conn, (CloseAuctions) proc); - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } else { - AuctionMarkWorker.this.closeAuctions_flag.set(true); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Marked ready flag for %s", txnType)); - } - } - } + // Always sleep until the next time that we need to check + try { + Thread.sleep(sleepTime * AuctionMarkConstants.MILLISECONDS_IN_A_SECOND); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + + if (AuctionMarkConstants.CLOSE_AUCTIONS_SEPARATE_THREAD) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Executing %s in separate thread", txnType)); + } + try (Connection conn = getBenchmark().makeConnection()) { + executeCloseAuctions(conn, (CloseAuctions) proc); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } else { + AuctionMarkWorker.this.closeAuctions_flag.set(true); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Marked ready flag for %s", txnType)); + } } + } } + } - // -------------------------------------------------------------------- - // TXN PARAMETER GENERATOR - // -------------------------------------------------------------------- - public interface AuctionMarkParamGenerator { - /** - * Returns true if the client will be able to successfully generate a new transaction call - * The client passes in the current BenchmarkProfile handle and an optional VoltTable. This allows - * you to invoke one txn using the output of a previously run txn. - * Note that this is not thread safe, so you'll need to combine the call to this with generate() - * in a single synchronization block. - * - * @param client - * @return - */ - boolean canGenerateParam(AuctionMarkWorker client); - } - - // -------------------------------------------------------------------- - // BENCHMARK TRANSACTIONS - // -------------------------------------------------------------------- - public enum Transaction { - // ==================================================================== - // CloseAuctions - // ==================================================================== - CloseAuctions(CloseAuctions.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (false); // Use CloseAuctionsChecker - } + // -------------------------------------------------------------------- + // TXN PARAMETER GENERATOR + // -------------------------------------------------------------------- + public interface AuctionMarkParamGenerator { + /** + * Returns true if the client will be able to successfully generate a new transaction call The + * client passes in the current BenchmarkProfile handle and an optional VoltTable. This allows + * you to invoke one txn using the output of a previously run txn. Note that this is not thread + * safe, so you'll need to combine the call to this with generate() in a single synchronization + * block. + * + * @param client + * @return + */ + boolean canGenerateParam(AuctionMarkWorker client); + } + + // -------------------------------------------------------------------- + // BENCHMARK TRANSACTIONS + // -------------------------------------------------------------------- + public enum Transaction { + // ==================================================================== + // CloseAuctions + // ==================================================================== + CloseAuctions( + CloseAuctions.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (false); // Use CloseAuctionsChecker + } }), - // ==================================================================== - // GetItem - // ==================================================================== - GetItem(GetItem.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getAvailableItemsCount() > 0); - } + // ==================================================================== + // GetItem + // ==================================================================== + GetItem( + GetItem.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getAvailableItemsCount() > 0); + } }), - // ==================================================================== - // GetUserInfo - // ==================================================================== - GetUserInfo(GetUserInfo.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (true); - } + // ==================================================================== + // GetUserInfo + // ==================================================================== + GetUserInfo( + GetUserInfo.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (true); + } }), - // ==================================================================== - // NewBid - // ==================================================================== - NewBid(NewBid.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getAllItemsCount() > 0); - } + // ==================================================================== + // NewBid + // ==================================================================== + NewBid( + NewBid.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getAllItemsCount() > 0); + } }), - // ==================================================================== - // NewComment - // ==================================================================== - NewComment(NewComment.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getCompleteItemsCount() > 0); - } + // ==================================================================== + // NewComment + // ==================================================================== + NewComment( + NewComment.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getCompleteItemsCount() > 0); + } }), - // ==================================================================== - // NewCommentResponse - // ==================================================================== - NewCommentResponse(NewCommentResponse.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (!client.profile.pending_commentResponses.isEmpty()); - } + // ==================================================================== + // NewCommentResponse + // ==================================================================== + NewCommentResponse( + NewCommentResponse.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (!client.profile.pending_commentResponses.isEmpty()); + } }), - // ==================================================================== - // NewFeedback - // ==================================================================== - NewFeedback(NewFeedback.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getCompleteItemsCount() > 0); - } + // ==================================================================== + // NewFeedback + // ==================================================================== + NewFeedback( + NewFeedback.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getCompleteItemsCount() > 0); + } }), - // ==================================================================== - // NewItem - // ==================================================================== - NewItem(NewItem.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (true); - } + // ==================================================================== + // NewItem + // ==================================================================== + NewItem( + NewItem.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (true); + } }), - // ==================================================================== - // NewPurchase - // ==================================================================== - NewPurchase(NewPurchase.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getWaitForPurchaseItemsCount() > 0); - } + // ==================================================================== + // NewPurchase + // ==================================================================== + NewPurchase( + NewPurchase.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getWaitForPurchaseItemsCount() > 0); + } }), - // ==================================================================== - // UpdateItem - // ==================================================================== - UpdateItem(UpdateItem.class, new AuctionMarkParamGenerator() { - @Override - public boolean canGenerateParam(AuctionMarkWorker client) { - return (client.profile.getAvailableItemsCount() > 0); - } + // ==================================================================== + // UpdateItem + // ==================================================================== + UpdateItem( + UpdateItem.class, + new AuctionMarkParamGenerator() { + @Override + public boolean canGenerateParam(AuctionMarkWorker client) { + return (client.profile.getAvailableItemsCount() > 0); + } }), - ; - - /** - * Constructor - * - * @param procClass - * @param generator - */ - Transaction(Class procClass, AuctionMarkParamGenerator generator) { - this.procClass = procClass; - this.generator = generator; - } - - public final Class procClass; - public final AuctionMarkParamGenerator generator; - - protected static final Map, Transaction> class_lookup = new HashMap<>(); - protected static final Map idx_lookup = new HashMap<>(); - protected static final Map name_lookup = new HashMap<>(); - - static { - for (Transaction vt : EnumSet.allOf(Transaction.class)) { - Transaction.idx_lookup.put(vt.ordinal(), vt); - Transaction.name_lookup.put(vt.name(), vt); - Transaction.class_lookup.put(vt.procClass, vt); - } - } - - public static Transaction get(Class clazz) { - return (Transaction.class_lookup.get(clazz)); - } - - /** - * This will return true if we can call a new transaction for this procedure - * A txn can be called if we can generate all of the parameters we need - * - * @return - */ - public boolean canExecute(AuctionMarkWorker client) { - if (LOG.isDebugEnabled()) { - LOG.debug("Checking whether we can execute {} now", this); - } - return this.generator.canGenerateParam(client); - } - } - - // ----------------------------------------------------------------- - // REQUIRED METHODS - // ----------------------------------------------------------------- + ; /** * Constructor * - * @param id - * @param benchmark + * @param procClass + * @param generator */ - public AuctionMarkWorker(int id, AuctionMarkBenchmark benchmark) { - super(benchmark, id); - this.profile = new AuctionMarkProfile(benchmark, benchmark.getRandomGenerator()); - - boolean needCloseAuctions = (AuctionMarkConstants.CLOSE_AUCTIONS_ENABLE && id == 0); - this.closeAuctions_flag.set(needCloseAuctions); - if (needCloseAuctions) { - this.closeAuctions_checker = new CloseAuctionsChecker(); - } else { - this.closeAuctions_checker = null; - } + Transaction(Class procClass, AuctionMarkParamGenerator generator) { + this.procClass = procClass; + this.generator = generator; } - protected AuctionMarkProfile getProfile() { - return (this.profile); - } + public final Class procClass; + public final AuctionMarkParamGenerator generator; - @Override - protected void initialize() { - // Load BenchmarkProfile - try { - profile.loadProfile(this); - } catch (SQLException ex) { - throw new RuntimeException("Failed to initialize AuctionMarkWorker", ex); - } - if (this.closeAuctions_checker != null) { - this.closeAuctions_checker.start(); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("AuctionMarkProfile %03d\n%s", this.getId(), profile)); - } - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException { - // We need to subtract the different between this and the profile's start time, - // since that accounts for the time gap between when the loader started and when the client start. - // Otherwise, all of our cache date will be out dated if it took a really long time - // to load everything up. Again, in order to keep things in synch, we only want to - // set this on the first call to runOnce(). This will account for start a bunch of - // clients on multiple nodes but then having to wait until they're all up and running - // before starting the actual benchmark run. - if (!profile.hasClientStartTime()) { - profile.setAndGetClientStartTime(); - } - - // Always update the current timestamp - profile.updateAndGetCurrentTime(); + protected static final Map, Transaction> class_lookup = + new HashMap<>(); + protected static final Map idx_lookup = new HashMap<>(); + protected static final Map name_lookup = new HashMap<>(); - Transaction txn = null; - - // Always check if we need to want to run CLOSE_AUCTIONS - // We only do this from the first client - if (!AuctionMarkConstants.CLOSE_AUCTIONS_SEPARATE_THREAD && - closeAuctions_flag.compareAndSet(true, false)) { - txn = Transaction.CloseAuctions; - TransactionTypes txnTypes = this.getWorkloadConfiguration().getTransTypes(); - txnType = txnTypes.getType(txn.procClass); - - } else { - txn = Transaction.get(txnType.getProcedureClass()); - if (!txn.canExecute(this)) { - LOG.trace("Unable to execute {} because it is not ready. Will RETRY_DIFFERENT.", txn); - return (TransactionStatus.RETRY_DIFFERENT); - } - } - - // Get the Procedure handle - Procedure proc = this.getProcedure(txnType); - - if (LOG.isTraceEnabled()) { - LOG.trace("{} -> {} -> {} -> {}", txnType, txn, txnType.getProcedureClass(), proc); - } - - boolean ret = false; - switch (txn) { - case CloseAuctions: - ret = executeCloseAuctions(conn, (CloseAuctions) proc); - break; - case GetItem: - ret = executeGetItem(conn, (GetItem) proc); - break; - case GetUserInfo: - ret = executeGetUserInfo(conn, (GetUserInfo) proc); - break; - case NewBid: - ret = executeNewBid(conn, (NewBid) proc); - break; - case NewComment: - ret = executeNewComment(conn, (NewComment) proc); - break; - case NewCommentResponse: - ret = executeNewCommentResponse(conn, (NewCommentResponse) proc); - break; - case NewFeedback: - ret = executeNewFeedback(conn, (NewFeedback) proc); - break; - case NewItem: - ret = executeNewItem(conn, (NewItem) proc); - break; - case NewPurchase: - ret = executeNewPurchase(conn, (NewPurchase) proc); - break; - case UpdateItem: - ret = executeUpdateItem(conn, (UpdateItem) proc); - break; - default: - - } - - if (ret && LOG.isDebugEnabled()) { - LOG.debug("Executed a new invocation of {}", txn); - } + static { + for (Transaction vt : EnumSet.allOf(Transaction.class)) { + Transaction.idx_lookup.put(vt.ordinal(), vt); + Transaction.name_lookup.put(vt.name(), vt); + Transaction.class_lookup.put(vt.procClass, vt); + } + } - return (TransactionStatus.SUCCESS); + public static Transaction get(Class clazz) { + return (Transaction.class_lookup.get(clazz)); } /** - * For the given VoltTable that contains ITEM records, process the current - * row of that table and update the benchmark profile based on item information - * stored in that row. + * This will return true if we can call a new transaction for this procedure A txn can be called + * if we can generate all of the parameters we need * - * @param row * @return - * @see CloseAuctions - * @see GetItem - * @see GetUserInfo - * @see NewBid - * @see NewItem - * @see NewPurchase */ - public ItemId processItemRecord(Object[] row) { - int col = 0; - ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id - String i_u_id = SQLUtil.getString(row[col++]); // i_u_id - assert i_u_id != null; - @SuppressWarnings("unused") - String i_name = (String) row[col++]; // i_name - double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price - long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids - Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]);// i_end_date - if (i_end_date == null) { - LOG.warn("end date is null: {} / {} expected timestamp or date", row[col - 1], row[col - 1].getClass()); - } - - Long temp = SQLUtil.getLong(row[col++]); - - if (temp == null) { - LOG.warn("status is null: {} / {} expected Long", row[col - 1], row[col - 1].getClass()); - - ItemStatus i_status = ItemStatus.get(temp); // i_status - - ItemInfo itemInfo = new ItemInfo(i_id, i_current_price, i_end_date, (int) i_num_bids); - itemInfo.setStatus(i_status); - - profile.addItemToProperQueue(itemInfo, false); - } - - - return (i_id); + public boolean canExecute(AuctionMarkWorker client) { + if (LOG.isDebugEnabled()) { + LOG.debug("Checking whether we can execute {} now", this); + } + return this.generator.canGenerateParam(client); } - - public Timestamp[] getTimestampParameterArray() { - return new Timestamp[]{profile.getLoaderStartTime(), - profile.getClientStartTime()}; + } + + // ----------------------------------------------------------------- + // REQUIRED METHODS + // ----------------------------------------------------------------- + + /** + * Constructor + * + * @param id + * @param benchmark + */ + public AuctionMarkWorker(int id, AuctionMarkBenchmark benchmark) { + super(benchmark, id); + this.profile = new AuctionMarkProfile(benchmark, benchmark.getRandomGenerator()); + + boolean needCloseAuctions = (AuctionMarkConstants.CLOSE_AUCTIONS_ENABLE && id == 0); + this.closeAuctions_flag.set(needCloseAuctions); + if (needCloseAuctions) { + this.closeAuctions_checker = new CloseAuctionsChecker(); + } else { + this.closeAuctions_checker = null; } - - // ---------------------------------------------------------------- - // CLOSE_AUCTIONS - // ---------------------------------------------------------------- - - protected boolean executeCloseAuctions(Connection conn, CloseAuctions proc) throws SQLException { - if (LOG.isDebugEnabled()) { - LOG.debug("Executing {}", proc); - } - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - Timestamp startTime = Timestamp.from(profile.getLastCloseAuctionsTime().toInstant()); - Timestamp endTime = Timestamp.from(profile.updateAndGetLastCloseAuctionsTime().toInstant()); - - List results = proc.run(conn, benchmarkTimes, startTime, endTime); - - - for (Object[] row : results) { - ItemId itemId = this.processItemRecord(row); - assert itemId != null; - } - profile.updateItemQueues(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Finished {}", proc); - } - return (true); + } + + protected AuctionMarkProfile getProfile() { + return (this.profile); + } + + @Override + protected void initialize() { + // Load BenchmarkProfile + try { + profile.loadProfile(this); + } catch (SQLException ex) { + throw new RuntimeException("Failed to initialize AuctionMarkWorker", ex); } - - // ---------------------------------------------------------------- - // GetItem - // ---------------------------------------------------------------- - - protected boolean executeGetItem(Connection conn, GetItem proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = profile.getRandomAvailableItemId(); - - Object[][] results = proc.run(conn, benchmarkTimes, itemInfo.getItemId().encode(), - itemInfo.getSellerId().encode()); - - // The first row will have our item data that we want - // We don't care about the user information... - ItemId itemId = this.processItemRecord(results[0]); - assert itemId != null; - - return (true); + if (this.closeAuctions_checker != null) { + this.closeAuctions_checker.start(); + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("AuctionMarkProfile %03d\n%s", this.getId(), profile)); + } + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException { + // We need to subtract the different between this and the profile's start time, + // since that accounts for the time gap between when the loader started and when the client + // start. + // Otherwise, all of our cache date will be out dated if it took a really long time + // to load everything up. Again, in order to keep things in synch, we only want to + // set this on the first call to runOnce(). This will account for start a bunch of + // clients on multiple nodes but then having to wait until they're all up and running + // before starting the actual benchmark run. + if (!profile.hasClientStartTime()) { + profile.setAndGetClientStartTime(); } - // ---------------------------------------------------------------- - // GetUserInfo - // ---------------------------------------------------------------- - - protected boolean executeGetUserInfo(Connection conn, GetUserInfo proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - UserId userId = profile.getRandomBuyerId(); - int rand; + // Always update the current timestamp + profile.updateAndGetCurrentTime(); + + Transaction txn = null; + + // Always check if we need to want to run CLOSE_AUCTIONS + // We only do this from the first client + if (!AuctionMarkConstants.CLOSE_AUCTIONS_SEPARATE_THREAD + && closeAuctions_flag.compareAndSet(true, false)) { + txn = Transaction.CloseAuctions; + TransactionTypes txnTypes = this.getWorkloadConfiguration().getTransTypes(); + txnType = txnTypes.getType(txn.procClass); + + } else { + txn = Transaction.get(txnType.getProcedureClass()); + if (!txn.canExecute(this)) { + LOG.trace("Unable to execute {} because it is not ready. Will RETRY_DIFFERENT.", txn); + return (TransactionStatus.RETRY_DIFFERENT); + } + } - // USER_FEEDBACK records - rand = profile.rng.number(0, 100); - boolean get_feedback = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_FEEDBACK); + // Get the Procedure handle + Procedure proc = this.getProcedure(txnType); - // ITEM_COMMENT records - rand = profile.rng.number(0, 100); - boolean get_comments = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_COMMENTS); + if (LOG.isTraceEnabled()) { + LOG.trace("{} -> {} -> {} -> {}", txnType, txn, txnType.getProcedureClass(), proc); + } - // Seller ITEM records - rand = profile.rng.number(0, 100); - boolean get_seller_items = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_SELLER_ITEMS); + boolean ret = false; + switch (txn) { + case CloseAuctions: + ret = executeCloseAuctions(conn, (CloseAuctions) proc); + break; + case GetItem: + ret = executeGetItem(conn, (GetItem) proc); + break; + case GetUserInfo: + ret = executeGetUserInfo(conn, (GetUserInfo) proc); + break; + case NewBid: + ret = executeNewBid(conn, (NewBid) proc); + break; + case NewComment: + ret = executeNewComment(conn, (NewComment) proc); + break; + case NewCommentResponse: + ret = executeNewCommentResponse(conn, (NewCommentResponse) proc); + break; + case NewFeedback: + ret = executeNewFeedback(conn, (NewFeedback) proc); + break; + case NewItem: + ret = executeNewItem(conn, (NewItem) proc); + break; + case NewPurchase: + ret = executeNewPurchase(conn, (NewPurchase) proc); + break; + case UpdateItem: + ret = executeUpdateItem(conn, (UpdateItem) proc); + break; + default: + } - // Buyer ITEM records - rand = profile.rng.number(0, 100); - boolean get_buyer_items = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_BUYER_ITEMS); + if (ret && LOG.isDebugEnabled()) { + LOG.debug("Executed a new invocation of {}", txn); + } - // USER_WATCH records - rand = profile.rng.number(0, 100); - boolean get_watched_items = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_WATCHED_ITEMS); + return (TransactionStatus.SUCCESS); + } + + /** + * For the given VoltTable that contains ITEM records, process the current row of that table and + * update the benchmark profile based on item information stored in that row. + * + * @param row + * @return + * @see CloseAuctions + * @see GetItem + * @see GetUserInfo + * @see NewBid + * @see NewItem + * @see NewPurchase + */ + public ItemId processItemRecord(Object[] row) { + int col = 0; + ItemId i_id = new ItemId(SQLUtil.getString(row[col++])); // i_id + String i_u_id = SQLUtil.getString(row[col++]); // i_u_id + assert i_u_id != null; + @SuppressWarnings("unused") + String i_name = (String) row[col++]; // i_name + double i_current_price = SQLUtil.getDouble(row[col++]); // i_current_price + long i_num_bids = SQLUtil.getLong(row[col++]); // i_num_bids + Timestamp i_end_date = SQLUtil.getTimestamp(row[col++]); // i_end_date + if (i_end_date == null) { + LOG.warn( + "end date is null: {} / {} expected timestamp or date", + row[col - 1], + row[col - 1].getClass()); + } - UserInfo results = proc.run(conn, benchmarkTimes, userId.encode(), - get_feedback, - get_comments, - get_seller_items, - get_buyer_items, - get_watched_items); + Long temp = SQLUtil.getLong(row[col++]); + if (temp == null) { + LOG.warn("status is null: {} / {} expected Long", row[col - 1], row[col - 1].getClass()); - // ITEM_COMMENTS - if (get_comments) { + ItemStatus i_status = ItemStatus.get(temp); // i_status - for (Object[] row : results.getItemComments()) { - String itemId = SQLUtil.getString(row[0]); - String sellerId = SQLUtil.getString(row[1]); - long commentId = SQLUtil.getLong(row[7]); + ItemInfo itemInfo = new ItemInfo(i_id, i_current_price, i_end_date, (int) i_num_bids); + itemInfo.setStatus(i_status); - ItemCommentResponse cr = new ItemCommentResponse(commentId, itemId, sellerId); - profile.addPendingItemCommentResponse(cr); + profile.addItemToProperQueue(itemInfo, false); + } - } - } + return (i_id); + } - for (Object[] row : results.getSellerItems()) { - ItemId itemId = this.processItemRecord(row); - assert itemId != null; - } + public Timestamp[] getTimestampParameterArray() { + return new Timestamp[] {profile.getLoaderStartTime(), profile.getClientStartTime()}; + } - for (Object[] row : results.getBuyerItems()) { - ItemId itemId = this.processItemRecord(row); - assert itemId != null; - } + // ---------------------------------------------------------------- + // CLOSE_AUCTIONS + // ---------------------------------------------------------------- - for (Object[] row : results.getWatchedItems()) { - ItemId itemId = this.processItemRecord(row); - assert itemId != null; - } + protected boolean executeCloseAuctions(Connection conn, CloseAuctions proc) throws SQLException { + if (LOG.isDebugEnabled()) { + LOG.debug("Executing {}", proc); + } + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + Timestamp startTime = Timestamp.from(profile.getLastCloseAuctionsTime().toInstant()); + Timestamp endTime = Timestamp.from(profile.updateAndGetLastCloseAuctionsTime().toInstant()); + List results = proc.run(conn, benchmarkTimes, startTime, endTime); - return (true); + for (Object[] row : results) { + ItemId itemId = this.processItemRecord(row); + assert itemId != null; } + profile.updateItemQueues(); - // ---------------------------------------------------------------- - // NewBid - // ---------------------------------------------------------------- - - protected boolean executeNewBid(Connection conn, NewBid proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = null; - UserId sellerId; - UserId buyerId; - double bid; - double maxBid; - - boolean has_available = (profile.getAvailableItemsCount() > 0); - boolean has_ending = (profile.getEndingSoonItemsCount() > 0); - boolean has_waiting = (profile.getWaitForPurchaseItemsCount() > 0); - boolean has_completed = (profile.getCompleteItemsCount() > 0); - - // Some NewBids will be for items that have already ended. - // This will simulate somebody trying to bid at the very end but failing - if ((has_waiting || has_completed) && - (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_NEWBID_CLOSED_ITEM || !has_available)) { - if (has_waiting) { - itemInfo = profile.getRandomWaitForPurchaseItem(); - - } else { - itemInfo = profile.getRandomCompleteItem(); - - } - sellerId = itemInfo.getSellerId(); - buyerId = profile.getRandomBuyerId(sellerId); - - // The bid/maxBid do not matter because they won't be able to actually - // update the auction - bid = profile.rng.nextDouble(); - maxBid = bid + 100; - } - - // Otherwise we want to generate information for a real bid - else { - - // 50% of NewBids will be for items that are ending soon - if ((has_ending && profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_NEWBID_CLOSED_ITEM) || !has_available) { - itemInfo = profile.getRandomEndingSoonItem(true); - } - if (itemInfo == null) { - itemInfo = profile.getRandomAvailableItem(true); - } - if (itemInfo == null) { - itemInfo = profile.getRandomItem(); - } - - sellerId = itemInfo.getSellerId(); - buyerId = profile.getRandomBuyerId(sellerId); - - double currentPrice = itemInfo.getCurrentPrice(); - bid = profile.rng.fixedPoint(2, currentPrice, currentPrice * (1 + (AuctionMarkConstants.ITEM_BID_PERCENT_STEP / 2))); - maxBid = profile.rng.fixedPoint(2, bid, (bid * (1 + (AuctionMarkConstants.ITEM_BID_PERCENT_STEP / 2)))); - } + if (LOG.isDebugEnabled()) { + LOG.debug("Finished {}", proc); + } + return (true); + } + + // ---------------------------------------------------------------- + // GetItem + // ---------------------------------------------------------------- + + protected boolean executeGetItem(Connection conn, GetItem proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = profile.getRandomAvailableItemId(); + + Object[][] results = + proc.run( + conn, benchmarkTimes, itemInfo.getItemId().encode(), itemInfo.getSellerId().encode()); + + // The first row will have our item data that we want + // We don't care about the user information... + ItemId itemId = this.processItemRecord(results[0]); + assert itemId != null; + + return (true); + } + + // ---------------------------------------------------------------- + // GetUserInfo + // ---------------------------------------------------------------- + + protected boolean executeGetUserInfo(Connection conn, GetUserInfo proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + UserId userId = profile.getRandomBuyerId(); + int rand; + + // USER_FEEDBACK records + rand = profile.rng.number(0, 100); + boolean get_feedback = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_FEEDBACK); + + // ITEM_COMMENT records + rand = profile.rng.number(0, 100); + boolean get_comments = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_COMMENTS); + + // Seller ITEM records + rand = profile.rng.number(0, 100); + boolean get_seller_items = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_SELLER_ITEMS); + + // Buyer ITEM records + rand = profile.rng.number(0, 100); + boolean get_buyer_items = (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_BUYER_ITEMS); + + // USER_WATCH records + rand = profile.rng.number(0, 100); + boolean get_watched_items = + (rand <= AuctionMarkConstants.PROB_GETUSERINFO_INCLUDE_WATCHED_ITEMS); + + UserInfo results = + proc.run( + conn, + benchmarkTimes, + userId.encode(), + get_feedback, + get_comments, + get_seller_items, + get_buyer_items, + get_watched_items); + + // ITEM_COMMENTS + if (get_comments) { + + for (Object[] row : results.getItemComments()) { + String itemId = SQLUtil.getString(row[0]); + String sellerId = SQLUtil.getString(row[1]); + long commentId = SQLUtil.getLong(row[7]); + + ItemCommentResponse cr = new ItemCommentResponse(commentId, itemId, sellerId); + profile.addPendingItemCommentResponse(cr); + } + } - Object[] results = proc.run(conn, benchmarkTimes, itemInfo.getItemId().encode(), - sellerId.encode(), - buyerId.encode(), - maxBid, - itemInfo.getEndDate()); + for (Object[] row : results.getSellerItems()) { + ItemId itemId = this.processItemRecord(row); + assert itemId != null; + } - ItemId itemId = this.processItemRecord(results); - assert itemId != null; + for (Object[] row : results.getBuyerItems()) { + ItemId itemId = this.processItemRecord(row); + assert itemId != null; + } - return (true); + for (Object[] row : results.getWatchedItems()) { + ItemId itemId = this.processItemRecord(row); + assert itemId != null; } - // ---------------------------------------------------------------- - // NewComment - // ---------------------------------------------------------------- + return (true); + } + + // ---------------------------------------------------------------- + // NewBid + // ---------------------------------------------------------------- + + protected boolean executeNewBid(Connection conn, NewBid proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = null; + UserId sellerId; + UserId buyerId; + double bid; + double maxBid; + + boolean has_available = (profile.getAvailableItemsCount() > 0); + boolean has_ending = (profile.getEndingSoonItemsCount() > 0); + boolean has_waiting = (profile.getWaitForPurchaseItemsCount() > 0); + boolean has_completed = (profile.getCompleteItemsCount() > 0); + + // Some NewBids will be for items that have already ended. + // This will simulate somebody trying to bid at the very end but failing + if ((has_waiting || has_completed) + && (profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_NEWBID_CLOSED_ITEM + || !has_available)) { + if (has_waiting) { + itemInfo = profile.getRandomWaitForPurchaseItem(); + + } else { + itemInfo = profile.getRandomCompleteItem(); + } + sellerId = itemInfo.getSellerId(); + buyerId = profile.getRandomBuyerId(sellerId); + + // The bid/maxBid do not matter because they won't be able to actually + // update the auction + bid = profile.rng.nextDouble(); + maxBid = bid + 100; + } - protected boolean executeNewComment(Connection conn, NewComment proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = profile.getRandomCompleteItem(); - UserId sellerId = itemInfo.getSellerId(); - UserId buyerId = profile.getRandomBuyerId(sellerId); - String question = profile.rng.astring(AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, - AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + // Otherwise we want to generate information for a real bid + else { + + // 50% of NewBids will be for items that are ending soon + if ((has_ending && profile.rng.number(1, 100) <= AuctionMarkConstants.PROB_NEWBID_CLOSED_ITEM) + || !has_available) { + itemInfo = profile.getRandomEndingSoonItem(true); + } + if (itemInfo == null) { + itemInfo = profile.getRandomAvailableItem(true); + } + if (itemInfo == null) { + itemInfo = profile.getRandomItem(); + } + + sellerId = itemInfo.getSellerId(); + buyerId = profile.getRandomBuyerId(sellerId); + + double currentPrice = itemInfo.getCurrentPrice(); + bid = + profile.rng.fixedPoint( + 2, + currentPrice, + currentPrice * (1 + (AuctionMarkConstants.ITEM_BID_PERCENT_STEP / 2))); + maxBid = + profile.rng.fixedPoint( + 2, bid, (bid * (1 + (AuctionMarkConstants.ITEM_BID_PERCENT_STEP / 2)))); + } - Object[] results = proc.run(conn, benchmarkTimes, - itemInfo.getItemId().encode(), - sellerId.encode(), - buyerId.encode(), - question); + Object[] results = + proc.run( + conn, + benchmarkTimes, + itemInfo.getItemId().encode(), + sellerId.encode(), + buyerId.encode(), + maxBid, + itemInfo.getEndDate()); + + ItemId itemId = this.processItemRecord(results); + assert itemId != null; + + return (true); + } + + // ---------------------------------------------------------------- + // NewComment + // ---------------------------------------------------------------- + + protected boolean executeNewComment(Connection conn, NewComment proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = profile.getRandomCompleteItem(); + UserId sellerId = itemInfo.getSellerId(); + UserId buyerId = profile.getRandomBuyerId(sellerId); + String question = + profile.rng.astring( + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + + Object[] results = + proc.run( + conn, + benchmarkTimes, + itemInfo.getItemId().encode(), + sellerId.encode(), + buyerId.encode(), + question); + + profile.pending_commentResponses.add( + new ItemCommentResponse( + SQLUtil.getLong(results[0]), + SQLUtil.getString(results[1]), + SQLUtil.getString(results[2]))); + return (true); + } + + // ---------------------------------------------------------------- + // NewCommentResponse + // ---------------------------------------------------------------- + + protected boolean executeNewCommentResponse(Connection conn, NewCommentResponse proc) + throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + int idx = profile.rng.nextInt(profile.pending_commentResponses.size()); + ItemCommentResponse cr = profile.pending_commentResponses.remove(idx); + + long commentId = cr.getCommentId(); + ItemId itemId = new ItemId(cr.getItemId()); + UserId sellerId = itemId.getSellerId(); + + String response = + profile.rng.astring( + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, + AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + + proc.run(conn, benchmarkTimes, itemId.encode(), sellerId.encode(), commentId, response); + + return (true); + } + + // ---------------------------------------------------------------- + // NewFeedback + // ---------------------------------------------------------------- + + protected boolean executeNewFeedback(Connection conn, NewFeedback proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = profile.getRandomCompleteItem(); + UserId sellerId = itemInfo.getSellerId(); + UserId buyerId = profile.getRandomBuyerId(sellerId); + long rating = profile.rng.number(-1, 1); + String feedback = profile.rng.astring(10, 80); + + String user_id; + String from_id; + if (profile.rng.nextBoolean()) { + user_id = sellerId.encode(); + from_id = buyerId.encode(); + } else { + user_id = buyerId.encode(); + from_id = sellerId.encode(); + } + proc.run( + conn, + benchmarkTimes, + user_id, + itemInfo.getItemId().encode(), + sellerId.encode(), + from_id, + rating, + feedback); + + return (true); + } + + // ---------------------------------------------------------------- + // NewItem + // ---------------------------------------------------------------- + + protected boolean executeNewItem(Connection conn, NewItem proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + UserId sellerId = profile.getRandomSellerId(this.getId()); + ItemId itemId = profile.getNextItemId(sellerId); + + String name = profile.rng.astring(6, 32); + String description = profile.rng.astring(50, 255); + long categoryId = profile.getRandomCategoryId(); + + double initial_price = profile.randomInitialPrice.nextInt(); + String attributes = profile.rng.astring(50, 255); + + int numAttributes = profile.randomNumAttributes.nextInt(); + List gavList = new ArrayList<>(numAttributes); + for (int i = 0; i < numAttributes; i++) { + GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); + if (!gavList.contains(gav_id)) { + gavList.add(gav_id); + } + } - profile.pending_commentResponses.add(new ItemCommentResponse(SQLUtil.getLong(results[0]), - SQLUtil.getString(results[1]), - SQLUtil.getString(results[2]))); - return (true); + String[] gag_ids = new String[gavList.size()]; + String[] gav_ids = new String[gavList.size()]; + for (int i = 0, cnt = gag_ids.length; i < cnt; i++) { + GlobalAttributeValueId gav_id = gavList.get(i); + gag_ids[i] = gav_id.getGlobalAttributeGroup().encode(); + gav_ids[i] = gav_id.encode(); } - // ---------------------------------------------------------------- - // NewCommentResponse - // ---------------------------------------------------------------- + int numImages = profile.randomNumImages.nextInt(); + String[] images = new String[numImages]; + for (int i = 0; i < numImages; i++) { + images[i] = profile.rng.astring(20, 100); + } - protected boolean executeNewCommentResponse(Connection conn, NewCommentResponse proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - int idx = profile.rng.nextInt(profile.pending_commentResponses.size()); - ItemCommentResponse cr = profile.pending_commentResponses.remove(idx); + long duration = profile.randomDuration.nextInt(); + + Object[] results = null; + try { + String itemIdEncoded = itemId.encode(); + results = + proc.run( + conn, + benchmarkTimes, + itemIdEncoded, + sellerId.encode(), + categoryId, + name, + description, + duration, + initial_price, + attributes, + gag_ids, + gav_ids, + images); + } catch (DuplicateItemIdException ex) { + profile.seller_item_cnt.set(sellerId, ex.getItemCount()); + LOG.warn( + "a duplicate item existed; i believe this error should be handled differently.: " + + ex.getMessage()); + throw ex; + } + itemId = this.processItemRecord(results); - long commentId = cr.getCommentId(); - ItemId itemId = new ItemId(cr.getItemId()); - UserId sellerId = itemId.getSellerId(); + return (true); + } - String response = profile.rng.astring(AuctionMarkConstants.ITEM_COMMENT_LENGTH_MIN, - AuctionMarkConstants.ITEM_COMMENT_LENGTH_MAX); + // ---------------------------------------------------------------- + // NewPurchase + // ---------------------------------------------------------------- - proc.run(conn, benchmarkTimes, itemId.encode(), - sellerId.encode(), - commentId, - response); + protected boolean executeNewPurchase(Connection conn, NewPurchase proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = profile.getRandomWaitForPurchaseItem(); + String encodedItemId = itemInfo.getItemId().encode(); + UserId sellerId = itemInfo.getSellerId(); + double buyer_credit = 0d; - return (true); + Integer ip_id_cnt = ip_id_cntrs.get(encodedItemId); + if (ip_id_cnt == null) { + ip_id_cnt = 0; } - // ---------------------------------------------------------------- - // NewFeedback - // ---------------------------------------------------------------- - - protected boolean executeNewFeedback(Connection conn, NewFeedback proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = profile.getRandomCompleteItem(); - UserId sellerId = itemInfo.getSellerId(); - UserId buyerId = profile.getRandomBuyerId(sellerId); - long rating = profile.rng.number(-1, 1); - String feedback = profile.rng.astring(10, 80); - - String user_id; - String from_id; - if (profile.rng.nextBoolean()) { - user_id = sellerId.encode(); - from_id = buyerId.encode(); - } else { - user_id = buyerId.encode(); - from_id = sellerId.encode(); - } - - proc.run(conn, benchmarkTimes, user_id, - itemInfo.getItemId().encode(), - sellerId.encode(), - from_id, - rating, - feedback); - - return (true); + String ip_id = AuctionMarkUtil.getUniqueElementId(encodedItemId, ip_id_cnt); + ip_id_cntrs.put(encodedItemId, (ip_id_cnt < 127) ? ip_id_cnt + 1 : 0); + + // Whether the buyer will not have enough money + if (itemInfo.hasCurrentPrice()) { + if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_NEWPURCHASE_NOT_ENOUGH_MONEY) { + buyer_credit = -1 * itemInfo.getCurrentPrice(); + } else { + buyer_credit = itemInfo.getCurrentPrice(); + itemInfo.setStatus(ItemStatus.CLOSED); + } } - // ---------------------------------------------------------------- - // NewItem - // ---------------------------------------------------------------- - - protected boolean executeNewItem(Connection conn, NewItem proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - UserId sellerId = profile.getRandomSellerId(this.getId()); - ItemId itemId = profile.getNextItemId(sellerId); - - String name = profile.rng.astring(6, 32); - String description = profile.rng.astring(50, 255); - long categoryId = profile.getRandomCategoryId(); - - double initial_price = profile.randomInitialPrice.nextInt(); - String attributes = profile.rng.astring(50, 255); - - int numAttributes = profile.randomNumAttributes.nextInt(); - List gavList = new ArrayList<>(numAttributes); - for (int i = 0; i < numAttributes; i++) { - GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); - if (!gavList.contains(gav_id)) { - gavList.add(gav_id); - } - } + Object[] results = + proc.run(conn, benchmarkTimes, encodedItemId, sellerId.encode(), ip_id, buyer_credit); - String[] gag_ids = new String[gavList.size()]; - String[] gav_ids = new String[gavList.size()]; - for (int i = 0, cnt = gag_ids.length; i < cnt; i++) { - GlobalAttributeValueId gav_id = gavList.get(i); - gag_ids[i] = gav_id.getGlobalAttributeGroup().encode(); - gav_ids[i] = gav_id.encode(); - } + ItemId itemId = this.processItemRecord(results); + assert itemId != null; - int numImages = profile.randomNumImages.nextInt(); - String[] images = new String[numImages]; - for (int i = 0; i < numImages; i++) { - images[i] = profile.rng.astring(20, 100); - } + return (true); + } - long duration = profile.randomDuration.nextInt(); + // ---------------------------------------------------------------- + // UpdateItem + // ---------------------------------------------------------------- - Object[] results = null; - try { - String itemIdEncoded = itemId.encode(); - results = proc.run(conn, benchmarkTimes, itemIdEncoded, sellerId.encode(), - categoryId, name, description, - duration, initial_price, attributes, - gag_ids, gav_ids, images); - } catch (DuplicateItemIdException ex) { - profile.seller_item_cnt.set(sellerId, ex.getItemCount()); - LOG.warn("a duplicate item existed; i believe this error should be handled differently.: " + ex.getMessage()); - throw ex; - } + protected boolean executeUpdateItem(Connection conn, UpdateItem proc) throws SQLException { + Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); + ItemInfo itemInfo = profile.getRandomAvailableItemId(); + UserId sellerId = itemInfo.getSellerId(); + String description = profile.rng.astring(50, 255); - itemId = this.processItemRecord(results); + boolean delete_attribute = false; + String[] add_attribute = {"-1", "-1"}; - - return (true); + // Delete ITEM_ATTRIBUTE + if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_UPDATEITEM_DELETE_ATTRIBUTE) { + delete_attribute = true; } + // Add ITEM_ATTRIBUTE + else if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_UPDATEITEM_ADD_ATTRIBUTE) { + GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); - // ---------------------------------------------------------------- - // NewPurchase - // ---------------------------------------------------------------- - - protected boolean executeNewPurchase(Connection conn, NewPurchase proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = profile.getRandomWaitForPurchaseItem(); - String encodedItemId = itemInfo.getItemId().encode(); - UserId sellerId = itemInfo.getSellerId(); - double buyer_credit = 0d; - - Integer ip_id_cnt = ip_id_cntrs.get(encodedItemId); - if (ip_id_cnt == null) { - ip_id_cnt = 0; - } - - String ip_id = AuctionMarkUtil.getUniqueElementId(encodedItemId, - ip_id_cnt); - ip_id_cntrs.put(encodedItemId, (ip_id_cnt < 127) ? ip_id_cnt + 1 : 0); - - // Whether the buyer will not have enough money - if (itemInfo.hasCurrentPrice()) { - if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_NEWPURCHASE_NOT_ENOUGH_MONEY) { - buyer_credit = -1 * itemInfo.getCurrentPrice(); - } else { - buyer_credit = itemInfo.getCurrentPrice(); - itemInfo.setStatus(ItemStatus.CLOSED); - } - } - - Object[] results = proc.run(conn, benchmarkTimes, encodedItemId, - sellerId.encode(), - ip_id, - buyer_credit); - - ItemId itemId = this.processItemRecord(results); - assert itemId != null; - - return (true); + add_attribute[0] = gav_id.getGlobalAttributeGroup().encode(); + add_attribute[1] = gav_id.encode(); } - // ---------------------------------------------------------------- - // UpdateItem - // ---------------------------------------------------------------- - - protected boolean executeUpdateItem(Connection conn, UpdateItem proc) throws SQLException { - Timestamp[] benchmarkTimes = this.getTimestampParameterArray(); - ItemInfo itemInfo = profile.getRandomAvailableItemId(); - UserId sellerId = itemInfo.getSellerId(); - String description = profile.rng.astring(50, 255); - - boolean delete_attribute = false; - String[] add_attribute = { - "-1", - "-1" - }; - - // Delete ITEM_ATTRIBUTE - if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_UPDATEITEM_DELETE_ATTRIBUTE) { - delete_attribute = true; - } - // Add ITEM_ATTRIBUTE - else if (profile.rng.number(1, 100) < AuctionMarkConstants.PROB_UPDATEITEM_ADD_ATTRIBUTE) { - GlobalAttributeValueId gav_id = profile.getRandomGlobalAttributeValue(); - - add_attribute[0] = gav_id.getGlobalAttributeGroup().encode(); - add_attribute[1] = gav_id.encode(); - } - - proc.run(conn, benchmarkTimes, itemInfo.getItemId().encode(), - sellerId.encode(), - description, - delete_attribute, - add_attribute); - - return (true); - } + proc.run( + conn, + benchmarkTimes, + itemInfo.getItemId().encode(), + sellerId.encode(), + description, + delete_attribute, + add_attribute); + + return (true); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/exceptions/DuplicateItemIdException.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/exceptions/DuplicateItemIdException.java index 2e8bc6599..3469d741d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/exceptions/DuplicateItemIdException.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/exceptions/DuplicateItemIdException.java @@ -20,34 +20,34 @@ import com.oltpbenchmark.api.Procedure.UserAbortException; public class DuplicateItemIdException extends UserAbortException { - private static final long serialVersionUID = -667971163586760142L; + private static final long serialVersionUID = -667971163586760142L; - private final String item_id; - private final String seller_id; - private final int item_count; + private final String item_id; + private final String seller_id; + private final int item_count; - public DuplicateItemIdException(String item_id, String seller_id, int item_count, Exception cause) { - super(String.format("Duplicate ItemId [%s] for Seller [%s]", item_id, seller_id), cause); + public DuplicateItemIdException( + String item_id, String seller_id, int item_count, Exception cause) { + super(String.format("Duplicate ItemId [%s] for Seller [%s]", item_id, seller_id), cause); - this.item_id = item_id; - this.seller_id = seller_id; - this.item_count = item_count; - } + this.item_id = item_id; + this.seller_id = seller_id; + this.item_count = item_count; + } - public DuplicateItemIdException(String item_id, String seller_id, int item_count) { - this(item_id, seller_id, item_count, null); - } + public DuplicateItemIdException(String item_id, String seller_id, int item_count) { + this(item_id, seller_id, item_count, null); + } - public String getItemId() { - return this.item_id; - } + public String getItemId() { + return this.item_id; + } - public String getSellerId() { - return this.seller_id; - } - - public int getItemCount() { - return this.item_count; - } + public String getSellerId() { + return this.seller_id; + } + public int getItemCount() { + return this.item_count; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/CloseAuctions.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/CloseAuctions.java index a04aedefd..706c5054f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/CloseAuctions.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/CloseAuctions.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,12 +22,11 @@ import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.*; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * PostAuction @@ -37,161 +35,175 @@ * @author visawee */ public class CloseAuctions extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(CloseAuctions.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getDueItems = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + " " + - "WHERE (i_start_date BETWEEN ? AND ?) " + - "AND i_status = ? " + - "ORDER BY i_id ASC " + - "LIMIT " + AuctionMarkConstants.CLOSE_AUCTIONS_ITEMS_PER_ROUND - ); - - public final SQLStmt getMaxBid = new SQLStmt( - "SELECT imb_ib_id, ib_buyer_id " + - "FROM " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + ", " + - AuctionMarkConstants.TABLENAME_ITEM_BID + - " WHERE imb_i_id = ? AND imb_u_id = ? " + - "AND ib_id = imb_ib_id AND ib_i_id = imb_i_id AND ib_u_id = imb_u_id " - ); - - public final SQLStmt updateItemStatus = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + " " + - "SET i_status = ?, " + - " i_updated = ? " + - "WHERE i_id = ? AND i_u_id = ? " - ); - - public final SQLStmt insertUserItem = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + "(" + - "ui_u_id, " + - "ui_i_id, " + - "ui_i_u_id, " + - "ui_created" + - ") VALUES(?, ?, ?, ?)" - ); - - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- - - public List run(Connection conn, Timestamp[] benchmarkTimes, - Timestamp startTime, Timestamp endTime) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - final boolean debug = LOG.isDebugEnabled(); - - if (debug) { - LOG.debug(String.format("startTime=%s, endTime=%s, currentTime=%s", - startTime, endTime, currentTime)); - } + private static final Logger LOG = LoggerFactory.getLogger(CloseAuctions.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getDueItems = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " " + + "WHERE (i_start_date BETWEEN ? AND ?) " + + "AND i_status = ? " + + "ORDER BY i_id ASC " + + "LIMIT " + + AuctionMarkConstants.CLOSE_AUCTIONS_ITEMS_PER_ROUND); + + public final SQLStmt getMaxBid = + new SQLStmt( + "SELECT imb_ib_id, ib_buyer_id " + + "FROM " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + ", " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " WHERE imb_i_id = ? AND imb_u_id = ? " + + "AND ib_id = imb_ib_id AND ib_i_id = imb_i_id AND ib_u_id = imb_u_id "); + + public final SQLStmt updateItemStatus = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " " + + "SET i_status = ?, " + + " i_updated = ? " + + "WHERE i_id = ? AND i_u_id = ? "); + + public final SQLStmt insertUserItem = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + + "(" + + "ui_u_id, " + + "ui_i_id, " + + "ui_i_u_id, " + + "ui_created" + + ") VALUES(?, ?, ?, ?)"); + + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- + + public List run( + Connection conn, Timestamp[] benchmarkTimes, Timestamp startTime, Timestamp endTime) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + final boolean debug = LOG.isDebugEnabled(); + + if (debug) { + LOG.debug( + String.format( + "startTime=%s, endTime=%s, currentTime=%s", startTime, endTime, currentTime)); + } - int closed_ctr = 0; - int waiting_ctr = 0; - int round = AuctionMarkConstants.CLOSE_AUCTIONS_ROUNDS; - int col = -1; - int param = -1; - - final List output_rows = new ArrayList<>(); - - try (PreparedStatement dueItemsStmt = this.getPreparedStatement(conn, getDueItems); - PreparedStatement maxBidStmt = this.getPreparedStatement(conn, getMaxBid)) { - - - while (round-- > 0) { - param = 1; - dueItemsStmt.setTimestamp(param++, startTime); - dueItemsStmt.setTimestamp(param++, endTime); - dueItemsStmt.setInt(param++, ItemStatus.OPEN.ordinal()); - try (ResultSet dueItemsTable = dueItemsStmt.executeQuery()) { - boolean adv = dueItemsTable.next(); - if (!adv) { - break; - } - - output_rows.clear(); - while (dueItemsTable.next()) { - col = 1; - String itemId = dueItemsTable.getString(col++); - String sellerId = dueItemsTable.getString(col++); - String i_name = dueItemsTable.getString(col++); - double currentPrice = dueItemsTable.getDouble(col++); - long numBids = dueItemsTable.getLong(col++); - Timestamp endDate = dueItemsTable.getTimestamp(col++); - ItemStatus itemStatus = ItemStatus.get(dueItemsTable.getLong(col++)); - Long bidId = null; - String buyerId = null; - - if (debug) { - LOG.debug(String.format("Getting max bid for itemId=%d / sellerId=%d", itemId, sellerId)); - } - - - // Has bid on this item - set status to WAITING_FOR_PURCHASE - // We'll also insert a new USER_ITEM record as needed - // We have to do this extra step because H-Store doesn't have good support in the - // query optimizer for LEFT OUTER JOINs - if (numBids > 0) { - waiting_ctr++; - - param = 1; - maxBidStmt.setString(param++, itemId); - maxBidStmt.setString(param++, sellerId); - try (ResultSet maxBidResults = maxBidStmt.executeQuery()) { - adv = maxBidResults.next(); - - - col = 1; - bidId = maxBidResults.getLong(col++); - buyerId = maxBidResults.getString(col++); - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertUserItem, buyerId, itemId, sellerId, currentTime)) { - preparedStatement.executeUpdate(); - } - - itemStatus = ItemStatus.WAITING_FOR_PURCHASE; - } - } - // No bid on this item - set status to CLOSED - else { - closed_ctr++; - itemStatus = ItemStatus.CLOSED; - } - - // Update Status! - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItemStatus, itemStatus.ordinal(), currentTime, itemId, sellerId)) { - preparedStatement.executeUpdate(); - } - if (debug) { - LOG.debug(String.format("Updated Status for Item %d => %s", itemId, itemStatus)); - } - - Object[] row = new Object[]{ - itemId, // i_id - sellerId, // i_u_id - i_name, // i_name - currentPrice, // i_current_price - numBids, // i_num_bids - endDate, // i_end_date - itemStatus.ordinal(), // i_status - bidId, // imb_ib_id - buyerId // ib_buyer_id - }; - output_rows.add(row); - } - } + int closed_ctr = 0; + int waiting_ctr = 0; + int round = AuctionMarkConstants.CLOSE_AUCTIONS_ROUNDS; + int col = -1; + int param = -1; + + final List output_rows = new ArrayList<>(); + + try (PreparedStatement dueItemsStmt = this.getPreparedStatement(conn, getDueItems); + PreparedStatement maxBidStmt = this.getPreparedStatement(conn, getMaxBid)) { + + while (round-- > 0) { + param = 1; + dueItemsStmt.setTimestamp(param++, startTime); + dueItemsStmt.setTimestamp(param++, endTime); + dueItemsStmt.setInt(param++, ItemStatus.OPEN.ordinal()); + try (ResultSet dueItemsTable = dueItemsStmt.executeQuery()) { + boolean adv = dueItemsTable.next(); + if (!adv) { + break; + } + + output_rows.clear(); + while (dueItemsTable.next()) { + col = 1; + String itemId = dueItemsTable.getString(col++); + String sellerId = dueItemsTable.getString(col++); + String i_name = dueItemsTable.getString(col++); + double currentPrice = dueItemsTable.getDouble(col++); + long numBids = dueItemsTable.getLong(col++); + Timestamp endDate = dueItemsTable.getTimestamp(col++); + ItemStatus itemStatus = ItemStatus.get(dueItemsTable.getLong(col++)); + Long bidId = null; + String buyerId = null; + + if (debug) { + LOG.debug( + String.format("Getting max bid for itemId=%d / sellerId=%d", itemId, sellerId)); } + // Has bid on this item - set status to WAITING_FOR_PURCHASE + // We'll also insert a new USER_ITEM record as needed + // We have to do this extra step because H-Store doesn't have good support in the + // query optimizer for LEFT OUTER JOINs + if (numBids > 0) { + waiting_ctr++; + + param = 1; + maxBidStmt.setString(param++, itemId); + maxBidStmt.setString(param++, sellerId); + try (ResultSet maxBidResults = maxBidStmt.executeQuery()) { + adv = maxBidResults.next(); + + col = 1; + bidId = maxBidResults.getLong(col++); + buyerId = maxBidResults.getString(col++); + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, insertUserItem, buyerId, itemId, sellerId, currentTime)) { + preparedStatement.executeUpdate(); + } - } + itemStatus = ItemStatus.WAITING_FOR_PURCHASE; + } + } + // No bid on this item - set status to CLOSED + else { + closed_ctr++; + itemStatus = ItemStatus.CLOSED; + } - if (debug) { - LOG.debug(String.format("Updated Auctions - Closed=%d / Waiting=%d", closed_ctr, waiting_ctr)); + // Update Status! + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, updateItemStatus, itemStatus.ordinal(), currentTime, itemId, sellerId)) { + preparedStatement.executeUpdate(); + } + if (debug) { + LOG.debug(String.format("Updated Status for Item %d => %s", itemId, itemStatus)); + } + + Object[] row = + new Object[] { + itemId, // i_id + sellerId, // i_u_id + i_name, // i_name + currentPrice, // i_current_price + numBids, // i_num_bids + endDate, // i_end_date + itemStatus.ordinal(), // i_status + bidId, // imb_ib_id + buyerId // ib_buyer_id + }; + output_rows.add(row); + } } + } + } - return (output_rows); + if (debug) { + LOG.debug( + String.format("Updated Auctions - Closed=%d / Waiting=%d", closed_ctr, waiting_ctr)); } + + return (output_rows); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/Config.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/Config.java index d4f5aec29..631b458b4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/Config.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/Config.java @@ -4,49 +4,56 @@ public class Config { - private final List configProfile; - private final List categoryCounts; - private final List attributes; - private final List pendingComments; - private final List openItems; - private final List waitingForPurchaseItems; - private final List closedItems; - - public Config(List configProfile, List categoryCounts, List attributes, List pendingComments, List openItems, List waitingForPurchaseItems, List closedItems) { - this.configProfile = configProfile; - this.categoryCounts = categoryCounts; - this.attributes = attributes; - this.pendingComments = pendingComments; - this.openItems = openItems; - this.waitingForPurchaseItems = waitingForPurchaseItems; - this.closedItems = closedItems; - } - - public List getConfigProfile() { - return configProfile; - } - - public List getCategoryCounts() { - return categoryCounts; - } - - public List getAttributes() { - return attributes; - } - - public List getPendingComments() { - return pendingComments; - } - - public List getOpenItems() { - return openItems; - } - - public List getWaitingForPurchaseItems() { - return waitingForPurchaseItems; - } - - public List getClosedItems() { - return closedItems; - } + private final List configProfile; + private final List categoryCounts; + private final List attributes; + private final List pendingComments; + private final List openItems; + private final List waitingForPurchaseItems; + private final List closedItems; + + public Config( + List configProfile, + List categoryCounts, + List attributes, + List pendingComments, + List openItems, + List waitingForPurchaseItems, + List closedItems) { + this.configProfile = configProfile; + this.categoryCounts = categoryCounts; + this.attributes = attributes; + this.pendingComments = pendingComments; + this.openItems = openItems; + this.waitingForPurchaseItems = waitingForPurchaseItems; + this.closedItems = closedItems; + } + + public List getConfigProfile() { + return configProfile; + } + + public List getCategoryCounts() { + return categoryCounts; + } + + public List getAttributes() { + return attributes; + } + + public List getPendingComments() { + return pendingComments; + } + + public List getOpenItems() { + return openItems; + } + + public List getWaitingForPurchaseItems() { + return waitingForPurchaseItems; + } + + public List getClosedItems() { + return closedItems; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetItem.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetItem.java index f9bc9cd00..402e02f00 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetItem.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetItem.java @@ -15,69 +15,71 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.util.SQLUtil; - import java.sql.*; /** - * Get Item Information - * Returns all of the attributes for a particular item + * Get Item Information Returns all of the attributes for a particular item * * @author pavlo */ public class GetItem extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- - public final SQLStmt getItem = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + - " WHERE i_id = ? AND i_u_id = ?" - ); + public final SQLStmt getItem = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " WHERE i_id = ? AND i_u_id = ?"); - public final SQLStmt getUser = new SQLStmt( - "SELECT u_id, u_rating, u_created, u_sattr0, u_sattr1, u_sattr2, u_sattr3, u_sattr4, r_name " + - " FROM " + AuctionMarkConstants.TABLENAME_USERACCT + ", " + - AuctionMarkConstants.TABLENAME_REGION + - " WHERE u_id = ? AND u_r_id = r_id" - ); + public final SQLStmt getUser = + new SQLStmt( + "SELECT u_id, u_rating, u_created, u_sattr0, u_sattr1, u_sattr2, u_sattr3, u_sattr4, r_name " + + " FROM " + + AuctionMarkConstants.TABLENAME_USERACCT + + ", " + + AuctionMarkConstants.TABLENAME_REGION + + " WHERE u_id = ? AND u_r_id = r_id"); - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- - public Object[][] run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id) throws SQLException { + public Object[][] run( + Connection conn, Timestamp[] benchmarkTimes, String item_id, String seller_id) + throws SQLException { - Object[] item_row = null; - try (PreparedStatement item_stmt = this.getPreparedStatement(conn, getItem, item_id, seller_id)) { - try (ResultSet item_results = item_stmt.executeQuery()) { - if (!item_results.next()) { - throw new UserAbortException("Invalid item " + item_id); - } - item_row = SQLUtil.getRowAsArray(item_results); - } + Object[] item_row = null; + try (PreparedStatement item_stmt = + this.getPreparedStatement(conn, getItem, item_id, seller_id)) { + try (ResultSet item_results = item_stmt.executeQuery()) { + if (!item_results.next()) { + throw new UserAbortException("Invalid item " + item_id); } + item_row = SQLUtil.getRowAsArray(item_results); + } + } - Object[] user_row = null; - try (PreparedStatement user_stmt = this.getPreparedStatement(conn, getUser, seller_id)) { - try (ResultSet user_results = user_stmt.executeQuery()) { - if (!user_results.next()) { - throw new UserAbortException("Invalid user id " + seller_id); - } - user_row = SQLUtil.getRowAsArray(user_results); - } + Object[] user_row = null; + try (PreparedStatement user_stmt = this.getPreparedStatement(conn, getUser, seller_id)) { + try (ResultSet user_results = user_stmt.executeQuery()) { + if (!user_results.next()) { + throw new UserAbortException("Invalid user id " + seller_id); } - - return (new Object[][]{item_row, user_row}); + user_row = SQLUtil.getRowAsArray(user_results); + } } + return (new Object[][] {item_row, user_row}); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetUserInfo.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetUserInfo.java index 364f0a2a6..35d6191df 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetUserInfo.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/GetUserInfo.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,12 +22,11 @@ import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.*; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * GetUserInfo @@ -37,171 +35,188 @@ * @author visawee */ public class GetUserInfo extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(GetUserInfo.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getUser = new SQLStmt( - "SELECT u_id, u_rating, u_created, u_balance, u_sattr0, u_sattr1, u_sattr2, u_sattr3, u_sattr4, r_name " + - "FROM " + AuctionMarkConstants.TABLENAME_USERACCT + ", " + - AuctionMarkConstants.TABLENAME_REGION + " " + - "WHERE u_id = ? AND u_r_id = r_id" - ); - - public final SQLStmt getUserFeedback = new SQLStmt( - "SELECT u_id, u_rating, u_sattr0, u_sattr1, uf_rating, uf_date, uf_sattr0 " + - " FROM " + AuctionMarkConstants.TABLENAME_USERACCT + ", " + - AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + - " WHERE u_id = ? AND uf_u_id = u_id " + - " ORDER BY uf_date DESC LIMIT 25 " - ); - - public final SQLStmt getItemComments = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + ", " + - " ic_id, ic_i_id, ic_u_id, ic_buyer_id, ic_question, ic_created " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + ", " + - AuctionMarkConstants.TABLENAME_ITEM_COMMENT + - " WHERE i_u_id = ? AND i_status = ? " + - " AND i_id = ic_i_id AND i_u_id = ic_u_id AND ic_response IS NULL " + - " ORDER BY ic_created DESC LIMIT 25 " - ); - - public final SQLStmt getSellerItems = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + " " + - "WHERE i_u_id = ? " + - "ORDER BY i_end_date DESC LIMIT 25 " - ); - - public final SQLStmt getBuyerItems = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + - " FROM " + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + ", " + - AuctionMarkConstants.TABLENAME_ITEM + - " WHERE ui_u_id = ? " + - "AND ui_i_id = i_id AND ui_i_u_id = i_u_id " + - "ORDER BY i_end_date DESC LIMIT 25 " - ); - - public final SQLStmt getWatchedItems = new SQLStmt( - "SELECT " + AuctionMarkConstants.ITEM_COLUMNS_STR + ", uw_u_id, uw_created " + - "FROM " + AuctionMarkConstants.TABLENAME_USERACCT_WATCH + ", " + - AuctionMarkConstants.TABLENAME_ITEM + - " WHERE uw_u_id = ? " + - " AND uw_i_id = i_id AND uw_i_u_id = i_u_id " + - " ORDER BY i_end_date DESC LIMIT 25" - ); - - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- - - /** - * @param conn - * @param benchmarkTimes - * @param user_id - * @param get_feedback - * @param get_comments - * @param get_seller_items - * @param get_buyer_items - * @param get_watched_items - * @return - * @throws SQLException - */ - public UserInfo run(Connection conn, Timestamp[] benchmarkTimes, - String user_id, - boolean get_feedback, - boolean get_comments, - boolean get_seller_items, - boolean get_buyer_items, - boolean get_watched_items) throws SQLException { - final boolean debug = LOG.isDebugEnabled(); - - - // The first VoltTable in the output will always be the user's information - if (debug) { - LOG.debug("Grabbing USER record: {}", user_id); - } - - List user = new ArrayList<>(); - - try (PreparedStatement stmt = this.getPreparedStatement(conn, getUser, user_id); - ResultSet rs = stmt.executeQuery()) { - user = SQLUtil.toList(rs); - } - - // They can also get their USER_FEEDBACK records if they want as well - List userFeedback = new ArrayList<>(); - if (get_feedback) { - if (debug) { - LOG.debug("Grabbing USER_FEEDBACK records: {}", user_id); - } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getUserFeedback, user_id); - ResultSet rs = stmt.executeQuery()) { - userFeedback = SQLUtil.toList(rs); - } - } - - - // And any pending ITEM_COMMENTS that need a response - List itemComments = new ArrayList<>(); - if (get_comments) { - if (debug) { - LOG.debug("Grabbing ITEM_COMMENT records: {}", user_id); - } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getItemComments, user_id, ItemStatus.OPEN.ordinal()); - ResultSet rs = stmt.executeQuery()) { - itemComments = SQLUtil.toList(rs); - } - } - - - // The seller's items - List sellerItems = new ArrayList<>(); - if (get_seller_items) { - if (debug) { - LOG.debug("Grabbing seller's ITEM records: {}", user_id); - } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSellerItems, user_id); - ResultSet rs = stmt.executeQuery()) { - sellerItems = SQLUtil.toList(rs); - } - } - - - // The buyer's purchased items - List buyerItems = new ArrayList<>(); - if (get_buyer_items) { - // 2010-11-15: The distributed query planner chokes on this one and makes a plan - // that basically sends the entire user table to all nodes. So for now we'll just execute - // the query to grab the buyer's feedback information - // this.getPreparedStatement(conn, select_seller_feedback, u_id); - if (debug) { - LOG.debug("Grabbing buyer's USER_ITEM records: {}", user_id); - } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getBuyerItems, user_id); - ResultSet rs = stmt.executeQuery()) { - buyerItems = SQLUtil.toList(rs); - } - } - - - // The buyer's watched items - - List watchedItems = new ArrayList<>(); - if (get_watched_items) { - if (debug) { - LOG.debug("Grabbing buyer's USER_WATCH records: {}", user_id); - } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getWatchedItems, user_id); - ResultSet rs = stmt.executeQuery()) { - - watchedItems = SQLUtil.toList(rs); - } - } - - - return new UserInfo(user, userFeedback, itemComments, sellerItems, buyerItems, watchedItems); + private static final Logger LOG = LoggerFactory.getLogger(GetUserInfo.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getUser = + new SQLStmt( + "SELECT u_id, u_rating, u_created, u_balance, u_sattr0, u_sattr1, u_sattr2, u_sattr3, u_sattr4, r_name " + + "FROM " + + AuctionMarkConstants.TABLENAME_USERACCT + + ", " + + AuctionMarkConstants.TABLENAME_REGION + + " " + + "WHERE u_id = ? AND u_r_id = r_id"); + + public final SQLStmt getUserFeedback = + new SQLStmt( + "SELECT u_id, u_rating, u_sattr0, u_sattr1, uf_rating, uf_date, uf_sattr0 " + + " FROM " + + AuctionMarkConstants.TABLENAME_USERACCT + + ", " + + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + + " WHERE u_id = ? AND uf_u_id = u_id " + + " ORDER BY uf_date DESC LIMIT 25 "); + + public final SQLStmt getItemComments = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + ", " + + " ic_id, ic_i_id, ic_u_id, ic_buyer_id, ic_question, ic_created " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + ", " + + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + + " WHERE i_u_id = ? AND i_status = ? " + + " AND i_id = ic_i_id AND i_u_id = ic_u_id AND ic_response IS NULL " + + " ORDER BY ic_created DESC LIMIT 25 "); + + public final SQLStmt getSellerItems = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " " + + "WHERE i_u_id = ? " + + "ORDER BY i_end_date DESC LIMIT 25 "); + + public final SQLStmt getBuyerItems = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + " FROM " + + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + + ", " + + AuctionMarkConstants.TABLENAME_ITEM + + " WHERE ui_u_id = ? " + + "AND ui_i_id = i_id AND ui_i_u_id = i_u_id " + + "ORDER BY i_end_date DESC LIMIT 25 "); + + public final SQLStmt getWatchedItems = + new SQLStmt( + "SELECT " + + AuctionMarkConstants.ITEM_COLUMNS_STR + + ", uw_u_id, uw_created " + + "FROM " + + AuctionMarkConstants.TABLENAME_USERACCT_WATCH + + ", " + + AuctionMarkConstants.TABLENAME_ITEM + + " WHERE uw_u_id = ? " + + " AND uw_i_id = i_id AND uw_i_u_id = i_u_id " + + " ORDER BY i_end_date DESC LIMIT 25"); + + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- + + /** + * @param conn + * @param benchmarkTimes + * @param user_id + * @param get_feedback + * @param get_comments + * @param get_seller_items + * @param get_buyer_items + * @param get_watched_items + * @return + * @throws SQLException + */ + public UserInfo run( + Connection conn, + Timestamp[] benchmarkTimes, + String user_id, + boolean get_feedback, + boolean get_comments, + boolean get_seller_items, + boolean get_buyer_items, + boolean get_watched_items) + throws SQLException { + final boolean debug = LOG.isDebugEnabled(); + + // The first VoltTable in the output will always be the user's information + if (debug) { + LOG.debug("Grabbing USER record: {}", user_id); + } + + List user = new ArrayList<>(); + + try (PreparedStatement stmt = this.getPreparedStatement(conn, getUser, user_id); + ResultSet rs = stmt.executeQuery()) { + user = SQLUtil.toList(rs); + } + + // They can also get their USER_FEEDBACK records if they want as well + List userFeedback = new ArrayList<>(); + if (get_feedback) { + if (debug) { + LOG.debug("Grabbing USER_FEEDBACK records: {}", user_id); + } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getUserFeedback, user_id); + ResultSet rs = stmt.executeQuery()) { + userFeedback = SQLUtil.toList(rs); + } } -} \ No newline at end of file + + // And any pending ITEM_COMMENTS that need a response + List itemComments = new ArrayList<>(); + if (get_comments) { + if (debug) { + LOG.debug("Grabbing ITEM_COMMENT records: {}", user_id); + } + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getItemComments, user_id, ItemStatus.OPEN.ordinal()); + ResultSet rs = stmt.executeQuery()) { + itemComments = SQLUtil.toList(rs); + } + } + + // The seller's items + List sellerItems = new ArrayList<>(); + if (get_seller_items) { + if (debug) { + LOG.debug("Grabbing seller's ITEM records: {}", user_id); + } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSellerItems, user_id); + ResultSet rs = stmt.executeQuery()) { + sellerItems = SQLUtil.toList(rs); + } + } + + // The buyer's purchased items + List buyerItems = new ArrayList<>(); + if (get_buyer_items) { + // 2010-11-15: The distributed query planner chokes on this one and makes a plan + // that basically sends the entire user table to all nodes. So for now we'll just execute + // the query to grab the buyer's feedback information + // this.getPreparedStatement(conn, select_seller_feedback, u_id); + if (debug) { + LOG.debug("Grabbing buyer's USER_ITEM records: {}", user_id); + } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getBuyerItems, user_id); + ResultSet rs = stmt.executeQuery()) { + buyerItems = SQLUtil.toList(rs); + } + } + + // The buyer's watched items + + List watchedItems = new ArrayList<>(); + if (get_watched_items) { + if (debug) { + LOG.debug("Grabbing buyer's USER_WATCH records: {}", user_id); + } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getWatchedItems, user_id); + ResultSet rs = stmt.executeQuery()) { + + watchedItems = SQLUtil.toList(rs); + } + } + + return new UserInfo(user, userFeedback, itemComments, sellerItems, buyerItems, watchedItems); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/LoadConfig.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/LoadConfig.java index 8e724f0f5..830b95cdf 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/LoadConfig.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/LoadConfig.java @@ -23,7 +23,6 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -32,117 +31,131 @@ public class LoadConfig extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getConfigProfile = new SQLStmt( - "SELECT * FROM " + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE - ); - - public final SQLStmt getCategoryCounts = new SQLStmt( - "SELECT i_c_id, COUNT(i_id) FROM " + AuctionMarkConstants.TABLENAME_ITEM + - " GROUP BY i_c_id" - ); - - public final SQLStmt getAttributes = new SQLStmt( - "SELECT gag_id FROM " + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP - ); - - public final SQLStmt getPendingComments = new SQLStmt( - "SELECT ic_id, ic_i_id, ic_u_id, ic_buyer_id " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + - " WHERE ic_response IS NULL" - ); - - public final SQLStmt getPastItems = new SQLStmt( - "SELECT i_id, i_current_price, i_end_date, i_num_bids, i_status " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + ", " + - AuctionMarkConstants.TABLENAME_CONFIG_PROFILE + - " WHERE i_status = ? AND i_end_date <= cfp_loader_start " + - " ORDER BY i_end_date ASC " + - " LIMIT " + AuctionMarkConstants.ITEM_LOADCONFIG_LIMIT - ); - - public final SQLStmt getFutureItems = new SQLStmt( - "SELECT i_id, i_current_price, i_end_date, i_num_bids, i_status " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + ", " + - AuctionMarkConstants.TABLENAME_CONFIG_PROFILE + - " WHERE i_status = ? AND i_end_date > cfp_loader_start " + - " ORDER BY i_end_date ASC " + - " LIMIT " + AuctionMarkConstants.ITEM_LOADCONFIG_LIMIT - ); - - // ----------------------------------------------------------------- - // RUN - // ----------------------------------------------------------------- - - public Config run(Connection conn) throws SQLException { - - - List configProfile; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getConfigProfile)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - configProfile = SQLUtil.toList(resultSet); - // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). - // These CLOB needs to be converted to String while the connection is alive. - - // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be attempted - // by SQLUtil.getString(Object) after the connection closes, which will result in - // java.sql.SQLRecoverableException: Closed Connection. - if (getDbType() == DatabaseType.ORACLE) { - for (Object[] configProfileInstance: configProfile) { - configProfileInstance[3] = SQLUtil.clobToString(configProfileInstance[3]); - } - } - } - } - - List categoryCounts; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getCategoryCounts)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - categoryCounts = SQLUtil.toList(resultSet); - } + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getConfigProfile = + new SQLStmt("SELECT * FROM " + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE); + + public final SQLStmt getCategoryCounts = + new SQLStmt( + "SELECT i_c_id, COUNT(i_id) FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " GROUP BY i_c_id"); + + public final SQLStmt getAttributes = + new SQLStmt("SELECT gag_id FROM " + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP); + + public final SQLStmt getPendingComments = + new SQLStmt( + "SELECT ic_id, ic_i_id, ic_u_id, ic_buyer_id " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + + " WHERE ic_response IS NULL"); + + public final SQLStmt getPastItems = + new SQLStmt( + "SELECT i_id, i_current_price, i_end_date, i_num_bids, i_status " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + ", " + + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE + + " WHERE i_status = ? AND i_end_date <= cfp_loader_start " + + " ORDER BY i_end_date ASC " + + " LIMIT " + + AuctionMarkConstants.ITEM_LOADCONFIG_LIMIT); + + public final SQLStmt getFutureItems = + new SQLStmt( + "SELECT i_id, i_current_price, i_end_date, i_num_bids, i_status " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + ", " + + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE + + " WHERE i_status = ? AND i_end_date > cfp_loader_start " + + " ORDER BY i_end_date ASC " + + " LIMIT " + + AuctionMarkConstants.ITEM_LOADCONFIG_LIMIT); + + // ----------------------------------------------------------------- + // RUN + // ----------------------------------------------------------------- + + public Config run(Connection conn) throws SQLException { + + List configProfile; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getConfigProfile)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + configProfile = SQLUtil.toList(resultSet); + // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). + // These CLOB needs to be converted to String while the connection is alive. + + // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be + // attempted + // by SQLUtil.getString(Object) after the connection closes, which will result in + // java.sql.SQLRecoverableException: Closed Connection. + if (getDbType() == DatabaseType.ORACLE) { + for (Object[] configProfileInstance : configProfile) { + configProfileInstance[3] = SQLUtil.clobToString(configProfileInstance[3]); + } } + } + } - List attributes; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAttributes)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - attributes = SQLUtil.toList(resultSet); - } - } + List categoryCounts; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getCategoryCounts)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + categoryCounts = SQLUtil.toList(resultSet); + } + } - List pendingComments; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getPendingComments)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - pendingComments = SQLUtil.toList(resultSet); - } - } + List attributes; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAttributes)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + attributes = SQLUtil.toList(resultSet); + } + } - List openItems; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getFutureItems)) { - preparedStatement.setLong(1, ItemStatus.OPEN.ordinal()); - try (ResultSet resultSet = preparedStatement.executeQuery()) { - openItems = SQLUtil.toList(resultSet); - } - } + List pendingComments; + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, getPendingComments)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + pendingComments = SQLUtil.toList(resultSet); + } + } - List waiting; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getPastItems)) { - preparedStatement.setLong(1, ItemStatus.WAITING_FOR_PURCHASE.ordinal()); - try (ResultSet resultSet = preparedStatement.executeQuery()) { - waiting = SQLUtil.toList(resultSet); - } - } + List openItems; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getFutureItems)) { + preparedStatement.setLong(1, ItemStatus.OPEN.ordinal()); + try (ResultSet resultSet = preparedStatement.executeQuery()) { + openItems = SQLUtil.toList(resultSet); + } + } - List closedItems; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getPastItems)) { - preparedStatement.setLong(1, ItemStatus.CLOSED.ordinal()); - try (ResultSet resultSet = preparedStatement.executeQuery()) { - closedItems = SQLUtil.toList(resultSet); - } - } + List waiting; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getPastItems)) { + preparedStatement.setLong(1, ItemStatus.WAITING_FOR_PURCHASE.ordinal()); + try (ResultSet resultSet = preparedStatement.executeQuery()) { + waiting = SQLUtil.toList(resultSet); + } + } - return new Config(configProfile, categoryCounts, attributes, pendingComments, openItems, waiting, closedItems); + List closedItems; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getPastItems)) { + preparedStatement.setLong(1, ItemStatus.CLOSED.ordinal()); + try (ResultSet resultSet = preparedStatement.executeQuery()) { + closedItems = SQLUtil.toList(resultSet); + } } + + return new Config( + configProfile, + categoryCounts, + attributes, + pendingComments, + openItems, + waiting, + closedItems); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewBid.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewBid.java index 485e22a11..e84dbfe32 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewBid.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewBid.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -24,11 +23,10 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemId; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; +import java.sql.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.*; - /** * NewBid * @@ -36,311 +34,382 @@ * @author visawee */ public class NewBid extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(NewBid.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getItem = new SQLStmt( - "SELECT i_initial_price, i_current_price, i_num_bids, i_end_date, i_status " + - "FROM " + AuctionMarkConstants.TABLENAME_ITEM + " " + - "WHERE i_id = ? AND i_u_id = ? " - ); - - public final SQLStmt getMaxBidId = new SQLStmt( - "SELECT MAX(ib_id) " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM_BID + - " WHERE ib_i_id = ? AND ib_u_id = ? " - ); - - public final SQLStmt getItemMaxBid = new SQLStmt( - "SELECT imb_ib_id, ib_bid, ib_max_bid, ib_buyer_id " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + ", " + - AuctionMarkConstants.TABLENAME_ITEM_BID + - " WHERE imb_i_id = ? AND imb_u_id = ? " + - " AND imb_ib_id = ib_id AND imb_ib_i_id = ib_i_id AND imb_ib_u_id = ib_u_id " - ); - - public final SQLStmt updateItem = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + - " SET i_num_bids = i_num_bids + 1, " + - " i_current_price = ?, " + - " i_updated = ? " + - " WHERE i_id = ? AND i_u_id = ? " - ); - - public final SQLStmt updateItemMaxBid = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + - " SET imb_ib_id = ?, " + - " imb_ib_i_id = ?, " + - " imb_ib_u_id = ?, " + - " imb_updated = ? " + - " WHERE imb_i_id = ? " + - " AND imb_u_id = ?" - ); - - public final SQLStmt updateBid = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM_BID + - " SET ib_bid = ?, " + - " ib_max_bid = ?, " + - " ib_updated = ? " + - " WHERE ib_id = ? " + - " AND ib_i_id = ? " + - " AND ib_u_id = ? " - ); - - public final SQLStmt insertItemBid = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_BID + " (" + - "ib_id, " + - "ib_i_id, " + - "ib_u_id, " + - "ib_buyer_id, " + - "ib_bid, " + - "ib_max_bid, " + - "ib_created, " + - "ib_updated " + - ") VALUES (" + - "?, " + // ib_id - "?, " + // ib_i_id - "?, " + // ib_u_id - "?, " + // ib_buyer_id - "?, " + // ib_bid - "?, " + // ib_max_bid - "?, " + // ib_created - "? " + // ib_updated - ")" - ); - - public final SQLStmt insertItemMaxBid = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + " (" + - "imb_i_id, " + - "imb_u_id, " + - "imb_ib_id, " + - "imb_ib_i_id, " + - "imb_ib_u_id, " + - "imb_created, " + - "imb_updated " + - ") VALUES (" + - "?, " + // imb_i_id - "?, " + // imb_u_id - "?, " + // imb_ib_id - "?, " + // imb_ib_i_id - "?, " + // imb_ib_u_id - "?, " + // imb_created - "? " + // imb_updated - ")" - ); - - public Object[] run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id, String buyer_id, double newBid, Timestamp estimatedEndDate) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - - LOG.debug(String.format("Attempting to place new bid on Item %s [buyer=%s, bid=%.2f]", - item_id, buyer_id, newBid)); - - - - // Check to make sure that we can even add a new bid to this item - // If we fail to get back an item, then we know that the auction is closed - double i_initial_price; - double i_current_price; - long i_num_bids; - Timestamp i_end_date; - ItemStatus i_status; - - try (PreparedStatement stmt = this.getPreparedStatement(conn, getItem, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - if (!results.next()) { - throw new UserAbortException("Invalid item " + item_id); - } - int col = 1; - i_initial_price = results.getDouble(col++); - i_current_price = results.getDouble(col++); - i_num_bids = results.getLong(col++); - i_end_date = results.getTimestamp(col++); - i_status = ItemStatus.get(results.getLong(col)); - - } + private static final Logger LOG = LoggerFactory.getLogger(NewBid.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getItem = + new SQLStmt( + "SELECT i_initial_price, i_current_price, i_num_bids, i_end_date, i_status " + + "FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " " + + "WHERE i_id = ? AND i_u_id = ? "); + + public final SQLStmt getMaxBidId = + new SQLStmt( + "SELECT MAX(ib_id) " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " WHERE ib_i_id = ? AND ib_u_id = ? "); + + public final SQLStmt getItemMaxBid = + new SQLStmt( + "SELECT imb_ib_id, ib_bid, ib_max_bid, ib_buyer_id " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + ", " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " WHERE imb_i_id = ? AND imb_u_id = ? " + + " AND imb_ib_id = ib_id AND imb_ib_i_id = ib_i_id AND imb_ib_u_id = ib_u_id "); + + public final SQLStmt updateItem = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " SET i_num_bids = i_num_bids + 1, " + + " i_current_price = ?, " + + " i_updated = ? " + + " WHERE i_id = ? AND i_u_id = ? "); + + public final SQLStmt updateItemMaxBid = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + " SET imb_ib_id = ?, " + + " imb_ib_i_id = ?, " + + " imb_ib_u_id = ?, " + + " imb_updated = ? " + + " WHERE imb_i_id = ? " + + " AND imb_u_id = ?"); + + public final SQLStmt updateBid = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " SET ib_bid = ?, " + + " ib_max_bid = ?, " + + " ib_updated = ? " + + " WHERE ib_id = ? " + + " AND ib_i_id = ? " + + " AND ib_u_id = ? "); + + public final SQLStmt insertItemBid = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " (" + + "ib_id, " + + "ib_i_id, " + + "ib_u_id, " + + "ib_buyer_id, " + + "ib_bid, " + + "ib_max_bid, " + + "ib_created, " + + "ib_updated " + + ") VALUES (" + + "?, " + + // ib_id + "?, " + + // ib_i_id + "?, " + + // ib_u_id + "?, " + + // ib_buyer_id + "?, " + + // ib_bid + "?, " + + // ib_max_bid + "?, " + + // ib_created + "? " + + // ib_updated + ")"); + + public final SQLStmt insertItemMaxBid = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + " (" + + "imb_i_id, " + + "imb_u_id, " + + "imb_ib_id, " + + "imb_ib_i_id, " + + "imb_ib_u_id, " + + "imb_created, " + + "imb_updated " + + ") VALUES (" + + "?, " + + // imb_i_id + "?, " + + // imb_u_id + "?, " + + // imb_ib_id + "?, " + + // imb_ib_i_id + "?, " + + // imb_ib_u_id + "?, " + + // imb_created + "? " + + // imb_updated + ")"); + + public Object[] run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + String buyer_id, + double newBid, + Timestamp estimatedEndDate) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + + LOG.debug( + String.format( + "Attempting to place new bid on Item %s [buyer=%s, bid=%.2f]", + item_id, buyer_id, newBid)); + + // Check to make sure that we can even add a new bid to this item + // If we fail to get back an item, then we know that the auction is closed + double i_initial_price; + double i_current_price; + long i_num_bids; + Timestamp i_end_date; + ItemStatus i_status; + + try (PreparedStatement stmt = this.getPreparedStatement(conn, getItem, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + if (!results.next()) { + throw new UserAbortException("Invalid item " + item_id); } + int col = 1; + i_initial_price = results.getDouble(col++); + i_current_price = results.getDouble(col++); + i_num_bids = results.getLong(col++); + i_end_date = results.getTimestamp(col++); + i_status = ItemStatus.get(results.getLong(col)); + } + } - long newBidId = 0; - String newBidMaxBuyerId = buyer_id; - - - - // If we existing bids, then we need to figure out whether we are the new highest - // bidder or if the existing one just has their max_bid bumped up - if (i_num_bids > 0) { - // Get the next ITEM_BID id for this item - LOG.debug("Retrieving ITEM_MAX_BID information for {}", ItemId.toString(item_id)); - try (PreparedStatement stmt = this.getPreparedStatement(conn, getMaxBidId, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - results.next(); - - newBidId = results.getLong(1) + 1; - } - } - - // Get the current max bid record for this item - long currentBidId; - double currentBidAmount; - double currentBidMax; - String currentBuyerId; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getItemMaxBid, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - results.next(); - - int col = 1; - currentBidId = results.getLong(col++); - currentBidAmount = results.getDouble(col++); - currentBidMax = results.getDouble(col++); - currentBuyerId = results.getString(col); - } - } - - boolean updateMaxBid = false; - // Check whether this bidder is already the max bidder - // This means we just need to increase their current max bid amount without - // changing the current auction price - if (buyer_id.equals(currentBuyerId)) { - if (newBid < currentBidMax) { - String msg = String.format("%s is already the highest bidder for Item %s but is trying to " + - "set a new max bid %.2f that is less than current max bid %.2f", - buyer_id, item_id, newBid, currentBidMax); - LOG.debug(msg); - throw new UserAbortException(msg); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateBid, i_current_price, - newBid, - currentTime, - currentBidId, - item_id, - seller_id)) { - preparedStatement.executeUpdate(); - } - LOG.debug(String.format("Increasing the max bid the highest bidder %s from %.2f to %.2f for Item %s", - buyer_id, currentBidMax, newBid, item_id)); - } - // Otherwise check whether this new bidder's max bid is greater than the current max - else { - // The new maxBid trumps the existing guy, so our the buyer_id for this txn becomes the new - // winning bidder at this time. The new current price is one step above the previous - // max bid amount - if (newBid > currentBidMax) { - i_current_price = Math.min(newBid, currentBidMax + (i_initial_price * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); - - // Defer the update to ITEM_MAX_BID until after we insert our new ITEM_BID record - updateMaxBid = true; - } - // The current max bidder is still the current one - // We just need to bump up their bid amount to be at least the bidder's amount - // Make sure that we don't go over the the currentMaxBidMax, otherwise this would mean - // that we caused the user to bid more than they wanted. - else { - newBidMaxBuyerId = currentBuyerId; - i_current_price = Math.min(currentBidMax, newBid + (i_initial_price * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); - - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateBid, i_current_price, - i_current_price, - currentTime, - currentBidId, - item_id, - seller_id)) { - preparedStatement.executeUpdate(); - } - LOG.debug(String.format("Keeping the existing highest bidder of Item %s as %s but updating current price from %.2f to %.2f", - item_id, buyer_id, currentBidAmount, i_current_price)); - } + long newBidId = 0; + String newBidMaxBuyerId = buyer_id; - // Always insert an new ITEM_BID record even if BuyerId doesn't become - // the new highest bidder. We also want to insert a new record even if - // the BuyerId already has ITEM_BID record, because we want to maintain - // the history of all the bid attempts - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertItemBid, newBidId, - item_id, - seller_id, - buyer_id, - i_current_price, - newBid, - currentTime, - currentTime)) { - preparedStatement.executeUpdate(); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItem, i_current_price, - currentTime, - item_id, - seller_id)) { - preparedStatement.executeUpdate(); - } + // If we existing bids, then we need to figure out whether we are the new highest + // bidder or if the existing one just has their max_bid bumped up + if (i_num_bids > 0) { + // Get the next ITEM_BID id for this item + LOG.debug("Retrieving ITEM_MAX_BID information for {}", ItemId.toString(item_id)); + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getMaxBidId, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + results.next(); - // This has to be done after we insert the ITEM_BID record to make sure - // that the HSQLDB test cases work - if (updateMaxBid) { - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItemMaxBid, newBidId, - item_id, - seller_id, - currentTime, - item_id, - seller_id)) { - preparedStatement.executeUpdate(); - } - LOG.debug(String.format("Changing new highest bidder of Item %s to %s [newMaxBid=%.2f > currentMaxBid=%.2f]", - item_id, buyer_id, newBid, currentBidMax)); - } - } + newBidId = results.getLong(1) + 1; + } + } + + // Get the current max bid record for this item + long currentBidId; + double currentBidAmount; + double currentBidMax; + String currentBuyerId; + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getItemMaxBid, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + results.next(); + + int col = 1; + currentBidId = results.getLong(col++); + currentBidAmount = results.getDouble(col++); + currentBidMax = results.getDouble(col++); + currentBuyerId = results.getString(col); + } + } + + boolean updateMaxBid = false; + // Check whether this bidder is already the max bidder + // This means we just need to increase their current max bid amount without + // changing the current auction price + if (buyer_id.equals(currentBuyerId)) { + if (newBid < currentBidMax) { + String msg = + String.format( + "%s is already the highest bidder for Item %s but is trying to " + + "set a new max bid %.2f that is less than current max bid %.2f", + buyer_id, item_id, newBid, currentBidMax); + LOG.debug(msg); + throw new UserAbortException(msg); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + updateBid, + i_current_price, + newBid, + currentTime, + currentBidId, + item_id, + seller_id)) { + preparedStatement.executeUpdate(); + } + LOG.debug( + String.format( + "Increasing the max bid the highest bidder %s from %.2f to %.2f for Item %s", + buyer_id, currentBidMax, newBid, item_id)); + } + // Otherwise check whether this new bidder's max bid is greater than the current max + else { + // The new maxBid trumps the existing guy, so our the buyer_id for this txn becomes the new + // winning bidder at this time. The new current price is one step above the previous + // max bid amount + if (newBid > currentBidMax) { + i_current_price = + Math.min( + newBid, + currentBidMax + (i_initial_price * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); + + // Defer the update to ITEM_MAX_BID until after we insert our new ITEM_BID record + updateMaxBid = true; } - // There is no existing max bid record, therefore we can just insert ourselves + // The current max bidder is still the current one + // We just need to bump up their bid amount to be at least the bidder's amount + // Make sure that we don't go over the the currentMaxBidMax, otherwise this would mean + // that we caused the user to bid more than they wanted. else { - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertItemBid, newBidId, - item_id, - seller_id, - buyer_id, - i_initial_price, - newBid, - currentTime, - currentTime)) { - preparedStatement.executeUpdate(); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertItemMaxBid, item_id, - seller_id, - newBidId, - item_id, - seller_id, - currentTime, - currentTime)) { - preparedStatement.executeUpdate(); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItem, i_current_price, - currentTime, - item_id, - seller_id)) { - preparedStatement.execute(); - } - LOG.debug(String.format("Creating the first bid record for Item %s and setting %s as highest bidder at %.2f", - item_id, buyer_id, i_current_price)); + newBidMaxBuyerId = currentBuyerId; + i_current_price = + Math.min( + currentBidMax, + newBid + (i_initial_price * AuctionMarkConstants.ITEM_BID_PERCENT_STEP)); + + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + updateBid, + i_current_price, + i_current_price, + currentTime, + currentBidId, + item_id, + seller_id)) { + preparedStatement.executeUpdate(); + } + LOG.debug( + String.format( + "Keeping the existing highest bidder of Item %s as %s but updating current price from %.2f to %.2f", + item_id, buyer_id, currentBidAmount, i_current_price)); } - // Return back information about the current state of the item auction - return new Object[]{ - // ITEM_ID + // Always insert an new ITEM_BID record even if BuyerId doesn't become + // the new highest bidder. We also want to insert a new record even if + // the BuyerId already has ITEM_BID record, because we want to maintain + // the history of all the bid attempts + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + insertItemBid, + newBidId, item_id, - // SELLER_ID seller_id, - // ITEM_NAME - null, // ignore - // CURRENT PRICE + buyer_id, i_current_price, - // NUM BIDS - i_num_bids + 1, - // END DATE - i_end_date, - // STATUS - i_status.ordinal(), - // MAX BID ID - newBidId, - // MAX BID BUYER_ID - newBidMaxBuyerId, - }; + newBid, + currentTime, + currentTime)) { + preparedStatement.executeUpdate(); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, updateItem, i_current_price, currentTime, item_id, seller_id)) { + preparedStatement.executeUpdate(); + } + + // This has to be done after we insert the ITEM_BID record to make sure + // that the HSQLDB test cases work + if (updateMaxBid) { + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + updateItemMaxBid, + newBidId, + item_id, + seller_id, + currentTime, + item_id, + seller_id)) { + preparedStatement.executeUpdate(); + } + LOG.debug( + String.format( + "Changing new highest bidder of Item %s to %s [newMaxBid=%.2f > currentMaxBid=%.2f]", + item_id, buyer_id, newBid, currentBidMax)); + } + } } + // There is no existing max bid record, therefore we can just insert ourselves + else { + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + insertItemBid, + newBidId, + item_id, + seller_id, + buyer_id, + i_initial_price, + newBid, + currentTime, + currentTime)) { + preparedStatement.executeUpdate(); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + insertItemMaxBid, + item_id, + seller_id, + newBidId, + item_id, + seller_id, + currentTime, + currentTime)) { + preparedStatement.executeUpdate(); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, updateItem, i_current_price, currentTime, item_id, seller_id)) { + preparedStatement.execute(); + } + LOG.debug( + String.format( + "Creating the first bid record for Item %s and setting %s as highest bidder at %.2f", + item_id, buyer_id, i_current_price)); + } + + // Return back information about the current state of the item auction + return new Object[] { + // ITEM_ID + item_id, + // SELLER_ID + seller_id, + // ITEM_NAME + null, // ignore + // CURRENT PRICE + i_current_price, + // NUM BIDS + i_num_bids + 1, + // END DATE + i_end_date, + // STATUS + i_status.ordinal(), + // MAX BID ID + newBidId, + // MAX BID BUYER_ID + newBidMaxBuyerId, + }; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewComment.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewComment.java index 2d0f11c02..c4ec9f0ee 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewComment.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewComment.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,7 +22,6 @@ import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; import com.oltpbenchmark.util.SQLUtil; - import java.sql.*; /** @@ -33,89 +31,109 @@ */ public class NewComment extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getItemComments = new SQLStmt( - "SELECT i_num_comments " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + - " WHERE i_id = ? AND i_u_id = ?" - ); - - public final SQLStmt updateItemComments = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + - " SET i_num_comments = i_num_comments + 1 " + - " WHERE i_id = ? AND i_u_id = ?" - ); - - public final SQLStmt insertItemComment = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + "(" + - "ic_id," + - "ic_i_id," + - "ic_u_id," + - "ic_buyer_id," + - "ic_question, " + - "ic_created," + - "ic_updated " + - ") VALUES (?,?,?,?,?,?,?)" - ); - - public final SQLStmt updateUser = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT + " " + - "SET u_comments = u_comments + 1, " + - " u_updated = ? " + - " WHERE u_id = ?" - ); - - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- - - public Object[] run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id, String buyer_id, String question) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - - // Set comment_id - long ic_id = 0; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getItemComments, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - ic_id = results.getLong(1) + 1; - } - } - } - - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertItemComment, ic_id, - item_id, - seller_id, - buyer_id, - question, - currentTime, - currentTime)) { - preparedStatement.executeUpdate(); - } - catch (SQLException ex) { - if (SQLUtil.isDuplicateKeyException(ex)) { - throw new UserAbortException("item comment id " + ic_id + " already exists for item " + item_id + " and seller " + seller_id); - } - else { - throw ex; - } + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getItemComments = + new SQLStmt( + "SELECT i_num_comments " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + " WHERE i_id = ? AND i_u_id = ?"); + + public final SQLStmt updateItemComments = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " SET i_num_comments = i_num_comments + 1 " + + " WHERE i_id = ? AND i_u_id = ?"); + + public final SQLStmt insertItemComment = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + + "(" + + "ic_id," + + "ic_i_id," + + "ic_u_id," + + "ic_buyer_id," + + "ic_question, " + + "ic_created," + + "ic_updated " + + ") VALUES (?,?,?,?,?,?,?)"); + + public final SQLStmt updateUser = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT + + " " + + "SET u_comments = u_comments + 1, " + + " u_updated = ? " + + " WHERE u_id = ?"); + + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- + + public Object[] run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + String buyer_id, + String question) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + + // Set comment_id + long ic_id = 0; + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getItemComments, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + ic_id = results.getLong(1) + 1; } + } + } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItemComments, item_id, seller_id)) { - preparedStatement.executeUpdate(); - } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + insertItemComment, + ic_id, + item_id, + seller_id, + buyer_id, + question, + currentTime, + currentTime)) { + preparedStatement.executeUpdate(); + } catch (SQLException ex) { + if (SQLUtil.isDuplicateKeyException(ex)) { + throw new UserAbortException( + "item comment id " + + ic_id + + " already exists for item " + + item_id + + " and seller " + + seller_id); + } else { + throw ex; + } + } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUser, currentTime, seller_id)) { - preparedStatement.executeUpdate(); - } + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateItemComments, item_id, seller_id)) { + preparedStatement.executeUpdate(); + } - // Return new ic_id - return new Object[]{ic_id, - item_id, - seller_id}; + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateUser, currentTime, seller_id)) { + preparedStatement.executeUpdate(); } -} \ No newline at end of file + // Return new ic_id + return new Object[] {ic_id, item_id, seller_id}; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewCommentResponse.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewCommentResponse.java index 28c1cc37f..4ee498650 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewCommentResponse.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewCommentResponse.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -36,36 +34,49 @@ */ public class NewCommentResponse extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- - public final SQLStmt updateComment = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + " " + - "SET ic_response = ?, " + - " ic_updated = ? " + - "WHERE ic_id = ? AND ic_i_id = ? AND ic_u_id = ? " - ); + public final SQLStmt updateComment = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM_COMMENT + + " " + + "SET ic_response = ?, " + + " ic_updated = ? " + + "WHERE ic_id = ? AND ic_i_id = ? AND ic_u_id = ? "); - public final SQLStmt updateUser = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT + " " + - "SET u_comments = u_comments - 1, " + - " u_updated = ? " + - " WHERE u_id = ?" - ); + public final SQLStmt updateUser = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT + + " " + + "SET u_comments = u_comments - 1, " + + " u_updated = ? " + + " WHERE u_id = ?"); - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- - public void run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id, long comment_id, String response) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateComment, response, currentTime, comment_id, item_id, seller_id)) { - preparedStatement.executeUpdate(); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUser, currentTime, seller_id)) { - preparedStatement.executeUpdate(); - } + public void run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + long comment_id, + String response) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, updateComment, response, currentTime, comment_id, item_id, seller_id)) { + preparedStatement.executeUpdate(); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateUser, currentTime, seller_id)) { + preparedStatement.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewFeedback.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewFeedback.java index 07c65afd9..7f2b8cd2b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewFeedback.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewFeedback.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; - import java.sql.*; /** @@ -32,72 +30,99 @@ */ public class NewFeedback extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- - public final SQLStmt checkUserFeedback = new SQLStmt( - "SELECT uf_i_id, uf_i_u_id, uf_from_id " + - " FROM " + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + " " + - " WHERE uf_u_id = ? AND uf_i_id = ? AND uf_i_u_id = ? AND uf_from_id = ?" - ); + public final SQLStmt checkUserFeedback = + new SQLStmt( + "SELECT uf_i_id, uf_i_u_id, uf_from_id " + + " FROM " + + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + + " " + + " WHERE uf_u_id = ? AND uf_i_id = ? AND uf_i_u_id = ? AND uf_from_id = ?"); - public final SQLStmt insertFeedback = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + "( " + - "uf_u_id, " + - "uf_i_id," + - "uf_i_u_id," + - "uf_from_id," + - "uf_rating," + - "uf_date," + - "uf_sattr0" + - ") VALUES (" + - "?," + // UF_U_ID - "?," + // UF_I_ID - "?," + // UF_I_U_ID - "?," + // UF_FROM_ID - "?," + // UF_RATING - "?," + // UF_DATE - "?" + // UF_SATTR0 - ")" - ); + public final SQLStmt insertFeedback = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_USERACCT_FEEDBACK + + "( " + + "uf_u_id, " + + "uf_i_id," + + "uf_i_u_id," + + "uf_from_id," + + "uf_rating," + + "uf_date," + + "uf_sattr0" + + ") VALUES (" + + "?," + + // UF_U_ID + "?," + + // UF_I_ID + "?," + + // UF_I_U_ID + "?," + + // UF_FROM_ID + "?," + + // UF_RATING + "?," + + // UF_DATE + "?" + + // UF_SATTR0 + ")"); - public final SQLStmt updateUser = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT + " " + - "SET u_rating = u_rating + ?, " + - " u_updated = ? " + - " WHERE u_id = ?" - ); + public final SQLStmt updateUser = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT + + " " + + "SET u_rating = u_rating + ?, " + + " u_updated = ? " + + " WHERE u_id = ?"); - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- - public void run(Connection conn, Timestamp[] benchmarkTimes, - String user_id, String i_id, String seller_id, String from_id, long rating, String comment) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + public void run( + Connection conn, + Timestamp[] benchmarkTimes, + String user_id, + String i_id, + String seller_id, + String from_id, + long rating, + String comment) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - // Check to make sure they're not trying to add feedback - // twice for the same ITEM - try (PreparedStatement stmt = this.getPreparedStatement(conn, checkUserFeedback, user_id, i_id, seller_id, from_id)) { - try (ResultSet rs = stmt.executeQuery()) { - if (rs.next()) { - throw new UserAbortException("Trying to add feedback for item " + i_id + " twice"); - } - } + // Check to make sure they're not trying to add feedback + // twice for the same ITEM + try (PreparedStatement stmt = + this.getPreparedStatement(conn, checkUserFeedback, user_id, i_id, seller_id, from_id)) { + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + throw new UserAbortException("Trying to add feedback for item " + i_id + " twice"); } + } + } - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertFeedback, user_id, - i_id, - seller_id, - from_id, - rating, - currentTime, - comment)) { - stmt.executeUpdate(); - } - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUser, rating, currentTime, user_id)) { - preparedStatement.executeUpdate(); - } + try (PreparedStatement stmt = + this.getPreparedStatement( + conn, + insertFeedback, + user_id, + i_id, + seller_id, + from_id, + rating, + currentTime, + comment)) { + stmt.executeUpdate(); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateUser, rating, currentTime, user_id)) { + preparedStatement.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewItem.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewItem.java index ca028bfa3..1bbaeb01d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewItem.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewItem.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -25,11 +24,10 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; import com.oltpbenchmark.util.SQLUtil; +import java.sql.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.*; - /** * NewItem * @@ -37,213 +35,309 @@ * @author visawee */ public class NewItem extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(NewItem.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt insertItem = new SQLStmt("INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM + "(" + "i_id," + "i_u_id," + "i_c_id," + "i_name," + "i_description," + "i_user_attributes," + "i_initial_price," + "i_current_price," + "i_num_bids," + "i_num_images," + "i_num_global_attrs," + "i_start_date," + "i_end_date," + "i_status, " + "i_created," + "i_updated," + "i_iattr0" + ") VALUES (" + "?," + // i_id - "?," + // i_u_id - "?," + // i_c_id - "?," + // i_name - "?," + // i_description - "?," + // i_user_attributes - "?," + // i_initial_price - "?," + // i_current_price - "?," + // i_num_bids - "?," + // i_num_images - "?," + // i_num_global_attrs - "?," + // i_start_date - "?," + // i_end_date - "?," + // i_status - "?," + // i_created - "?," + // i_updated - "1" + // i_attr0 - ")"); - - public final SQLStmt getCategory = new SQLStmt("SELECT * FROM " + AuctionMarkConstants.TABLENAME_CATEGORY + " WHERE c_id = ? "); - - public final SQLStmt getCategoryParent = new SQLStmt("SELECT * FROM " + AuctionMarkConstants.TABLENAME_CATEGORY + " WHERE c_parent_id = ? "); - - public final SQLStmt getGlobalAttribute = new SQLStmt("SELECT gag_name, gav_name, gag_c_id " + "FROM " + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP + ", " + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE + " WHERE gav_id = ? AND gav_gag_id = ? " + "AND gav_gag_id = gag_id"); - - public final SQLStmt insertItemAttribute = new SQLStmt("INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + "(" + "ia_id," + "ia_i_id," + "ia_u_id," + "ia_gav_id," + "ia_gag_id" + ") VALUES(?, ?, ?, ?, ?)"); - - public final SQLStmt insertImage = new SQLStmt("INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_IMAGE + "(" + "ii_id," + "ii_i_id," + "ii_u_id," + "ii_sattr0" + ") VALUES(?, ?, ?, ?)"); - - public final SQLStmt updateUserBalance = new SQLStmt("UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT + " " + "SET u_balance = u_balance - 1, " + " u_updated = ? " + " WHERE u_id = ?"); - - public final SQLStmt getSellerItemCount = new SQLStmt("SELECT COUNT(*) FROM " + AuctionMarkConstants.TABLENAME_ITEM + " WHERE i_u_id = ?"); - - - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- - - /** - * Insert a new ITEM record for a user. - * The benchmark client provides all of the preliminary information - * required for the new item, as well as optional information to create - * derivative image and attribute records. After inserting the new ITEM - * record, the transaction then inserts any GLOBAL ATTRIBUTE VALUE and - * ITEM IMAGE. The unique identifer for each of these records is a - * composite 64-bit key where the lower 60-bits are the i id parameter and the - * upper 4-bits are used to represent the index of the image/attribute. - * For example, if the i id is 100 and there are four items, then the - * composite key will be 0 100 for the first image, 1 100 for the second, - * and so on. After these records are inserted, the transaction then updates - * the USER record to add the listing fee to the seller's balance. - */ - public Object[] run(Connection conn, Timestamp[] benchmarkTimes, String item_id, String seller_id, long category_id, String name, String description, long duration, double initial_price, String attributes, String[] gag_ids, String[] gav_ids, String[] images) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - final boolean debug = LOG.isDebugEnabled(); - - // Calculate endDate - Timestamp end_date = new Timestamp(currentTime.getTime() + (duration * AuctionMarkConstants.MILLISECONDS_IN_A_DAY)); - - if (debug) { - LOG.debug("NewItem :: run "); - LOG.debug(">> item_id = {} , seller_id = {}, category_id = {}", item_id, seller_id, category_id); - LOG.debug(">> name = {} , description length = {}", name, description.length()); - LOG.debug(">> initial_price = {} , attributes length = {}", initial_price, attributes.length()); - LOG.debug(">> gag_ids[].length = {} , gav_ids[] length = {}", gag_ids.length, gav_ids.length); - LOG.debug(">> image length = {} ", images.length); - LOG.debug(">> start = {}, end = {}", currentTime, end_date); - } - - // Get attribute names and category path and append - // them to the item description - - - // ATTRIBUTES - description += "\nATTRIBUTES: "; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getGlobalAttribute)) { - for (int i = 0; i < gag_ids.length; i++) { - int col = 1; - stmt.setString(col++, gav_ids[i]); - stmt.setString(col, gag_ids[i]); - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - col = 1; - description += String.format(" * %s -> %s\n", results.getString(col++), results.getString(col)); - } - } - } - } - - // CATEGORY - String category_name; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getCategory, category_id)) { - try (ResultSet results = stmt.executeQuery()) { - results.next(); + private static final Logger LOG = LoggerFactory.getLogger(NewItem.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt insertItem = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM + + "(" + + "i_id," + + "i_u_id," + + "i_c_id," + + "i_name," + + "i_description," + + "i_user_attributes," + + "i_initial_price," + + "i_current_price," + + "i_num_bids," + + "i_num_images," + + "i_num_global_attrs," + + "i_start_date," + + "i_end_date," + + "i_status, " + + "i_created," + + "i_updated," + + "i_iattr0" + + ") VALUES (" + + "?," + + // i_id + "?," + + // i_u_id + "?," + + // i_c_id + "?," + + // i_name + "?," + + // i_description + "?," + + // i_user_attributes + "?," + + // i_initial_price + "?," + + // i_current_price + "?," + + // i_num_bids + "?," + + // i_num_images + "?," + + // i_num_global_attrs + "?," + + // i_start_date + "?," + + // i_end_date + "?," + + // i_status + "?," + + // i_created + "?," + + // i_updated + "1" + + // i_attr0 + ")"); + + public final SQLStmt getCategory = + new SQLStmt("SELECT * FROM " + AuctionMarkConstants.TABLENAME_CATEGORY + " WHERE c_id = ? "); + + public final SQLStmt getCategoryParent = + new SQLStmt( + "SELECT * FROM " + AuctionMarkConstants.TABLENAME_CATEGORY + " WHERE c_parent_id = ? "); + + public final SQLStmt getGlobalAttribute = + new SQLStmt( + "SELECT gag_name, gav_name, gag_c_id " + + "FROM " + + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_GROUP + + ", " + + AuctionMarkConstants.TABLENAME_GLOBAL_ATTRIBUTE_VALUE + + " WHERE gav_id = ? AND gav_gag_id = ? " + + "AND gav_gag_id = gag_id"); + + public final SQLStmt insertItemAttribute = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + + "(" + + "ia_id," + + "ia_i_id," + + "ia_u_id," + + "ia_gav_id," + + "ia_gag_id" + + ") VALUES(?, ?, ?, ?, ?)"); + + public final SQLStmt insertImage = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_IMAGE + + "(" + + "ii_id," + + "ii_i_id," + + "ii_u_id," + + "ii_sattr0" + + ") VALUES(?, ?, ?, ?)"); + + public final SQLStmt updateUserBalance = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT + + " " + + "SET u_balance = u_balance - 1, " + + " u_updated = ? " + + " WHERE u_id = ?"); + + public final SQLStmt getSellerItemCount = + new SQLStmt( + "SELECT COUNT(*) FROM " + AuctionMarkConstants.TABLENAME_ITEM + " WHERE i_u_id = ?"); + + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- + + /** + * Insert a new ITEM record for a user. The benchmark client provides all of the preliminary + * information required for the new item, as well as optional information to create derivative + * image and attribute records. After inserting the new ITEM record, the transaction then inserts + * any GLOBAL ATTRIBUTE VALUE and ITEM IMAGE. The unique identifer for each of these records is a + * composite 64-bit key where the lower 60-bits are the i id parameter and the upper 4-bits are + * used to represent the index of the image/attribute. For example, if the i id is 100 and there + * are four items, then the composite key will be 0 100 for the first image, 1 100 for the second, + * and so on. After these records are inserted, the transaction then updates the USER record to + * add the listing fee to the seller's balance. + */ + public Object[] run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + long category_id, + String name, + String description, + long duration, + double initial_price, + String attributes, + String[] gag_ids, + String[] gav_ids, + String[] images) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + final boolean debug = LOG.isDebugEnabled(); + + // Calculate endDate + Timestamp end_date = + new Timestamp( + currentTime.getTime() + (duration * AuctionMarkConstants.MILLISECONDS_IN_A_DAY)); + + if (debug) { + LOG.debug("NewItem :: run "); + LOG.debug( + ">> item_id = {} , seller_id = {}, category_id = {}", item_id, seller_id, category_id); + LOG.debug(">> name = {} , description length = {}", name, description.length()); + LOG.debug( + ">> initial_price = {} , attributes length = {}", initial_price, attributes.length()); + LOG.debug(">> gag_ids[].length = {} , gav_ids[] length = {}", gag_ids.length, gav_ids.length); + LOG.debug(">> image length = {} ", images.length); + LOG.debug(">> start = {}, end = {}", currentTime, end_date); + } - category_name = String.format("%s[%d]", results.getString(2), results.getInt(1)); - } + // Get attribute names and category path and append + // them to the item description + + // ATTRIBUTES + description += "\nATTRIBUTES: "; + try (PreparedStatement stmt = this.getPreparedStatement(conn, getGlobalAttribute)) { + for (int i = 0; i < gag_ids.length; i++) { + int col = 1; + stmt.setString(col++, gav_ids[i]); + stmt.setString(col, gag_ids[i]); + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + col = 1; + description += + String.format(" * %s -> %s\n", results.getString(col++), results.getString(col)); + } } + } + } - // CATEGORY PARENT - try (PreparedStatement stmt = this.getPreparedStatement(conn, getCategoryParent, category_id)) { - try (ResultSet results = stmt.executeQuery()) { - String category_parent = null; - if (results.next()) { - category_parent = String.format("%s[%d]", results.getString(2), results.getInt(1)); - } else { - category_parent = ""; - } - description += String.format("\nCATEGORY: %s >> %s", category_parent, category_name); - } - } + // CATEGORY + String category_name; + try (PreparedStatement stmt = this.getPreparedStatement(conn, getCategory, category_id)) { + try (ResultSet results = stmt.executeQuery()) { + results.next(); - int sellerItemCount = 0; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSellerItemCount, seller_id); - ResultSet results = stmt.executeQuery()) { - if (results.next()) { - sellerItemCount = results.getInt(1); - } - } + category_name = String.format("%s[%d]", results.getString(2), results.getInt(1)); + } + } - // Insert new ITEM tuple - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertItem, item_id, // i_id - seller_id, // i_u_id - category_id, // i_c_id - name, // i_name - description, // i_description - attributes, // i_user_attributes - initial_price, // i_initial_proce - initial_price, // i_current_price - 0, // i_num_bids - images.length, // i_num_images - gav_ids.length, // i_num_global_attrs - currentTime, // i_start_date - end_date, // i_end_date - ItemStatus.OPEN.ordinal(), // i_status - currentTime, // i_created - currentTime // i_updated - )) { - - // NOTE: This may fail with a duplicate entry exception because - // the client's internal count of the number of items that this seller - // already has is wrong. That's ok. We'll just abort and ignore the problem - // Eventually the client's internal cache will catch up with what's in the database - stmt.executeUpdate(); - - } catch (SQLException ex) { - if (SQLUtil.isDuplicateKeyException(ex)) { - throw new DuplicateItemIdException(item_id, seller_id, sellerItemCount, ex); - } else { - throw ex; - } + // CATEGORY PARENT + try (PreparedStatement stmt = this.getPreparedStatement(conn, getCategoryParent, category_id)) { + try (ResultSet results = stmt.executeQuery()) { + String category_parent = null; + if (results.next()) { + category_parent = String.format("%s[%d]", results.getString(2), results.getInt(1)); + } else { + category_parent = ""; } + description += String.format("\nCATEGORY: %s >> %s", category_parent, category_name); + } + } - // Insert ITEM_ATTRIBUTE tuples - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertItemAttribute)) { - for (int i = 0; i < gav_ids.length; i++) { - int param = 1; - stmt.setString(param++, AuctionMarkUtil.getUniqueElementId(item_id, i)); - stmt.setString(param++, item_id); - stmt.setString(param++, seller_id); - stmt.setString(param++, gav_ids[i]); - stmt.setString(param, gag_ids[i]); - stmt.executeUpdate(); - - } - } + int sellerItemCount = 0; + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSellerItemCount, seller_id); + ResultSet results = stmt.executeQuery()) { + if (results.next()) { + sellerItemCount = results.getInt(1); + } + } - // Insert ITEM_IMAGE tuples - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertImage)) { - for (int i = 0; i < images.length; i++) { - int param = 1; - stmt.setString(param++, AuctionMarkUtil.getUniqueElementId(item_id, i)); - stmt.setString(param++, item_id); - stmt.setString(param++, seller_id); - stmt.setString(param, images[i]); - stmt.executeUpdate(); - - } - } + // Insert new ITEM tuple + try (PreparedStatement stmt = + this.getPreparedStatement( + conn, + insertItem, + item_id, // i_id + seller_id, // i_u_id + category_id, // i_c_id + name, // i_name + description, // i_description + attributes, // i_user_attributes + initial_price, // i_initial_proce + initial_price, // i_current_price + 0, // i_num_bids + images.length, // i_num_images + gav_ids.length, // i_num_global_attrs + currentTime, // i_start_date + end_date, // i_end_date + ItemStatus.OPEN.ordinal(), // i_status + currentTime, // i_created + currentTime // i_updated + )) { + + // NOTE: This may fail with a duplicate entry exception because + // the client's internal count of the number of items that this seller + // already has is wrong. That's ok. We'll just abort and ignore the problem + // Eventually the client's internal cache will catch up with what's in the database + stmt.executeUpdate(); + + } catch (SQLException ex) { + if (SQLUtil.isDuplicateKeyException(ex)) { + throw new DuplicateItemIdException(item_id, seller_id, sellerItemCount, ex); + } else { + throw ex; + } + } - // Update listing fee - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUserBalance, currentTime, seller_id)) { - preparedStatement.executeUpdate(); - } + // Insert ITEM_ATTRIBUTE tuples + try (PreparedStatement stmt = this.getPreparedStatement(conn, insertItemAttribute)) { + for (int i = 0; i < gav_ids.length; i++) { + int param = 1; + stmt.setString(param++, AuctionMarkUtil.getUniqueElementId(item_id, i)); + stmt.setString(param++, item_id); + stmt.setString(param++, seller_id); + stmt.setString(param++, gav_ids[i]); + stmt.setString(param, gag_ids[i]); + stmt.executeUpdate(); + } + } + // Insert ITEM_IMAGE tuples + try (PreparedStatement stmt = this.getPreparedStatement(conn, insertImage)) { + for (int i = 0; i < images.length; i++) { + int param = 1; + stmt.setString(param++, AuctionMarkUtil.getUniqueElementId(item_id, i)); + stmt.setString(param++, item_id); + stmt.setString(param++, seller_id); + stmt.setString(param, images[i]); + stmt.executeUpdate(); + } + } - // Return new item_id and user_id - return new Object[]{ - // ITEM ID - item_id, - // SELLER ID - seller_id, - // ITEM_NAME - name, - // CURRENT PRICE - initial_price, - // NUM BIDS - 0L, - // END DATE - end_date, - // STATUS - ItemStatus.OPEN.ordinal()}; + // Update listing fee + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateUserBalance, currentTime, seller_id)) { + preparedStatement.executeUpdate(); } -} \ No newline at end of file + + // Return new item_id and user_id + return new Object[] { + // ITEM ID + item_id, + // SELLER ID + seller_id, + // ITEM_NAME + name, + // CURRENT PRICE + initial_price, + // NUM BIDS + 0L, + // END DATE + end_date, + // STATUS + ItemStatus.OPEN.ordinal() + }; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewPurchase.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewPurchase.java index f7a066758..7f95c0126 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewPurchase.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/NewPurchase.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,239 +22,302 @@ import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; - import java.sql.*; /** - * NewPurchase - * Description goes here... + * NewPurchase Description goes here... * * @author visawee */ public class NewPurchase extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- - public final SQLStmt getItemMaxBid = new SQLStmt( - "SELECT * FROM " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + - " WHERE imb_i_id = ? AND imb_u_id = ?" - ); + public final SQLStmt getItemMaxBid = + new SQLStmt( + "SELECT * FROM " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + " WHERE imb_i_id = ? AND imb_u_id = ?"); - public final SQLStmt getMaxBid = new SQLStmt( - "SELECT * FROM " + AuctionMarkConstants.TABLENAME_ITEM_BID + - " WHERE imb_i_id = ? AND imb_u_id = ? " + - " ORDER BY ib_bid DESC LIMIT 1" - ); + public final SQLStmt getMaxBid = + new SQLStmt( + "SELECT * FROM " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + " WHERE imb_i_id = ? AND imb_u_id = ? " + + " ORDER BY ib_bid DESC LIMIT 1"); - public final SQLStmt insertItemMaxBid = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + " (" + - "imb_i_id, " + - "imb_u_id, " + - "imb_ib_id, " + - "imb_ib_i_id, " + - "imb_ib_u_id, " + - "imb_created, " + - "imb_updated " + - ") VALUES (" + - "?, " + // imb_i_id - "?, " + // imb_u_id - "?, " + // imb_ib_id - "?, " + // imb_ib_i_id - "?, " + // imb_ib_u_id - "?, " + // imb_created - "? " + // imb_updated - ")" - ); + public final SQLStmt insertItemMaxBid = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + " (" + + "imb_i_id, " + + "imb_u_id, " + + "imb_ib_id, " + + "imb_ib_i_id, " + + "imb_ib_u_id, " + + "imb_created, " + + "imb_updated " + + ") VALUES (" + + "?, " + + // imb_i_id + "?, " + + // imb_u_id + "?, " + + // imb_ib_id + "?, " + + // imb_ib_i_id + "?, " + + // imb_ib_u_id + "?, " + + // imb_created + "? " + + // imb_updated + ")"); - public final SQLStmt getItemInfo = new SQLStmt( - "SELECT i_num_bids, i_current_price, i_end_date, " + - " ib_id, ib_buyer_id, " + - " u_balance " + - " FROM " + AuctionMarkConstants.TABLENAME_ITEM + ", " + - AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + ", " + - AuctionMarkConstants.TABLENAME_ITEM_BID + ", " + - AuctionMarkConstants.TABLENAME_USERACCT + - " WHERE i_id = ? AND i_u_id = ? " + - " AND imb_i_id = i_id AND imb_u_id = i_u_id " + - " AND imb_ib_id = ib_id AND imb_ib_i_id = ib_i_id AND imb_ib_u_id = ib_u_id " + - " AND ib_buyer_id = u_id " - ); + public final SQLStmt getItemInfo = + new SQLStmt( + "SELECT i_num_bids, i_current_price, i_end_date, " + + " ib_id, ib_buyer_id, " + + " u_balance " + + " FROM " + + AuctionMarkConstants.TABLENAME_ITEM + + ", " + + AuctionMarkConstants.TABLENAME_ITEM_MAX_BID + + ", " + + AuctionMarkConstants.TABLENAME_ITEM_BID + + ", " + + AuctionMarkConstants.TABLENAME_USERACCT + + " WHERE i_id = ? AND i_u_id = ? " + + " AND imb_i_id = i_id AND imb_u_id = i_u_id " + + " AND imb_ib_id = ib_id AND imb_ib_i_id = ib_i_id AND imb_ib_u_id = ib_u_id " + + " AND ib_buyer_id = u_id "); - public final SQLStmt getBuyerInfo = new SQLStmt( - "SELECT u_id, u_balance " + - " FROM " + AuctionMarkConstants.TABLENAME_USERACCT + - " WHERE u_id = ? " - ); + public final SQLStmt getBuyerInfo = + new SQLStmt( + "SELECT u_id, u_balance " + + " FROM " + + AuctionMarkConstants.TABLENAME_USERACCT + + " WHERE u_id = ? "); - public final SQLStmt insertPurchase = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + " (" + - "ip_id," + - "ip_ib_id," + - "ip_ib_i_id," + - "ip_ib_u_id," + - "ip_date" + - ") VALUES(?,?,?,?,?)" - ); + public final SQLStmt insertPurchase = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + + " (" + + "ip_id," + + "ip_ib_id," + + "ip_ib_i_id," + + "ip_ib_u_id," + + "ip_date" + + ") VALUES(?,?,?,?,?)"); - public final SQLStmt updateItem = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + - " SET i_status = " + ItemStatus.CLOSED.ordinal() + ", i_updated = ? " + - " WHERE i_id = ? AND i_u_id = ? " - ); + public final SQLStmt updateItem = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " SET i_status = " + + ItemStatus.CLOSED.ordinal() + + ", i_updated = ? " + + " WHERE i_id = ? AND i_u_id = ? "); - public final SQLStmt updateUserItem = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + " " + - "SET ui_ip_id = ?, " + - " ui_ip_ib_id = ?, " + - " ui_ip_ib_i_id = ?, " + - " ui_ip_ib_u_id = ?" + - " WHERE ui_u_id = ? AND ui_i_id = ? AND ui_i_u_id = ?" - ); + public final SQLStmt updateUserItem = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + + " " + + "SET ui_ip_id = ?, " + + " ui_ip_ib_id = ?, " + + " ui_ip_ib_i_id = ?, " + + " ui_ip_ib_u_id = ?" + + " WHERE ui_u_id = ? AND ui_i_id = ? AND ui_i_u_id = ?"); - public final SQLStmt insertUserItem = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + "(" + - "ui_u_id, " + - "ui_i_id, " + - "ui_i_u_id, " + - "ui_ip_id, " + - "ui_ip_ib_id, " + - "ui_ip_ib_i_id, " + - "ui_ip_ib_u_id, " + - "ui_created" + - ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)" - ); + public final SQLStmt insertUserItem = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_USERACCT_ITEM + + "(" + + "ui_u_id, " + + "ui_i_id, " + + "ui_i_u_id, " + + "ui_ip_id, " + + "ui_ip_ib_id, " + + "ui_ip_ib_i_id, " + + "ui_ip_ib_u_id, " + + "ui_created" + + ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - public final SQLStmt updateUserBalance = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_USERACCT + " " + - "SET u_balance = u_balance + ? " + - " WHERE u_id = ?" - ); + public final SQLStmt updateUserBalance = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_USERACCT + + " " + + "SET u_balance = u_balance + ? " + + " WHERE u_id = ?"); - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- - public Object[] run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id, String ip_id, double buyer_credit) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + public Object[] run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + String ip_id, + double buyer_credit) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - // HACK: Check whether we have an ITEM_MAX_BID record. If not, we'll insert one - try (PreparedStatement getItemMaxBidStatement = this.getPreparedStatement(conn, getItemMaxBid, item_id, seller_id); - ResultSet results = getItemMaxBidStatement.executeQuery()) { - if (!results.next()) { - try (PreparedStatement getMaxBidStatement = this.getPreparedStatement(conn, getMaxBid, item_id, seller_id); - ResultSet getMaxBidResults = getMaxBidStatement.executeQuery()) { - getMaxBidResults.next(); + // HACK: Check whether we have an ITEM_MAX_BID record. If not, we'll insert one + try (PreparedStatement getItemMaxBidStatement = + this.getPreparedStatement(conn, getItemMaxBid, item_id, seller_id); + ResultSet results = getItemMaxBidStatement.executeQuery()) { + if (!results.next()) { + try (PreparedStatement getMaxBidStatement = + this.getPreparedStatement(conn, getMaxBid, item_id, seller_id); + ResultSet getMaxBidResults = getMaxBidStatement.executeQuery()) { + getMaxBidResults.next(); - long bid_id = results.getLong(1); + long bid_id = results.getLong(1); - try (PreparedStatement insertItemMaxBidStatement = this.getPreparedStatement(conn, insertItemMaxBid, item_id, - seller_id, - bid_id, - item_id, - seller_id, - currentTime, - currentTime)) { - insertItemMaxBidStatement.executeUpdate(); - } - } - } + try (PreparedStatement insertItemMaxBidStatement = + this.getPreparedStatement( + conn, + insertItemMaxBid, + item_id, + seller_id, + bid_id, + item_id, + seller_id, + currentTime, + currentTime)) { + insertItemMaxBidStatement.executeUpdate(); + } } + } + } - // Get the ITEM_MAX_BID record so that we know what we need to process - // At this point we should always have an ITEM_MAX_BID record - - long i_num_bids; - double i_current_price; - Timestamp i_end_date; - ItemStatus i_status; - long ib_id; - long ib_buyer_id; - double u_balance; - - try (PreparedStatement stmt = this.getPreparedStatement(conn, getItemInfo, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - if (!results.next()) { - String msg = "No ITEM_MAX_BID is available record for item " + item_id; - throw new UserAbortException(msg); - } - int col = 1; - i_num_bids = results.getLong(col++); - i_current_price = results.getDouble(col++); - i_end_date = results.getTimestamp(col++); - i_status = ItemStatus.CLOSED; - ib_id = results.getLong(col++); - ib_buyer_id = results.getLong(col++); - u_balance = results.getDouble(col); - } - } + // Get the ITEM_MAX_BID record so that we know what we need to process + // At this point we should always have an ITEM_MAX_BID record - // Make sure that the buyer has enough money to cover this charge - // We can add in a credit for the buyer's account - if (i_current_price > (buyer_credit + u_balance)) { - String msg = String.format("Buyer #%d does not have enough money in account to purchase Item #%s" + - "[maxBid=%.2f, balance=%.2f, credit=%.2f]", - ib_buyer_id, item_id, i_current_price, u_balance, buyer_credit); - throw new UserAbortException(msg); - } + long i_num_bids; + double i_current_price; + Timestamp i_end_date; + ItemStatus i_status; + long ib_id; + long ib_buyer_id; + double u_balance; - // Set item_purchase_id - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, insertPurchase, ip_id, ib_id, item_id, seller_id, currentTime)) { - preparedStatement.executeUpdate(); + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getItemInfo, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + if (!results.next()) { + String msg = "No ITEM_MAX_BID is available record for item " + item_id; + throw new UserAbortException(msg); } + int col = 1; + i_num_bids = results.getLong(col++); + i_current_price = results.getDouble(col++); + i_end_date = results.getTimestamp(col++); + i_status = ItemStatus.CLOSED; + ib_id = results.getLong(col++); + ib_buyer_id = results.getLong(col++); + u_balance = results.getDouble(col); + } + } + // Make sure that the buyer has enough money to cover this charge + // We can add in a credit for the buyer's account + if (i_current_price > (buyer_credit + u_balance)) { + String msg = + String.format( + "Buyer #%d does not have enough money in account to purchase Item #%s" + + "[maxBid=%.2f, balance=%.2f, credit=%.2f]", + ib_buyer_id, item_id, i_current_price, u_balance, buyer_credit); + throw new UserAbortException(msg); + } - // Update item status to close - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateItem, currentTime, item_id, seller_id)) { - preparedStatement.executeUpdate(); - } + // Set item_purchase_id + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, insertPurchase, ip_id, ib_id, item_id, seller_id, currentTime)) { + preparedStatement.executeUpdate(); + } - // And update this the USERACT_ITEM record to link it to the new ITEM_PURCHASE record - // If we don't have a record to update, just go ahead and create it - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUserItem, ip_id, ib_id, item_id, seller_id, - ib_buyer_id, item_id, seller_id)) { - int updated = preparedStatement.executeUpdate(); - if (updated == 0) { - try (PreparedStatement preparedStatement2 = this.getPreparedStatement(conn, insertUserItem, ib_buyer_id, item_id, seller_id, - ip_id, ib_id, item_id, seller_id, - currentTime)) { - preparedStatement2.executeUpdate(); - } - } - } - // Decrement the buyer's account - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUserBalance, -1 * (i_current_price) + buyer_credit, ib_buyer_id)) { - preparedStatement.executeUpdate(); - } + // Update item status to close + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateItem, currentTime, item_id, seller_id)) { + preparedStatement.executeUpdate(); + } - // And credit the seller's account - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, updateUserBalance, i_current_price, seller_id)) { - preparedStatement.executeUpdate(); - } - // Return a tuple of the item that we just updated - return new Object[]{ - // ITEM ID + // And update this the USERACT_ITEM record to link it to the new ITEM_PURCHASE record + // If we don't have a record to update, just go ahead and create it + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, + updateUserItem, + ip_id, + ib_id, + item_id, + seller_id, + ib_buyer_id, + item_id, + seller_id)) { + int updated = preparedStatement.executeUpdate(); + if (updated == 0) { + try (PreparedStatement preparedStatement2 = + this.getPreparedStatement( + conn, + insertUserItem, + ib_buyer_id, item_id, - // SELLER ID seller_id, - // ITEM_NAME - null, - // CURRENT PRICE - i_current_price, - // NUM BIDS - i_num_bids, - // END DATE - i_end_date, - // STATUS - i_status.ordinal(), - // PURCHASE ID ip_id, - // BID ID ib_id, - // BUYER ID - ib_buyer_id, - }; + item_id, + seller_id, + currentTime)) { + preparedStatement2.executeUpdate(); + } + } + } + // Decrement the buyer's account + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, updateUserBalance, -1 * (i_current_price) + buyer_credit, ib_buyer_id)) { + preparedStatement.executeUpdate(); + } + + // And credit the seller's account + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, updateUserBalance, i_current_price, seller_id)) { + preparedStatement.executeUpdate(); } -} \ No newline at end of file + // Return a tuple of the item that we just updated + return new Object[] { + // ITEM ID + item_id, + // SELLER ID + seller_id, + // ITEM_NAME + null, + // CURRENT PRICE + i_current_price, + // NUM BIDS + i_num_bids, + // END DATE + i_end_date, + // STATUS + i_status.ordinal(), + // PURCHASE ID + ip_id, + // BID ID + ib_id, + // BUYER ID + ib_buyer_id, + }; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/ResetDatabase.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/ResetDatabase.java index fea7a03b1..505ce815e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/ResetDatabase.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/ResetDatabase.java @@ -21,71 +21,74 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.ItemStatus; +import java.sql.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.*; - /** * Remove ITEM entries created after the loader started * * @author pavlo */ public class ResetDatabase extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(ResetDatabase.class); + private static final Logger LOG = LoggerFactory.getLogger(ResetDatabase.class); - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- - public final SQLStmt getLoaderStop = new SQLStmt( - "SELECT cfp_loader_stop FROM " + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE - ); + public final SQLStmt getLoaderStop = + new SQLStmt("SELECT cfp_loader_stop FROM " + AuctionMarkConstants.TABLENAME_CONFIG_PROFILE); - public final SQLStmt resetItems = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + - " SET i_status = ?, i_updated = ?" + - " WHERE i_status != ?" + - " AND i_updated > ? " - ); + public final SQLStmt resetItems = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " SET i_status = ?, i_updated = ?" + + " WHERE i_status != ?" + + " AND i_updated > ? "); - public final SQLStmt deleteItemPurchases = new SQLStmt( - "DELETE FROM " + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + - " WHERE ip_date > ?" - ); + public final SQLStmt deleteItemPurchases = + new SQLStmt( + "DELETE FROM " + AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + " WHERE ip_date > ?"); - public void run(Connection conn) throws SQLException { - int updated; + public void run(Connection conn) throws SQLException { + int updated; - // We have to get the loaderStopTimestamp from the CONFIG_PROFILE - // We will then reset any changes that were made after this timestamp - Timestamp loaderStop; + // We have to get the loaderStopTimestamp from the CONFIG_PROFILE + // We will then reset any changes that were made after this timestamp + Timestamp loaderStop; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getLoaderStop)) { - try (ResultSet rs = preparedStatement.executeQuery()) { - rs.next(); + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getLoaderStop)) { + try (ResultSet rs = preparedStatement.executeQuery()) { + rs.next(); - loaderStop = rs.getTimestamp(1); - } - } + loaderStop = rs.getTimestamp(1); + } + } - // Reset ITEM information - try (PreparedStatement stmt = this.getPreparedStatement(conn, resetItems, ItemStatus.OPEN.ordinal(), - loaderStop, - ItemStatus.OPEN.ordinal(), - loaderStop)) { - updated = stmt.executeUpdate(); - } - if (LOG.isDebugEnabled()) { - LOG.debug(AuctionMarkConstants.TABLENAME_ITEM + " Reset: {}", updated); - } + // Reset ITEM information + try (PreparedStatement stmt = + this.getPreparedStatement( + conn, + resetItems, + ItemStatus.OPEN.ordinal(), + loaderStop, + ItemStatus.OPEN.ordinal(), + loaderStop)) { + updated = stmt.executeUpdate(); + } + if (LOG.isDebugEnabled()) { + LOG.debug(AuctionMarkConstants.TABLENAME_ITEM + " Reset: {}", updated); + } - // Reset ITEM_PURCHASE - try (PreparedStatement stmt = this.getPreparedStatement(conn, deleteItemPurchases, loaderStop)) { - updated = stmt.executeUpdate(); - } - if (LOG.isDebugEnabled()) { - LOG.debug(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + " Reset: {}", updated); - } + // Reset ITEM_PURCHASE + try (PreparedStatement stmt = + this.getPreparedStatement(conn, deleteItemPurchases, loaderStop)) { + updated = stmt.executeUpdate(); + } + if (LOG.isDebugEnabled()) { + LOG.debug(AuctionMarkConstants.TABLENAME_ITEM_PURCHASE + " Reset: {}", updated); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UpdateItem.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UpdateItem.java index 60a968627..f476af5c8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UpdateItem.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UpdateItem.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; import com.oltpbenchmark.benchmarks.auctionmark.util.AuctionMarkUtil; - import java.sql.*; /** @@ -33,94 +31,106 @@ */ public class UpdateItem extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt updateItem = new SQLStmt( - "UPDATE " + AuctionMarkConstants.TABLENAME_ITEM + - " SET i_description = ?, " + - " i_updated = ? " + - " WHERE i_id = ? AND i_u_id = ? " - // " AND i_status = " + ItemStatus.OPEN.ordinal() - ); - - public final SQLStmt deleteItemAttribute = new SQLStmt( - "DELETE FROM " + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + - " WHERE ia_id = ? AND ia_i_id = ? AND ia_u_id = ?" - ); - - public final SQLStmt getMaxItemAttributeId = new SQLStmt( - "SELECT MAX(ia_id) FROM " + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + - " WHERE ia_i_id = ? AND ia_u_id = ?" - ); - - public final SQLStmt insertItemAttribute = new SQLStmt( - "INSERT INTO " + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + " (" + - "ia_id," + - "ia_i_id," + - "ia_u_id," + - "ia_gav_id," + - "ia_gag_id" + - ") VALUES (?, ?, ?, ?, ?)" - ); - - // ----------------------------------------------------------------- - // RUN METHOD - // ----------------------------------------------------------------- - - /** - * The buyer modifies an existing auction that is still available. - * The transaction will just update the description of the auction. - * A small percentage of the transactions will be for auctions that are - * uneditable (1.0%?); when this occurs, the transaction will abort. - */ - public boolean run(Connection conn, Timestamp[] benchmarkTimes, - String item_id, String seller_id, String description, - boolean delete_attribute, String[] add_attribute) throws SQLException { - final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); - - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateItem, description, currentTime, item_id, seller_id)) { - int updated = stmt.executeUpdate(); - if (updated == 0) { - throw new UserAbortException("Unable to update closed auction"); - } - } - - - // DELETE ITEM_ATTRIBUTE - if (delete_attribute) { - // Only delete the first (if it even exists) - String ia_id = AuctionMarkUtil.getUniqueElementId(item_id, 0); - try (PreparedStatement stmt = this.getPreparedStatement(conn, deleteItemAttribute, ia_id, item_id, seller_id)) { - stmt.executeUpdate(); - } - } - // ADD ITEM_ATTRIBUTE - if (add_attribute.length > 0 && !add_attribute[0].equals("-1")) { - - String gag_id = add_attribute[0]; - String gav_id = add_attribute[1]; - String ia_id = "-1"; - - try (PreparedStatement stmt = this.getPreparedStatement(conn, getMaxItemAttributeId, item_id, seller_id)) { - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - ia_id = results.getString(0); - } else { - ia_id = AuctionMarkUtil.getUniqueElementId(item_id, 0); - } - } - } - - - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertItemAttribute, ia_id, item_id, seller_id, gag_id, gav_id)) { - stmt.executeUpdate(); - } + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt updateItem = + new SQLStmt( + "UPDATE " + + AuctionMarkConstants.TABLENAME_ITEM + + " SET i_description = ?, " + + " i_updated = ? " + + " WHERE i_id = ? AND i_u_id = ? " + // " AND i_status = " + ItemStatus.OPEN.ordinal() + ); + + public final SQLStmt deleteItemAttribute = + new SQLStmt( + "DELETE FROM " + + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + + " WHERE ia_id = ? AND ia_i_id = ? AND ia_u_id = ?"); + + public final SQLStmt getMaxItemAttributeId = + new SQLStmt( + "SELECT MAX(ia_id) FROM " + + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + + " WHERE ia_i_id = ? AND ia_u_id = ?"); + + public final SQLStmt insertItemAttribute = + new SQLStmt( + "INSERT INTO " + + AuctionMarkConstants.TABLENAME_ITEM_ATTRIBUTE + + " (" + + "ia_id," + + "ia_i_id," + + "ia_u_id," + + "ia_gav_id," + + "ia_gag_id" + + ") VALUES (?, ?, ?, ?, ?)"); + + // ----------------------------------------------------------------- + // RUN METHOD + // ----------------------------------------------------------------- + + /** + * The buyer modifies an existing auction that is still available. The transaction will just + * update the description of the auction. A small percentage of the transactions will be for + * auctions that are uneditable (1.0%?); when this occurs, the transaction will abort. + */ + public boolean run( + Connection conn, + Timestamp[] benchmarkTimes, + String item_id, + String seller_id, + String description, + boolean delete_attribute, + String[] add_attribute) + throws SQLException { + final Timestamp currentTime = AuctionMarkUtil.getProcTimestamp(benchmarkTimes); + + try (PreparedStatement stmt = + this.getPreparedStatement(conn, updateItem, description, currentTime, item_id, seller_id)) { + int updated = stmt.executeUpdate(); + if (updated == 0) { + throw new UserAbortException("Unable to update closed auction"); + } + } + // DELETE ITEM_ATTRIBUTE + if (delete_attribute) { + // Only delete the first (if it even exists) + String ia_id = AuctionMarkUtil.getUniqueElementId(item_id, 0); + try (PreparedStatement stmt = + this.getPreparedStatement(conn, deleteItemAttribute, ia_id, item_id, seller_id)) { + stmt.executeUpdate(); + } + } + // ADD ITEM_ATTRIBUTE + if (add_attribute.length > 0 && !add_attribute[0].equals("-1")) { + + String gag_id = add_attribute[0]; + String gav_id = add_attribute[1]; + String ia_id = "-1"; + + try (PreparedStatement stmt = + this.getPreparedStatement(conn, getMaxItemAttributeId, item_id, seller_id)) { + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + ia_id = results.getString(0); + } else { + ia_id = AuctionMarkUtil.getUniqueElementId(item_id, 0); + } } + } - return (true); + try (PreparedStatement stmt = + this.getPreparedStatement( + conn, insertItemAttribute, ia_id, item_id, seller_id, gag_id, gav_id)) { + stmt.executeUpdate(); + } } -} \ No newline at end of file + return (true); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UserInfo.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UserInfo.java index 0b4782931..0cf11a7e9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UserInfo.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/procedures/UserInfo.java @@ -4,43 +4,49 @@ public class UserInfo { - private final List user; - private final List userFeedback; - private final List itemComments; - private final List sellerItems; - private final List buyerItems; - private final List watchedItems; - - public UserInfo(List user, List userFeedback, List itemComments, List sellerItems, List buyerItems, List watchedItems) { - this.user = user; - this.userFeedback = userFeedback; - this.itemComments = itemComments; - this.sellerItems = sellerItems; - this.buyerItems = buyerItems; - this.watchedItems = watchedItems; - } - - public List getUser() { - return user; - } - - public List getUserFeedback() { - return userFeedback; - } - - public List getItemComments() { - return itemComments; - } - - public List getSellerItems() { - return sellerItems; - } - - public List getBuyerItems() { - return buyerItems; - } - - public List getWatchedItems() { - return watchedItems; - } + private final List user; + private final List userFeedback; + private final List itemComments; + private final List sellerItems; + private final List buyerItems; + private final List watchedItems; + + public UserInfo( + List user, + List userFeedback, + List itemComments, + List sellerItems, + List buyerItems, + List watchedItems) { + this.user = user; + this.userFeedback = userFeedback; + this.itemComments = itemComments; + this.sellerItems = sellerItems; + this.buyerItems = buyerItems; + this.watchedItems = watchedItems; + } + + public List getUser() { + return user; + } + + public List getUserFeedback() { + return userFeedback; + } + + public List getItemComments() { + return itemComments; + } + + public List getSellerItems() { + return sellerItems; + } + + public List getBuyerItems() { + return buyerItems; + } + + public List getWatchedItems() { + return watchedItems; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java index 04410db77..e5f2616a0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/AuctionMarkUtil.java @@ -15,63 +15,60 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; +import java.sql.Timestamp; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Timestamp; - public abstract class AuctionMarkUtil { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkUtil.class); - - @SuppressWarnings("unused") - private static final long ITEM_ID_MASK = 0xFFFFFFFFFFFFFFL; // 56 bits (ITEM_ID) - - /** - * @param item_id - * @param idx - * @return - */ - public static String getUniqueElementId(String item_id, int idx) { - ItemId itemId = new ItemId(item_id); - UserId sellerId = itemId.getSellerId(); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(AuctionMarkUtil.class); - return new ItemId(sellerId, idx).encode(); - } + @SuppressWarnings("unused") + private static final long ITEM_ID_MASK = 0xFFFFFFFFFFFFFFL; // 56 bits (ITEM_ID) - /** - * @param benchmarkTimes - * @return - */ - public static Timestamp getProcTimestamp(Timestamp[] benchmarkTimes) { + /** + * @param item_id + * @param idx + * @return + */ + public static String getUniqueElementId(String item_id, int idx) { + ItemId itemId = new ItemId(item_id); + UserId sellerId = itemId.getSellerId(); + return new ItemId(sellerId, idx).encode(); + } - Timestamp tmp = new Timestamp(System.currentTimeMillis()); - long timestamp = getScaledTimestamp(benchmarkTimes[0], benchmarkTimes[1], tmp); - tmp.setTime(timestamp); + /** + * @param benchmarkTimes + * @return + */ + public static Timestamp getProcTimestamp(Timestamp[] benchmarkTimes) { - return (tmp); - } + Timestamp tmp = new Timestamp(System.currentTimeMillis()); + long timestamp = getScaledTimestamp(benchmarkTimes[0], benchmarkTimes[1], tmp); + tmp.setTime(timestamp); - /** - * @param benchmarkStart - * @param clientStart - * @param current - * @return - */ - public static long getScaledTimestamp(Timestamp benchmarkStart, Timestamp clientStart, Timestamp current) { - // First get the offset between the benchmarkStart and the clientStart - // We then subtract that value from the current time. This gives us the total elapsed - // time from the current time to the time that the benchmark start (with the gap - // from when the benchmark was loading data cut out) - long base = benchmarkStart.getTime(); - long offset = current.getTime() - (clientStart.getTime() - base); - long elapsed = (offset - base) * AuctionMarkConstants.TIME_SCALE_FACTOR; - return (base + elapsed); - } + return (tmp); + } + /** + * @param benchmarkStart + * @param clientStart + * @param current + * @return + */ + public static long getScaledTimestamp( + Timestamp benchmarkStart, Timestamp clientStart, Timestamp current) { + // First get the offset between the benchmarkStart and the clientStart + // We then subtract that value from the current time. This gives us the total elapsed + // time from the current time to the time that the benchmark start (with the gap + // from when the benchmark was loading data cut out) + long base = benchmarkStart.getTime(); + long offset = current.getTime() - (clientStart.getTime() - base); + long elapsed = (offset - base) * AuctionMarkConstants.TIME_SCALE_FACTOR; + return (base + elapsed); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/Category.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/Category.java index 2805e16bc..5c4035253 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/Category.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/Category.java @@ -15,60 +15,64 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import java.util.Objects; public class Category { - private final int categoryID; - private final Integer parentCategoryID; - private final int itemCount; - private final String name; - private final boolean isLeaf; + private final int categoryID; + private final Integer parentCategoryID; + private final int itemCount; + private final String name; + private final boolean isLeaf; - public Category(int categoryID, String name, Integer parentCategoryID, int itemCount, boolean isLeaf) { - this.categoryID = categoryID; - this.name = name; - this.parentCategoryID = parentCategoryID; - this.itemCount = itemCount; - this.isLeaf = isLeaf; - } + public Category( + int categoryID, String name, Integer parentCategoryID, int itemCount, boolean isLeaf) { + this.categoryID = categoryID; + this.name = name; + this.parentCategoryID = parentCategoryID; + this.itemCount = itemCount; + this.isLeaf = isLeaf; + } - public String getName() { - return this.name; - } + public String getName() { + return this.name; + } - public int getCategoryID() { - return this.categoryID; - } + public int getCategoryID() { + return this.categoryID; + } - public Integer getParentCategoryID() { - return this.parentCategoryID; - } + public Integer getParentCategoryID() { + return this.parentCategoryID; + } - public int getItemCount() { - return this.itemCount; - } + public int getItemCount() { + return this.itemCount; + } - public boolean isLeaf() { - return this.isLeaf; - } + public boolean isLeaf() { + return this.isLeaf; + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Category category = (Category) o; - return categoryID == category.categoryID && itemCount == category.itemCount && isLeaf == category.isLeaf && Objects.equals(parentCategoryID, category.parentCategoryID) && Objects.equals(name, category.name); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public int hashCode() { - return Objects.hash(categoryID, parentCategoryID, itemCount, name, isLeaf); + if (o == null || getClass() != o.getClass()) { + return false; } -} \ No newline at end of file + Category category = (Category) o; + return categoryID == category.categoryID + && itemCount == category.itemCount + && isLeaf == category.isLeaf + && Objects.equals(parentCategoryID, category.parentCategoryID) + && Objects.equals(name, category.name); + } + + @Override + public int hashCode() { + return Objects.hash(categoryID, parentCategoryID, itemCount, name, isLeaf); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java index c06f25e42..a67cb5ebb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/CategoryParser.java @@ -15,109 +15,98 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; -import org.apache.commons.io.IOUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.InputStream; import java.nio.charset.Charset; import java.util.List; import java.util.Map; import java.util.TreeMap; - +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class CategoryParser { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(CategoryParser.class); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(CategoryParser.class); - Map _categoryMap; - private int _nextCategoryID; - String _fileName; + Map _categoryMap; + private int _nextCategoryID; + String _fileName; - public CategoryParser() { + public CategoryParser() { - _categoryMap = new TreeMap<>(); - _nextCategoryID = 0; + _categoryMap = new TreeMap<>(); + _nextCategoryID = 0; + final String path = "/benchmarks/auctionmark/table.category"; - final String path = "/benchmarks/auctionmark/table.category"; + try (InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { - try (InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { + List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); + for (String line : lines) { + extractCategory(line); + } - List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); - for (String line : lines) { - extractCategory(line); - } + } catch (Exception ex) { + throw new RuntimeException("Failed to load in category file", ex); + } + } + + public void extractCategory(String s) { + String[] tokens = s.split("\t"); + int itemCount = Integer.parseInt(tokens[5]); + StringBuilder sb = new StringBuilder(); + for (int i = 0; i <= 4; i++) { + if (!tokens[i].trim().isEmpty()) { + sb.append(tokens[i].trim()).append("/"); + } else { + break; + } + } + String categoryName = sb.toString(); + if (categoryName.length() > 0) { + categoryName = categoryName.substring(0, categoryName.length() - 1); + } - } catch (Exception ex) { - throw new RuntimeException("Failed to load in category file", ex); - } + addNewCategory(categoryName, itemCount, true); + } - } + public Category addNewCategory(String fullCategoryName, int itemCount, boolean isLeaf) { + Category category = null; + Category parentCategory = null; - public void extractCategory(String s) { - String[] tokens = s.split("\t"); - int itemCount = Integer.parseInt(tokens[5]); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i <= 4; i++) { - if (!tokens[i].trim().isEmpty()) { - sb.append(tokens[i].trim()) - .append("/"); - } else { - break; - } - } - String categoryName = sb.toString(); - if (categoryName.length() > 0) { - categoryName = categoryName.substring(0, categoryName.length() - 1); - } - - addNewCategory(categoryName, itemCount, true); - } + String categoryName = fullCategoryName; + String parentCategoryName = ""; + Integer parentCategoryID = null; - public Category addNewCategory(String fullCategoryName, int itemCount, boolean isLeaf) { - Category category = null; - Category parentCategory = null; - - String categoryName = fullCategoryName; - String parentCategoryName = ""; - Integer parentCategoryID = null; - - if (categoryName.indexOf('/') != -1) { - int separatorIndex = fullCategoryName.lastIndexOf('/'); - parentCategoryName = fullCategoryName.substring(0, separatorIndex); - categoryName = fullCategoryName.substring(separatorIndex + 1); - } - /* - System.out.println("parentCat name = " + parentCategoryName); - System.out.println("cat name = " + categoryName); - */ - if (_categoryMap.containsKey(parentCategoryName)) { - parentCategory = _categoryMap.get(parentCategoryName); - } else if (!parentCategoryName.isEmpty()) { - parentCategory = addNewCategory(parentCategoryName, 0, false); - } - - if (parentCategory != null) { - parentCategoryID = parentCategory.getCategoryID(); - } - - category = new Category(_nextCategoryID++, - categoryName, - parentCategoryID, - itemCount, - isLeaf); - - _categoryMap.put(fullCategoryName, category); - - return category; + if (categoryName.indexOf('/') != -1) { + int separatorIndex = fullCategoryName.lastIndexOf('/'); + parentCategoryName = fullCategoryName.substring(0, separatorIndex); + categoryName = fullCategoryName.substring(separatorIndex + 1); + } + /* + System.out.println("parentCat name = " + parentCategoryName); + System.out.println("cat name = " + categoryName); + */ + if (_categoryMap.containsKey(parentCategoryName)) { + parentCategory = _categoryMap.get(parentCategoryName); + } else if (!parentCategoryName.isEmpty()) { + parentCategory = addNewCategory(parentCategoryName, 0, false); } - public Map getCategoryMap() { - return _categoryMap; + if (parentCategory != null) { + parentCategoryID = parentCategory.getCategoryID(); } + category = new Category(_nextCategoryID++, categoryName, parentCategoryID, itemCount, isLeaf); + + _categoryMap.put(fullCategoryName, category); + + return category; + } + + public Map getCategoryMap() { + return _categoryMap; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeGroupId.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeGroupId.java index 1df7f063a..925ce0304 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeGroupId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeGroupId.java @@ -15,91 +15,92 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.CompositeId; - import java.util.Comparator; import java.util.Objects; import java.util.stream.IntStream; -public final class GlobalAttributeGroupId extends CompositeId implements Comparable { - - private static final int[] COMPOSITE_BITS = { - INT_MAX_DIGITS, // CATEGORY - INT_MAX_DIGITS, // ID - INT_MAX_DIGITS // COUNT - }; - - public static final int ID_LENGTH = IntStream.of(COMPOSITE_BITS).sum(); - - private int category_id; - private int id; - private int count; - - public GlobalAttributeGroupId(int category_id, int id, int count) { - this.category_id = category_id; - this.id = id; - this.count = count; +public final class GlobalAttributeGroupId extends CompositeId + implements Comparable { + + private static final int[] COMPOSITE_BITS = { + INT_MAX_DIGITS, // CATEGORY + INT_MAX_DIGITS, // ID + INT_MAX_DIGITS // COUNT + }; + + public static final int ID_LENGTH = IntStream.of(COMPOSITE_BITS).sum(); + + private int category_id; + private int id; + private int count; + + public GlobalAttributeGroupId(int category_id, int id, int count) { + this.category_id = category_id; + this.id = id; + this.count = count; + } + + public GlobalAttributeGroupId(String composite_id) { + this.decode(composite_id); + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.category_id = Integer.parseInt(values[0]); + this.id = Integer.parseInt(values[1]); + this.count = Integer.parseInt(values[2]); + } + + @Override + public String[] toArray() { + return (new String[] { + Integer.toString(this.category_id), Integer.toString(this.id), Integer.toString(this.count) + }); + } + + public int getCategoryId() { + return (this.category_id); + } + + protected int getId() { + return (this.id); + } + + public int getCount() { + return (this.count); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public GlobalAttributeGroupId(String composite_id) { - this.decode(composite_id); - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.category_id = Integer.parseInt(values[0]); - this.id = Integer.parseInt(values[1]); - this.count = Integer.parseInt(values[2]); - } - - @Override - public String[] toArray() { - return (new String[]{Integer.toString(this.category_id), Integer.toString(this.id), Integer.toString(this.count)}); - } - - public int getCategoryId() { - return (this.category_id); - } - - protected int getId() { - return (this.id); - } - - public int getCount() { - return (this.count); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GlobalAttributeGroupId that = (GlobalAttributeGroupId) o; - return category_id == that.category_id && id == that.id && count == that.count; - } - - @Override - public int hashCode() { - return Objects.hash(category_id, id, count); - } - - @Override - public int compareTo(GlobalAttributeGroupId o) { - return Comparator.comparingInt(GlobalAttributeGroupId::getCategoryId) - .thenComparingInt(GlobalAttributeGroupId::getId) - .thenComparingInt(GlobalAttributeGroupId::getCount) - .compare(this, o); + if (o == null || getClass() != o.getClass()) { + return false; } + GlobalAttributeGroupId that = (GlobalAttributeGroupId) o; + return category_id == that.category_id && id == that.id && count == that.count; + } + + @Override + public int hashCode() { + return Objects.hash(category_id, id, count); + } + + @Override + public int compareTo(GlobalAttributeGroupId o) { + return Comparator.comparingInt(GlobalAttributeGroupId::getCategoryId) + .thenComparingInt(GlobalAttributeGroupId::getId) + .thenComparingInt(GlobalAttributeGroupId::getCount) + .compare(this, o); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeValueId.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeValueId.java index 947156141..e4ad78050 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeValueId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/GlobalAttributeValueId.java @@ -15,79 +15,78 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.CompositeId; - import java.util.Comparator; import java.util.Objects; -public class GlobalAttributeValueId extends CompositeId implements Comparable { - - private static final int[] COMPOSITE_BITS = { - GlobalAttributeGroupId.ID_LENGTH, // GROUP_ATTRIBUTE_ID - INT_MAX_DIGITS // ID - }; - - private String group_attribute_id; - private int id; - - public GlobalAttributeValueId(String group_attribute_id, int id) { - this.group_attribute_id = group_attribute_id; - this.id = id; - } - - public GlobalAttributeValueId(GlobalAttributeGroupId group_attribute_id, int id) { - this(group_attribute_id.encode(), id); - } - - @Override - public String encode() { - return (super.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.group_attribute_id = values[0]; - this.id = Integer.parseInt(values[1]); +public class GlobalAttributeValueId extends CompositeId + implements Comparable { + + private static final int[] COMPOSITE_BITS = { + GlobalAttributeGroupId.ID_LENGTH, // GROUP_ATTRIBUTE_ID + INT_MAX_DIGITS // ID + }; + + private String group_attribute_id; + private int id; + + public GlobalAttributeValueId(String group_attribute_id, int id) { + this.group_attribute_id = group_attribute_id; + this.id = id; + } + + public GlobalAttributeValueId(GlobalAttributeGroupId group_attribute_id, int id) { + this(group_attribute_id.encode(), id); + } + + @Override + public String encode() { + return (super.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.group_attribute_id = values[0]; + this.id = Integer.parseInt(values[1]); + } + + @Override + public String[] toArray() { + return (new String[] {this.group_attribute_id, Integer.toString(this.id)}); + } + + public GlobalAttributeGroupId getGlobalAttributeGroup() { + return new GlobalAttributeGroupId(this.group_attribute_id); + } + + protected int getId() { + return (this.id); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public String[] toArray() { - return (new String[]{this.group_attribute_id, Integer.toString(this.id)}); - } - - public GlobalAttributeGroupId getGlobalAttributeGroup() { - return new GlobalAttributeGroupId(this.group_attribute_id); - } - - protected int getId() { - return (this.id); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GlobalAttributeValueId that = (GlobalAttributeValueId) o; - return id == that.id && Objects.equals(group_attribute_id, that.group_attribute_id); - } - - @Override - public int hashCode() { - return Objects.hash(group_attribute_id, id); - } - - @Override - public int compareTo(GlobalAttributeValueId o) { - return Comparator.comparing(GlobalAttributeValueId::getGlobalAttributeGroup) - .thenComparingInt(GlobalAttributeValueId::getId) - .compare(this, o); + if (o == null || getClass() != o.getClass()) { + return false; } + GlobalAttributeValueId that = (GlobalAttributeValueId) o; + return id == that.id && Objects.equals(group_attribute_id, that.group_attribute_id); + } + + @Override + public int hashCode() { + return Objects.hash(group_attribute_id, id); + } + + @Override + public int compareTo(GlobalAttributeValueId o) { + return Comparator.comparing(GlobalAttributeValueId::getGlobalAttributeGroup) + .thenComparingInt(GlobalAttributeValueId::getId) + .compare(this, o); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemCommentResponse.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemCommentResponse.java index 9f8b706a6..aa88e8b60 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemCommentResponse.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemCommentResponse.java @@ -21,42 +21,44 @@ public class ItemCommentResponse { - private final Long commentId; - private final String itemId; - private final String sellerId; - - public ItemCommentResponse(Long commentId, String itemId, String sellerId) { - this.commentId = commentId; - this.itemId = itemId; - this.sellerId = sellerId; - } + private final Long commentId; + private final String itemId; + private final String sellerId; - public Long getCommentId() { - return commentId; - } + public ItemCommentResponse(Long commentId, String itemId, String sellerId) { + this.commentId = commentId; + this.itemId = itemId; + this.sellerId = sellerId; + } - public String getItemId() { - return itemId; - } + public Long getCommentId() { + return commentId; + } - public String getSellerId() { - return sellerId; - } + public String getItemId() { + return itemId; + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ItemCommentResponse that = (ItemCommentResponse) o; - return Objects.equals(commentId, that.commentId) && Objects.equals(itemId, that.itemId) && Objects.equals(sellerId, that.sellerId); - } + public String getSellerId() { + return sellerId; + } - @Override - public int hashCode() { - return Objects.hash(commentId, itemId, sellerId); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; } + ItemCommentResponse that = (ItemCommentResponse) o; + return Objects.equals(commentId, that.commentId) + && Objects.equals(itemId, that.itemId) + && Objects.equals(sellerId, that.sellerId); + } + + @Override + public int hashCode() { + return Objects.hash(commentId, itemId, sellerId); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemId.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemId.java index ddd99b00d..bc6681c3f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemId.java @@ -15,106 +15,104 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.CompositeId; - import java.util.Comparator; import java.util.Objects; /** - * Composite Item Id - * First 48-bits are the seller's USER.U_ID - * Last 16-bits are the item counter for this particular user + * Composite Item Id First 48-bits are the seller's USER.U_ID Last 16-bits are the item counter for + * this particular user * * @author pavlo */ public final class ItemId extends CompositeId implements Comparable { - private static final int[] COMPOSITE_BITS = { - UserId.ID_LENGTH, // SELLER_ID - INT_MAX_DIGITS // ITEM_CTR - }; - - private UserId seller_id; - private int item_ctr; - - public ItemId(UserId seller_id, int item_ctr) { - this.seller_id = seller_id; - this.item_ctr = item_ctr; - } - - - public ItemId(String composite_id) { - this.decode(composite_id); - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.seller_id = new UserId(values[0]); - this.item_ctr = Integer.parseInt(values[1]); - } - - @Override - public String[] toArray() { - return (new String[]{this.seller_id.encode(), Integer.toString(this.item_ctr)}); + private static final int[] COMPOSITE_BITS = { + UserId.ID_LENGTH, // SELLER_ID + INT_MAX_DIGITS // ITEM_CTR + }; + + private UserId seller_id; + private int item_ctr; + + public ItemId(UserId seller_id, int item_ctr) { + this.seller_id = seller_id; + this.item_ctr = item_ctr; + } + + public ItemId(String composite_id) { + this.decode(composite_id); + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.seller_id = new UserId(values[0]); + this.item_ctr = Integer.parseInt(values[1]); + } + + @Override + public String[] toArray() { + return (new String[] {this.seller_id.encode(), Integer.toString(this.item_ctr)}); + } + + /** + * Return the user id portion of this ItemId + * + * @return the user_id + */ + public UserId getSellerId() { + return (this.seller_id); + } + + /** + * Return the item counter id for this user in the ItemId + * + * @return the item_ctr + */ + public int getItemCtr() { + return (this.item_ctr); + } + + @Override + public String toString() { + return (String.format( + "ItemId", + this.item_ctr, this.seller_id, this.encode())); + } + + public static String toString(String itemId) { + return new ItemId(itemId).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * Return the user id portion of this ItemId - * - * @return the user_id - */ - public UserId getSellerId() { - return (this.seller_id); - } - - /** - * Return the item counter id for this user in the ItemId - * - * @return the item_ctr - */ - public int getItemCtr() { - return (this.item_ctr); - } - - @Override - public String toString() { - return (String.format("ItemId", this.item_ctr, this.seller_id, this.encode())); - } - - public static String toString(String itemId) { - return new ItemId(itemId).toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ItemId itemId = (ItemId) o; - return item_ctr == itemId.item_ctr && Objects.equals(seller_id, itemId.seller_id); - } - - @Override - public int hashCode() { - return Objects.hash(seller_id, item_ctr); - } - - @Override - public int compareTo(ItemId o) { - return Comparator.comparing(ItemId::getSellerId) - .thenComparingInt(ItemId::getItemCtr) - .compare(this, o); + if (o == null || getClass() != o.getClass()) { + return false; } -} \ No newline at end of file + ItemId itemId = (ItemId) o; + return item_ctr == itemId.item_ctr && Objects.equals(seller_id, itemId.seller_id); + } + + @Override + public int hashCode() { + return Objects.hash(seller_id, item_ctr); + } + + @Override + public int compareTo(ItemId o) { + return Comparator.comparing(ItemId::getSellerId) + .thenComparingInt(ItemId::getItemCtr) + .compare(this, o); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemInfo.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemInfo.java index 0cbdfd30e..ea86561f2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemInfo.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemInfo.java @@ -15,109 +15,116 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import java.sql.Timestamp; import java.util.Objects; public class ItemInfo implements Comparable { - private ItemId itemId; - private Float currentPrice; - private Timestamp endDate; - private long numBids = 0; - private ItemStatus status = null; - - public ItemInfo(ItemId id, Double currentPrice, Timestamp endDate, int numBids) { - this.itemId = id; - this.currentPrice = (currentPrice != null ? currentPrice.floatValue() : null); - this.endDate = endDate; - this.numBids = numBids; - } - - - public ItemId getItemId() { - return (this.itemId); - } - - public UserId getSellerId() { - return (this.itemId.getSellerId()); - } - - public boolean hasCurrentPrice() { - return (this.currentPrice != null); - } - - public Float getCurrentPrice() { - return currentPrice; - } - - public boolean hasEndDate() { - return (this.endDate != null); - } - - public Timestamp getEndDate() { - return endDate; - } - - public void setItemId(ItemId itemId) { - this.itemId = itemId; - } - - public void setCurrentPrice(Float currentPrice) { - this.currentPrice = currentPrice; - } - - public void setEndDate(Timestamp endDate) { - this.endDate = endDate; - } - - public long getNumBids() { - return numBids; - } - - public void setNumBids(long numBids) { - this.numBids = numBids; - } - - public ItemStatus getStatus() { - return status; - } - - public void setStatus(ItemStatus status) { - this.status = status; - } - - @Override - public int compareTo(ItemInfo o) { - return this.itemId.compareTo(o.itemId); - } - - @Override - public String toString() { - return "ItemInfo{" + - "itemId=" + itemId + - ", currentPrice=" + currentPrice + - ", endDate=" + endDate + - ", numBids=" + numBids + - ", status=" + status + - '}'; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ItemInfo itemInfo = (ItemInfo) o; - return numBids == itemInfo.numBids && Objects.equals(itemId, itemInfo.itemId) && Objects.equals(currentPrice, itemInfo.currentPrice) && Objects.equals(endDate, itemInfo.endDate) && status == itemInfo.status; - } - - @Override - public int hashCode() { - return Objects.hash(itemId, currentPrice, endDate, numBids, status); - } -} \ No newline at end of file + private ItemId itemId; + private Float currentPrice; + private Timestamp endDate; + private long numBids = 0; + private ItemStatus status = null; + + public ItemInfo(ItemId id, Double currentPrice, Timestamp endDate, int numBids) { + this.itemId = id; + this.currentPrice = (currentPrice != null ? currentPrice.floatValue() : null); + this.endDate = endDate; + this.numBids = numBids; + } + + public ItemId getItemId() { + return (this.itemId); + } + + public UserId getSellerId() { + return (this.itemId.getSellerId()); + } + + public boolean hasCurrentPrice() { + return (this.currentPrice != null); + } + + public Float getCurrentPrice() { + return currentPrice; + } + + public boolean hasEndDate() { + return (this.endDate != null); + } + + public Timestamp getEndDate() { + return endDate; + } + + public void setItemId(ItemId itemId) { + this.itemId = itemId; + } + + public void setCurrentPrice(Float currentPrice) { + this.currentPrice = currentPrice; + } + + public void setEndDate(Timestamp endDate) { + this.endDate = endDate; + } + + public long getNumBids() { + return numBids; + } + + public void setNumBids(long numBids) { + this.numBids = numBids; + } + + public ItemStatus getStatus() { + return status; + } + + public void setStatus(ItemStatus status) { + this.status = status; + } + + @Override + public int compareTo(ItemInfo o) { + return this.itemId.compareTo(o.itemId); + } + + @Override + public String toString() { + return "ItemInfo{" + + "itemId=" + + itemId + + ", currentPrice=" + + currentPrice + + ", endDate=" + + endDate + + ", numBids=" + + numBids + + ", status=" + + status + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ItemInfo itemInfo = (ItemInfo) o; + return numBids == itemInfo.numBids + && Objects.equals(itemId, itemInfo.itemId) + && Objects.equals(currentPrice, itemInfo.currentPrice) + && Objects.equals(endDate, itemInfo.endDate) + && status == itemInfo.status; + } + + @Override + public int hashCode() { + return Objects.hash(itemId, currentPrice, endDate, numBids, status); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemStatus.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemStatus.java index 40ae599d6..b3ff202df 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemStatus.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/ItemStatus.java @@ -23,22 +23,22 @@ * @author pavlo */ public enum ItemStatus { - OPEN(false), - ENDING_SOON(true), // Only used internally - WAITING_FOR_PURCHASE(false), - CLOSED(false); + OPEN(false), + ENDING_SOON(true), // Only used internally + WAITING_FOR_PURCHASE(false), + CLOSED(false); - private final boolean internal; + private final boolean internal; - ItemStatus(boolean internal) { - this.internal = internal; - } + ItemStatus(boolean internal) { + this.internal = internal; + } - public boolean isInternal() { - return internal; - } + public boolean isInternal() { + return internal; + } - public static ItemStatus get(long idx) { - return (values()[(int) idx]); - } -} \ No newline at end of file + public static ItemStatus get(long idx) { + return (values()[(int) idx]); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/LoaderItemInfo.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/LoaderItemInfo.java index 101c869fd..95700d3d8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/LoaderItemInfo.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/LoaderItemInfo.java @@ -15,232 +15,229 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.CollectionUtil; import com.oltpbenchmark.util.Histogram; import com.oltpbenchmark.util.StringUtil; -import org.apache.commons.collections4.map.ListOrderedMap; - import java.lang.reflect.Field; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import org.apache.commons.collections4.map.ListOrderedMap; public class LoaderItemInfo extends ItemInfo { - private final List bids = new ArrayList<>(); - private final Histogram bidderHistogram = new Histogram<>(); + private final List bids = new ArrayList<>(); + private final Histogram bidderHistogram = new Histogram<>(); + + private short numImages; + private short numAttributes; + private short numComments; + private int numWatches; + private Timestamp startDate; + private Timestamp purchaseDate; + private float initialPrice; + private UserId lastBidderId; // if null, then no bidder + + public LoaderItemInfo(ItemId id, Timestamp endDate, int numBids) { + super(id, null, endDate, numBids); + this.numImages = 0; + this.numAttributes = 0; + this.numComments = 0; + this.numWatches = 0; + this.startDate = null; + this.purchaseDate = null; + this.initialPrice = 0; + this.lastBidderId = null; + } + + public short getNumImages() { + return numImages; + } + + public void setNumImages(short numImages) { + this.numImages = numImages; + } + + public short getNumAttributes() { + return numAttributes; + } + + public void setNumAttributes(short numAttributes) { + this.numAttributes = numAttributes; + } + + public short getNumComments() { + return numComments; + } + + public void setNumComments(short numComments) { + this.numComments = numComments; + } + + public int getNumWatches() { + return numWatches; + } + + public void setNumWatches(int numWatches) { + this.numWatches = numWatches; + } + + public Timestamp getStartDate() { + return startDate; + } + + public void setStartDate(Timestamp startDate) { + this.startDate = startDate; + } - private short numImages; - private short numAttributes; - private short numComments; - private int numWatches; - private Timestamp startDate; - private Timestamp purchaseDate; - private float initialPrice; - private UserId lastBidderId; // if null, then no bidder + public Timestamp getPurchaseDate() { + return purchaseDate; + } - public LoaderItemInfo(ItemId id, Timestamp endDate, int numBids) { - super(id, null, endDate, numBids); - this.numImages = 0; - this.numAttributes = 0; - this.numComments = 0; - this.numWatches = 0; - this.startDate = null; - this.purchaseDate = null; - this.initialPrice = 0; - this.lastBidderId = null; - } + public void setPurchaseDate(Timestamp purchaseDate) { + this.purchaseDate = purchaseDate; + } + public float getInitialPrice() { + return initialPrice; + } - public short getNumImages() { - return numImages; - } + public void setInitialPrice(float initialPrice) { + this.initialPrice = initialPrice; + } - public void setNumImages(short numImages) { - this.numImages = numImages; - } + public UserId getLastBidderId() { + return lastBidderId; + } - public short getNumAttributes() { - return numAttributes; - } + public void setLastBidderId(UserId lastBidderId) { + this.lastBidderId = lastBidderId; + } - public void setNumAttributes(short numAttributes) { - this.numAttributes = numAttributes; - } + public int getBidCount() { + return (this.bids.size()); + } - public short getNumComments() { - return numComments; - } + public Bid getNextBid(long id, UserId bidder_id) { - public void setNumComments(short numComments) { - this.numComments = numComments; - } + Bid b = new Bid(id, bidder_id); + this.bids.add(b); - public int getNumWatches() { - return numWatches; - } + this.bidderHistogram.put(bidder_id); - public void setNumWatches(int numWatches) { - this.numWatches = numWatches; - } + return (b); + } - public Timestamp getStartDate() { - return startDate; + public Bid getLastBid() { + return (CollectionUtil.last(this.bids)); + } + + public Histogram getBidderHistogram() { + return bidderHistogram; + } + + @Override + public String toString() { + Class hints_class = this.getClass(); + ListOrderedMap m = new ListOrderedMap<>(); + for (Field f : hints_class.getDeclaredFields()) { + String key = f.getName().toUpperCase(); + Object val = null; + try { + val = f.get(this); + } catch (IllegalAccessException ex) { + val = ex.getMessage(); + } + m.put(key, val); } + return (StringUtil.formatMaps(m)); + } + + public class Bid { + private final long id; + private final UserId bidderId; + private float maxBid; + private Timestamp createDate; + private Timestamp updateDate; + private boolean buyer_feedback = false; + private boolean seller_feedback = false; - public void setStartDate(Timestamp startDate) { - this.startDate = startDate; + private Bid(long id, UserId bidderId) { + this.id = id; + this.bidderId = bidderId; + this.maxBid = 0; + this.createDate = null; + this.updateDate = null; } - public Timestamp getPurchaseDate() { - return purchaseDate; + public long getId() { + return id; } - public void setPurchaseDate(Timestamp purchaseDate) { - this.purchaseDate = purchaseDate; + public UserId getBidderId() { + return bidderId; } - public float getInitialPrice() { - return initialPrice; + public float getMaxBid() { + return maxBid; } - public void setInitialPrice(float initialPrice) { - this.initialPrice = initialPrice; + public void setMaxBid(float maxBid) { + this.maxBid = maxBid; } - public UserId getLastBidderId() { - return lastBidderId; + public Timestamp getCreateDate() { + return createDate; } - public void setLastBidderId(UserId lastBidderId) { - this.lastBidderId = lastBidderId; + public void setCreateDate(Timestamp createDate) { + this.createDate = createDate; } - public int getBidCount() { - return (this.bids.size()); + public Timestamp getUpdateDate() { + return updateDate; } - public Bid getNextBid(long id, UserId bidder_id) { + public void setUpdateDate(Timestamp updateDate) { + this.updateDate = updateDate; + } - Bid b = new Bid(id, bidder_id); - this.bids.add(b); + public boolean isBuyer_feedback() { + return buyer_feedback; + } - this.bidderHistogram.put(bidder_id); + public void setBuyer_feedback(boolean buyer_feedback) { + this.buyer_feedback = buyer_feedback; + } - return (b); + public boolean isSeller_feedback() { + return seller_feedback; } - public Bid getLastBid() { - return (CollectionUtil.last(this.bids)); + public void setSeller_feedback(boolean seller_feedback) { + this.seller_feedback = seller_feedback; } - public Histogram getBidderHistogram() { - return bidderHistogram; + public LoaderItemInfo getLoaderItemInfo() { + return (LoaderItemInfo.this); } @Override public String toString() { - Class hints_class = this.getClass(); - ListOrderedMap m = new ListOrderedMap<>(); - for (Field f : hints_class.getDeclaredFields()) { - String key = f.getName().toUpperCase(); - Object val = null; - try { - val = f.get(this); - } catch (IllegalAccessException ex) { - val = ex.getMessage(); - } - m.put(key, val); - } - return (StringUtil.formatMaps(m)); - } - - public class Bid { - private final long id; - private final UserId bidderId; - private float maxBid; - private Timestamp createDate; - private Timestamp updateDate; - private boolean buyer_feedback = false; - private boolean seller_feedback = false; - - private Bid(long id, UserId bidderId) { - this.id = id; - this.bidderId = bidderId; - this.maxBid = 0; - this.createDate = null; - this.updateDate = null; - } - - public long getId() { - return id; - } - - public UserId getBidderId() { - return bidderId; - } - - public float getMaxBid() { - return maxBid; - } - - public void setMaxBid(float maxBid) { - this.maxBid = maxBid; - } - - public Timestamp getCreateDate() { - return createDate; - } - - public void setCreateDate(Timestamp createDate) { - this.createDate = createDate; - } - - public Timestamp getUpdateDate() { - return updateDate; - } - - public void setUpdateDate(Timestamp updateDate) { - this.updateDate = updateDate; - } - - public boolean isBuyer_feedback() { - return buyer_feedback; - } - - public void setBuyer_feedback(boolean buyer_feedback) { - this.buyer_feedback = buyer_feedback; - } - - public boolean isSeller_feedback() { - return seller_feedback; - } - - public void setSeller_feedback(boolean seller_feedback) { - this.seller_feedback = seller_feedback; - } - - public LoaderItemInfo getLoaderItemInfo() { - return (LoaderItemInfo.this); - } - - @Override - public String toString() { - Class hints_class = this.getClass(); - ListOrderedMap m = new ListOrderedMap<>(); - for (Field f : hints_class.getFields()) { - String key = f.getName().toUpperCase(); - Object val = null; - try { - val = f.get(this); - } catch (IllegalAccessException ex) { - val = ex.getMessage(); - } - m.put(key, val); - } - return (StringUtil.formatMaps(m)); - } - } -} \ No newline at end of file + Class hints_class = this.getClass(); + ListOrderedMap m = new ListOrderedMap<>(); + for (Field f : hints_class.getFields()) { + String key = f.getName().toUpperCase(); + Object val = null; + try { + val = f.get(this); + } catch (IllegalAccessException ex) { + val = ex.getMessage(); + } + m.put(key, val); + } + return (StringUtil.formatMaps(m)); + } + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserId.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserId.java index 428fca04d..929f7e889 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserId.java @@ -15,113 +15,104 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.CompositeId; - import java.util.Comparator; import java.util.Objects; import java.util.stream.IntStream; public final class UserId extends CompositeId implements Comparable { - private static final int[] COMPOSITE_BITS = { - INT_MAX_DIGITS, // ITEM_COUNT - INT_MAX_DIGITS // OFFSET - }; - - public static final int ID_LENGTH = IntStream.of(COMPOSITE_BITS).sum(); - - /** - * The size index is the position in the histogram for the number - * of users per items size - */ - private int itemCount; - - /** - * The offset is based on the number of users that exist at a given size index - */ - private int offset; - - - /** - * Constructor - * - * @param itemCount - * @param offset - */ - public UserId(int itemCount, int offset) { - this.itemCount = itemCount; - this.offset = offset; - } - - /** - * Constructor - * Converts a composite id generated by encode() into the full object - * - * @param composite_id - */ - public UserId(String composite_id) { - this.decode(composite_id); - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.itemCount = Integer.parseInt(values[0]); - this.offset = Integer.parseInt(values[1]); - } - - @Override - public String[] toArray() { - return (new String[]{Integer.toString(this.itemCount), Integer.toString(this.offset)}); - } - - public int getItemCount() { - return this.itemCount; + private static final int[] COMPOSITE_BITS = { + INT_MAX_DIGITS, // ITEM_COUNT + INT_MAX_DIGITS // OFFSET + }; + + public static final int ID_LENGTH = IntStream.of(COMPOSITE_BITS).sum(); + + /** The size index is the position in the histogram for the number of users per items size */ + private int itemCount; + + /** The offset is based on the number of users that exist at a given size index */ + private int offset; + + /** + * Constructor + * + * @param itemCount + * @param offset + */ + public UserId(int itemCount, int offset) { + this.itemCount = itemCount; + this.offset = offset; + } + + /** + * Constructor Converts a composite id generated by encode() into the full object + * + * @param composite_id + */ + public UserId(String composite_id) { + this.decode(composite_id); + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.itemCount = Integer.parseInt(values[0]); + this.offset = Integer.parseInt(values[1]); + } + + @Override + public String[] toArray() { + return (new String[] {Integer.toString(this.itemCount), Integer.toString(this.offset)}); + } + + public int getItemCount() { + return this.itemCount; + } + + public int getOffset() { + return this.offset; + } + + @Override + public String toString() { + return String.format( + "UserId", this.itemCount, this.offset, this.encode()); + } + + public static String toString(String userId) { + return new UserId(userId).toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public int getOffset() { - return this.offset; - } - - @Override - public String toString() { - return String.format("UserId", - this.itemCount, this.offset, this.encode()); - } - - public static String toString(String userId) { - return new UserId(userId).toString(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - UserId userId = (UserId) o; - return itemCount == userId.itemCount && offset == userId.offset; - } - - @Override - public int hashCode() { - return Objects.hash(itemCount, offset); - } - - @Override - public int compareTo(UserId o) { - return Comparator.comparingInt(UserId::getItemCount) - .thenComparingInt(UserId::getOffset) - .compare(this, o); + if (o == null || getClass() != o.getClass()) { + return false; } + UserId userId = (UserId) o; + return itemCount == userId.itemCount && offset == userId.offset; + } + + @Override + public int hashCode() { + return Objects.hash(itemCount, offset); + } + + @Override + public int compareTo(UserId o) { + return Comparator.comparingInt(UserId::getItemCount) + .thenComparingInt(UserId::getOffset) + .compare(this, o); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserIdGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserIdGenerator.java index 7fe6097bc..5d7bbe85c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserIdGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/auctionmark/util/UserIdGenerator.java @@ -15,212 +15,210 @@ * */ - package com.oltpbenchmark.benchmarks.auctionmark.util; import com.oltpbenchmark.util.Histogram; import com.oltpbenchmark.util.StringUtil; -import org.apache.commons.collections4.map.ListOrderedMap; -import org.apache.commons.lang3.NotImplementedException; - import java.util.Arrays; import java.util.Iterator; import java.util.Map; +import org.apache.commons.collections4.map.ListOrderedMap; +import org.apache.commons.lang3.NotImplementedException; public final class UserIdGenerator implements Iterator { - private final int numClients; - private final Integer clientId; - private final int[] usersPerItemCounts; - private final int minItemCount; - private final int maxItemCount; - private final long totalUsers; - - private UserId next = null; - private int currentItemCount = -1; - private int currentOffset; - private int currentPosition = 0; - - /** - * Construct a new generator based on the given histogram. - * If clientId is not null, then this generator will only return UserIds that are mapped - * to that clientId based on the UserId's offset - * - * @param users_per_item_count - * @param numClients - * @param clientId - */ - public UserIdGenerator(Histogram users_per_item_count, int numClients, Integer clientId) { - - if (numClients <= 0) { - throw new IllegalArgumentException("numClients must be more than 0 : " + numClients); - } - if (clientId != null && clientId < 0) { - throw new IllegalArgumentException("clientId must be more than or equal to 0 : " + clientId); - } + private final int numClients; + private final Integer clientId; + private final int[] usersPerItemCounts; + private final int minItemCount; + private final int maxItemCount; + private final long totalUsers; + + private UserId next = null; + private int currentItemCount = -1; + private int currentOffset; + private int currentPosition = 0; + + /** + * Construct a new generator based on the given histogram. If clientId is not null, then this + * generator will only return UserIds that are mapped to that clientId based on the UserId's + * offset + * + * @param users_per_item_count + * @param numClients + * @param clientId + */ + public UserIdGenerator(Histogram users_per_item_count, int numClients, Integer clientId) { + + if (numClients <= 0) { + throw new IllegalArgumentException("numClients must be more than 0 : " + numClients); + } + if (clientId != null && clientId < 0) { + throw new IllegalArgumentException("clientId must be more than or equal to 0 : " + clientId); + } - this.numClients = numClients; - this.clientId = clientId; + this.numClients = numClients; + this.clientId = clientId; - Long temp = users_per_item_count.getMaxValue(); - this.maxItemCount = temp.intValue(); - this.usersPerItemCounts = new int[this.maxItemCount + 2]; - for (int i = 0; i < this.usersPerItemCounts.length; i++) { - this.usersPerItemCounts[i] = users_per_item_count.get((long) i, 0); - } + Long temp = users_per_item_count.getMaxValue(); + this.maxItemCount = temp.intValue(); + this.usersPerItemCounts = new int[this.maxItemCount + 2]; + for (int i = 0; i < this.usersPerItemCounts.length; i++) { + this.usersPerItemCounts[i] = users_per_item_count.get((long) i, 0); + } - temp = users_per_item_count.getMinValue(); - this.minItemCount = (temp != null ? temp.intValue() : 0); + temp = users_per_item_count.getMinValue(); + this.minItemCount = (temp != null ? temp.intValue() : 0); - this.totalUsers = users_per_item_count.getSampleCount(); + this.totalUsers = users_per_item_count.getSampleCount(); - this.setCurrentItemCount(this.minItemCount); - } + this.setCurrentItemCount(this.minItemCount); + } - public UserIdGenerator(Histogram users_per_item_count, int numClients) { - this(users_per_item_count, numClients, null); - } + public UserIdGenerator(Histogram users_per_item_count, int numClients) { + this(users_per_item_count, numClients, null); + } + public long getTotalUsers() { + return (this.totalUsers); + } - public long getTotalUsers() { - return (this.totalUsers); + public void setCurrentItemCount(int size) { + // It's lame, but we need to make sure that we prime total_ctr + // so that we always get the same UserIds back per client + this.currentPosition = 0; + for (int i = 0; i < size; i++) { + this.currentPosition += this.usersPerItemCounts[i]; } + this.currentItemCount = size; + this.currentOffset = this.usersPerItemCounts[this.currentItemCount]; + } - public void setCurrentItemCount(int size) { - // It's lame, but we need to make sure that we prime total_ctr - // so that we always get the same UserIds back per client - this.currentPosition = 0; - for (int i = 0; i < size; i++) { - this.currentPosition += this.usersPerItemCounts[i]; - } - this.currentItemCount = size; - this.currentOffset = this.usersPerItemCounts[this.currentItemCount]; - } + public int getCurrentPosition() { + return (this.currentPosition); + } + + public UserId seekToPosition(int position) { - public int getCurrentPosition() { - return (this.currentPosition); + UserId user_id = null; + + this.currentPosition = 0; + this.currentItemCount = 0; + while (true) { + int num_users = this.usersPerItemCounts[this.currentItemCount]; + + if (this.currentPosition + num_users > position) { + this.next = null; + this.currentOffset = num_users - (position - this.currentPosition); + this.currentPosition = position; + user_id = this.next(); + break; + } else { + this.currentPosition += num_users; + } + this.currentItemCount++; + } + return (user_id); + } + + /** + * Returns true if the given UserId should be processed by the given client id + * + * @param user_id + * @return + */ + public boolean checkClient(UserId user_id) { + if (this.clientId == null) { + return (true); } - public UserId seekToPosition(int position) { - - UserId user_id = null; - - this.currentPosition = 0; - this.currentItemCount = 0; - while (true) { - int num_users = this.usersPerItemCounts[this.currentItemCount]; - - if (this.currentPosition + num_users > position) { - this.next = null; - this.currentOffset = num_users - (position - this.currentPosition); - this.currentPosition = position; - user_id = this.next(); - break; - } else { - this.currentPosition += num_users; - } - this.currentItemCount++; - } - return (user_id); + int tmp_count = 0; + int tmp_position = 0; + while (tmp_count <= this.maxItemCount) { + int num_users = this.usersPerItemCounts[tmp_count]; + if (tmp_count == user_id.getItemCount()) { + tmp_position += (num_users - user_id.getOffset()) + 1; + break; + } + tmp_position += num_users; + tmp_count++; } + return (tmp_position % this.numClients == this.clientId); + } - /** - * Returns true if the given UserId should be processed by the given - * client id - * - * @param user_id - * @return - */ - public boolean checkClient(UserId user_id) { - if (this.clientId == null) { - return (true); - } + private UserId findNextUserId() { + // Find the next id for this size level + Long found = null; + while (this.currentItemCount <= this.maxItemCount) { + while (this.currentOffset > 0) { + long nextCtr = this.currentOffset--; + this.currentPosition++; - int tmp_count = 0; - int tmp_position = 0; - while (tmp_count <= this.maxItemCount) { - int num_users = this.usersPerItemCounts[tmp_count]; - if (tmp_count == user_id.getItemCount()) { - tmp_position += (num_users - user_id.getOffset()) + 1; - break; - } - tmp_position += num_users; - tmp_count++; - } - return (tmp_position % this.numClients == this.clientId); - } + // If we weren't given a clientId, then we'll generate UserIds - private UserId findNextUserId() { - // Find the next id for this size level - Long found = null; - while (this.currentItemCount <= this.maxItemCount) { - while (this.currentOffset > 0) { - long nextCtr = this.currentOffset--; - this.currentPosition++; - - // If we weren't given a clientId, then we'll generate UserIds - - if (this.clientId == null) { - found = nextCtr; - break; - } - // Otherwise we have to spin through and find one for our client - else if (this.currentPosition % this.numClients == this.clientId) { - found = nextCtr; - break; - } - } - if (found != null) { - break; - } - this.currentItemCount++; - this.currentOffset = this.usersPerItemCounts[this.currentItemCount]; + if (this.clientId == null) { + found = nextCtr; + break; } - if (found == null) { - return (null); + // Otherwise we have to spin through and find one for our client + else if (this.currentPosition % this.numClients == this.clientId) { + found = nextCtr; + break; } - - return (new UserId(this.currentItemCount, found.intValue())); + } + if (found != null) { + break; + } + this.currentItemCount++; + this.currentOffset = this.usersPerItemCounts[this.currentItemCount]; } - - @Override - public boolean hasNext() { - if (this.next == null) { - this.next = this.findNextUserId(); - } - return (this.next != null); + if (found == null) { + return (null); } - @Override - public UserId next() { - if (this.next == null) { - this.next = this.findNextUserId(); - } - UserId ret = this.next; - this.next = null; - return (ret); - } + return (new UserId(this.currentItemCount, found.intValue())); + } - @Override - public void remove() { - throw new NotImplementedException("Cannot call remove!!"); + @Override + public boolean hasNext() { + if (this.next == null) { + this.next = this.findNextUserId(); } + return (this.next != null); + } - @Override - public String toString() { - Map m = new ListOrderedMap<>(); - m.put("numClients", this.numClients); - m.put("clientId", this.clientId); - m.put("minItemCount", this.minItemCount); - m.put("maxItemCount", this.maxItemCount); - m.put("totalUsers", this.totalUsers); - m.put("currentItemCount", this.currentItemCount); - m.put("currentOffset", this.currentOffset); - m.put("currentPosition", this.currentPosition); - m.put("next", this.next); - m.put("users_per_item_count", String.format("[Length:%d] => %s", - this.usersPerItemCounts.length, - Arrays.toString(this.usersPerItemCounts))); - return StringUtil.formatMaps(m); + @Override + public UserId next() { + if (this.next == null) { + this.next = this.findNextUserId(); } + UserId ret = this.next; + this.next = null; + return (ret); + } + + @Override + public void remove() { + throw new NotImplementedException("Cannot call remove!!"); + } + + @Override + public String toString() { + Map m = new ListOrderedMap<>(); + m.put("numClients", this.numClients); + m.put("clientId", this.clientId); + m.put("minItemCount", this.minItemCount); + m.put("maxItemCount", this.maxItemCount); + m.put("totalUsers", this.totalUsers); + m.put("currentItemCount", this.currentItemCount); + m.put("currentOffset", this.currentOffset); + m.put("currentPosition", this.currentPosition); + m.put("next", this.next); + m.put( + "users_per_item_count", + String.format( + "[Length:%d] => %s", + this.usersPerItemCounts.length, Arrays.toString(this.usersPerItemCounts))); + return StringUtil.formatMaps(m); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmark.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmark.java index 33de1ab11..d45b07bcc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmark.java @@ -17,45 +17,42 @@ package com.oltpbenchmark.benchmarks.chbenchmark; - import com.oltpbenchmark.WorkloadConfiguration; import com.oltpbenchmark.api.BenchmarkModule; import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.chbenchmark.queries.Q1; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class CHBenCHmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(CHBenCHmark.class); + private static final Logger LOG = LoggerFactory.getLogger(CHBenCHmark.class); - public CHBenCHmark(WorkloadConfiguration workConf) { - super(workConf); - } + public CHBenCHmark(WorkloadConfiguration workConf) { + super(workConf); + } - protected Package getProcedurePackageImpl() { - return (Q1.class.getPackage()); - } + protected Package getProcedurePackageImpl() { + return (Q1.class.getPackage()); + } - @Override - protected List> makeWorkersImpl() { - // HACK: Turn off terminal messages - List> workers = new ArrayList<>(); + @Override + protected List> makeWorkersImpl() { + // HACK: Turn off terminal messages + List> workers = new ArrayList<>(); - int numTerminals = workConf.getTerminals(); - LOG.info(String.format("Creating %d workers for CHBenCHMark", numTerminals)); - for (int i = 0; i < numTerminals; i++) { - workers.add(new CHBenCHmarkWorker(this, i)); - } - - return workers; + int numTerminals = workConf.getTerminals(); + LOG.info(String.format("Creating %d workers for CHBenCHMark", numTerminals)); + for (int i = 0; i < numTerminals; i++) { + workers.add(new CHBenCHmarkWorker(this, i)); } - protected Loader makeLoaderImpl() { - return new CHBenCHmarkLoader(this); - } + return workers; + } + protected Loader makeLoaderImpl() { + return new CHBenCHmarkLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java index 6112318be..f30050d11 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkLoader.java @@ -17,15 +17,12 @@ package com.oltpbenchmark.benchmarks.chbenchmark; - import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.benchmarks.chbenchmark.pojo.Nation; import com.oltpbenchmark.benchmarks.chbenchmark.pojo.Region; import com.oltpbenchmark.benchmarks.chbenchmark.pojo.Supplier; import com.oltpbenchmark.util.RandomGenerator; -import org.apache.commons.io.IOUtils; - import java.io.InputStream; import java.nio.charset.Charset; import java.sql.Connection; @@ -36,283 +33,287 @@ import java.util.List; import java.util.StringTokenizer; import java.util.concurrent.CountDownLatch; +import org.apache.commons.io.IOUtils; public final class CHBenCHmarkLoader extends Loader { - private static final RandomGenerator ran = new RandomGenerator(0); - + private static final RandomGenerator ran = new RandomGenerator(0); - //create possible keys for n_nationkey ([a-zA-Z0-9]) - private static final int[] nationkeys = new int[62]; + // create possible keys for n_nationkey ([a-zA-Z0-9]) + private static final int[] nationkeys = new int[62]; - static { - for (char i = 0; i < 10; i++) { - nationkeys[i] = '0' + i; - } - for (char i = 0; i < 26; i++) { - nationkeys[i + 10] = 'A' + i; - } - for (char i = 0; i < 26; i++) { - nationkeys[i + 36] = 'a' + i; - } + static { + for (char i = 0; i < 10; i++) { + nationkeys[i] = '0' + i; } - - public CHBenCHmarkLoader(CHBenCHmark benchmark) { - super(benchmark); + for (char i = 0; i < 26; i++) { + nationkeys[i + 10] = 'A' + i; + } + for (char i = 0; i < 26; i++) { + nationkeys[i + 36] = 'a' + i; } + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); + public CHBenCHmarkLoader(CHBenCHmark benchmark) { + super(benchmark); + } - final CountDownLatch regionLatch = new CountDownLatch(1); + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = conn.prepareStatement("INSERT INTO region " + " (r_regionkey, r_name, r_comment) " + "VALUES (?, ?, ?)")) { + final CountDownLatch regionLatch = new CountDownLatch(1); - loadRegions(conn, statement); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = + conn.prepareStatement( + "INSERT INTO region " + + " (r_regionkey, r_name, r_comment) " + + "VALUES (?, ?, ?)")) { - @Override - public void afterLoad() { - regionLatch.countDown(); + loadRegions(conn, statement); } + } + + @Override + public void afterLoad() { + regionLatch.countDown(); + } }); - final CountDownLatch nationLatch = new CountDownLatch(1); + final CountDownLatch nationLatch = new CountDownLatch(1); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = conn.prepareStatement("INSERT INTO nation " + " (n_nationkey, n_name, n_regionkey, n_comment) " + "VALUES (?, ?, ?, ?)")) { + try (PreparedStatement statement = + conn.prepareStatement( + "INSERT INTO nation " + + " (n_nationkey, n_name, n_regionkey, n_comment) " + + "VALUES (?, ?, ?, ?)")) { - loadNations(conn, statement); - } + loadNations(conn, statement); } - - @Override - public void beforeLoad() { - try { - regionLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + } + + @Override + public void beforeLoad() { + try { + regionLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - nationLatch.countDown(); - } + @Override + public void afterLoad() { + nationLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = conn.prepareStatement("INSERT INTO supplier " + " (su_suppkey, su_name, su_address, su_nationkey, su_phone, su_acctbal, su_comment) " + "VALUES (?, ?, ?, ?, ?, ?, ?)")) { - - loadSuppliers(conn, statement); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = + conn.prepareStatement( + "INSERT INTO supplier " + + " (su_suppkey, su_name, su_address, su_nationkey, su_phone, su_acctbal, su_comment) " + + "VALUES (?, ?, ?, ?, ?, ?, ?)")) { + + loadSuppliers(conn, statement); } - - @Override - public void beforeLoad() { - try { - nationLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + } + + @Override + public void beforeLoad() { + try { + nationLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } }); - return threads; - } + return threads; + } - private void truncateTable(Connection conn, String strTable) { + private void truncateTable(Connection conn, String strTable) { - LOG.debug("Truncating '{}' ...", strTable); - try (Statement statement = conn.createStatement()) { - statement.execute("DELETE FROM " + strTable); - } catch (SQLException se) { - LOG.debug(se.getMessage()); - } + LOG.debug("Truncating '{}' ...", strTable); + try (Statement statement = conn.createStatement()) { + statement.execute("DELETE FROM " + strTable); + } catch (SQLException se) { + LOG.debug(se.getMessage()); } + } - private int loadRegions(Connection conn, PreparedStatement statement) throws SQLException { - int k = 0; - - truncateTable(conn, "region"); - truncateTable(conn, "nation"); - truncateTable(conn, "supplier"); + private int loadRegions(Connection conn, PreparedStatement statement) throws SQLException { + int k = 0; - Region region = new Region(); + truncateTable(conn, "region"); + truncateTable(conn, "nation"); + truncateTable(conn, "supplier"); - final String path = "/benchmarks/" + this.benchmark.getBenchmarkName() + "/region_gen.tbl"; + Region region = new Region(); - try (InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { + final String path = "/benchmarks/" + this.benchmark.getBenchmarkName() + "/region_gen.tbl"; - List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); + try (InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { - for (String line : lines) { - StringTokenizer st = new StringTokenizer(line, "|"); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - region.r_regionkey = Integer.parseInt(st.nextToken()); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - region.r_name = st.nextToken(); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - region.r_comment = st.nextToken(); - if (st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } + List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); - k++; - - statement.setLong(1, region.r_regionkey); - statement.setString(2, region.r_name); - statement.setString(3, region.r_comment); - statement.addBatch(); - - if ((k % workConf.getBatchSize()) == 0) { + for (String line : lines) { + StringTokenizer st = new StringTokenizer(line, "|"); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + region.r_regionkey = Integer.parseInt(st.nextToken()); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + region.r_name = st.nextToken(); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + region.r_comment = st.nextToken(); + if (st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } - statement.executeBatch(); - statement.clearBatch(); - } + k++; - } + statement.setLong(1, region.r_regionkey); + statement.setString(2, region.r_name); + statement.setString(3, region.r_comment); + statement.addBatch(); - statement.executeBatch(); - statement.clearBatch(); + if ((k % workConf.getBatchSize()) == 0) { - } catch (SQLException se) { - LOG.debug(se.getMessage()); - } catch (Exception e) { - LOG.error(e.getMessage(), e); + statement.executeBatch(); + statement.clearBatch(); } + } - return (k); + statement.executeBatch(); + statement.clearBatch(); + } catch (SQLException se) { + LOG.debug(se.getMessage()); + } catch (Exception e) { + LOG.error(e.getMessage(), e); } - private int loadNations(Connection conn, PreparedStatement statement) { - int k = 0; - - Nation nation = new Nation(); - - final String path = "/benchmarks/" + this.benchmark.getBenchmarkName() + "/nation_gen.tbl"; - - try (final InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { - - List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); - - for (String line : lines) { - StringTokenizer st = new StringTokenizer(line, "|"); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - nation.n_nationkey = Integer.parseInt(st.nextToken()); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - nation.n_name = st.nextToken(); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - nation.n_regionkey = Integer.parseInt(st.nextToken()); - if (!st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - nation.n_comment = st.nextToken(); - if (st.hasMoreTokens()) { - LOG.error("invalid input file: {}", path); - } - - k++; - - statement.setLong(1, nation.n_nationkey); - statement.setString(2, nation.n_name); - statement.setLong(3, nation.n_regionkey); - statement.setString(4, nation.n_comment); - statement.addBatch(); - - if ((k % workConf.getBatchSize()) == 0) { - - statement.executeBatch(); - statement.clearBatch(); - } + return (k); + } - } + private int loadNations(Connection conn, PreparedStatement statement) { + int k = 0; + Nation nation = new Nation(); - statement.executeBatch(); - statement.clearBatch(); + final String path = "/benchmarks/" + this.benchmark.getBenchmarkName() + "/nation_gen.tbl"; + try (final InputStream resourceAsStream = this.getClass().getResourceAsStream(path)) { - } catch (SQLException se) { - LOG.debug(se.getMessage()); - } catch (Exception e) { - LOG.error(e.getMessage(), e); + List lines = IOUtils.readLines(resourceAsStream, Charset.defaultCharset()); + + for (String line : lines) { + StringTokenizer st = new StringTokenizer(line, "|"); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + nation.n_nationkey = Integer.parseInt(st.nextToken()); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + nation.n_name = st.nextToken(); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + nation.n_regionkey = Integer.parseInt(st.nextToken()); + if (!st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); + } + nation.n_comment = st.nextToken(); + if (st.hasMoreTokens()) { + LOG.error("invalid input file: {}", path); } - return (k); + k++; - } + statement.setLong(1, nation.n_nationkey); + statement.setString(2, nation.n_name); + statement.setLong(3, nation.n_regionkey); + statement.setString(4, nation.n_comment); + statement.addBatch(); - private int loadSuppliers(Connection conn, PreparedStatement statement) { - int k = 0; + if ((k % workConf.getBatchSize()) == 0) { - try { + statement.executeBatch(); + statement.clearBatch(); + } + } - Supplier supplier = new Supplier(); + statement.executeBatch(); + statement.clearBatch(); - for (int index = 1; index <= 10000; index++) { - supplier.su_suppkey = index; - supplier.su_name = ran.astring(25, 25); - supplier.su_address = ran.astring(20, 40); - supplier.su_nationkey = nationkeys[ran.number(0, 61)]; - supplier.su_phone = ran.nstring(15, 15); - supplier.su_acctbal = (float) ran.fixedPoint(2, 10000., 1000000000.); - supplier.su_comment = ran.astring(51, 101); + } catch (SQLException se) { + LOG.debug(se.getMessage()); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } - k++; + return (k); + } - statement.setLong(1, supplier.su_suppkey); - statement.setString(2, supplier.su_name); - statement.setString(3, supplier.su_address); - statement.setLong(4, supplier.su_nationkey); - statement.setString(5, supplier.su_phone); - statement.setDouble(6, supplier.su_acctbal); - statement.setString(7, supplier.su_comment); - statement.addBatch(); + private int loadSuppliers(Connection conn, PreparedStatement statement) { + int k = 0; - if ((k % workConf.getBatchSize()) == 0) { + try { - statement.executeBatch(); - statement.clearBatch(); - } - } + Supplier supplier = new Supplier(); + for (int index = 1; index <= 10000; index++) { + supplier.su_suppkey = index; + supplier.su_name = ran.astring(25, 25); + supplier.su_address = ran.astring(20, 40); + supplier.su_nationkey = nationkeys[ran.number(0, 61)]; + supplier.su_phone = ran.nstring(15, 15); + supplier.su_acctbal = (float) ran.fixedPoint(2, 10000., 1000000000.); + supplier.su_comment = ran.astring(51, 101); - statement.executeBatch(); - statement.clearBatch(); + k++; + statement.setLong(1, supplier.su_suppkey); + statement.setString(2, supplier.su_name); + statement.setString(3, supplier.su_address); + statement.setLong(4, supplier.su_nationkey); + statement.setString(5, supplier.su_phone); + statement.setDouble(6, supplier.su_acctbal); + statement.setString(7, supplier.su_comment); + statement.addBatch(); - } catch (SQLException se) { - LOG.debug(se.getMessage()); - } catch (Exception e) { - LOG.error(e.getMessage(), e); + if ((k % workConf.getBatchSize()) == 0) { + + statement.executeBatch(); + statement.clearBatch(); } + } - return (k); + statement.executeBatch(); + statement.clearBatch(); + } catch (SQLException se) { + LOG.debug(se.getMessage()); + } catch (Exception e) { + LOG.error(e.getMessage(), e); } - + return (k); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkWorker.java index c7b6024b0..6244ccf75 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/CHBenCHmarkWorker.java @@ -22,25 +22,24 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.chbenchmark.queries.GenericQuery; import com.oltpbenchmark.types.TransactionStatus; - import java.sql.Connection; import java.sql.SQLException; public final class CHBenCHmarkWorker extends Worker { - public CHBenCHmarkWorker(CHBenCHmark benchmarkModule, int id) { - super(benchmarkModule, id); - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) throws UserAbortException, SQLException { - try { - GenericQuery proc = (GenericQuery) this.getProcedure(nextTransaction.getProcedureClass()); - proc.run(conn); - } catch (ClassCastException e) { - throw new RuntimeException(e); - } - - return (TransactionStatus.SUCCESS); + public CHBenCHmarkWorker(CHBenCHmark benchmarkModule, int id) { + super(benchmarkModule, id); + } + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) + throws UserAbortException, SQLException { + try { + GenericQuery proc = (GenericQuery) this.getProcedure(nextTransaction.getProcedureClass()); + proc.run(conn); + } catch (ClassCastException e) { + throw new RuntimeException(e); } + + return (TransactionStatus.SUCCESS); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Nation.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Nation.java index a6398f7a8..7ef20f499 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Nation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Nation.java @@ -15,25 +15,29 @@ * */ - package com.oltpbenchmark.benchmarks.chbenchmark.pojo; -//>>> CH-benCHmark +// >>> CH-benCHmark public class Nation { - public int n_nationkey; // PRIMARY KEY - public String n_name; - public int n_regionkey; - public String n_comment; - - @Override - public String toString() { - return ("\n***************** Nation ********************" - + "\n* n_nationkey = " + n_nationkey + "\n* n_name = " + n_name - + "\n* n_regionkey = " + n_regionkey + "\n* n_comment = " + n_comment - + "\n**********************************************"); - } + public int n_nationkey; // PRIMARY KEY + public String n_name; + public int n_regionkey; + public String n_comment; + @Override + public String toString() { + return ("\n***************** Nation ********************" + + "\n* n_nationkey = " + + n_nationkey + + "\n* n_name = " + + n_name + + "\n* n_regionkey = " + + n_regionkey + + "\n* n_comment = " + + n_comment + + "\n**********************************************"); + } } -//<<< CH-benCHmark \ No newline at end of file +// <<< CH-benCHmark diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Region.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Region.java index 92ffc219c..bcbe3cebe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Region.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Region.java @@ -15,23 +15,26 @@ * */ - package com.oltpbenchmark.benchmarks.chbenchmark.pojo; -//>>> CH-benCHmark +// >>> CH-benCHmark public class Region { - public int r_regionkey; // PRIMARY KEY - public String r_name; - public String r_comment; - - @Override - public String toString() { - return ("\n***************** Region ********************" - + "\n* r_regionkey = " + r_regionkey + "\n* r_name = " + r_name - + "\n* r_comment = " + r_comment + "\n**********************************************"); - } + public int r_regionkey; // PRIMARY KEY + public String r_name; + public String r_comment; + @Override + public String toString() { + return ("\n***************** Region ********************" + + "\n* r_regionkey = " + + r_regionkey + + "\n* r_name = " + + r_name + + "\n* r_comment = " + + r_comment + + "\n**********************************************"); + } } -//<<< CH-benCHmark \ No newline at end of file +// <<< CH-benCHmark diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Supplier.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Supplier.java index 1037b75e2..1dfa2e414 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Supplier.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/pojo/Supplier.java @@ -15,29 +15,38 @@ * */ - package com.oltpbenchmark.benchmarks.chbenchmark.pojo; -//>>> CH-benCHmark +// >>> CH-benCHmark public class Supplier { - public int su_suppkey; // PRIMARY KEY - public String su_name; - public String su_address; - public int su_nationkey; - public String su_phone; - public float su_acctbal; - public String su_comment; - - @Override - public String toString() { - return ("\n***************** Supplier ********************" - + "\n* su_suppkey = " + su_suppkey + "\n* su_name = " + su_name - + "\n* su_address = " + su_address + "\n* su_nationkey = " + su_nationkey - + "\n* su_phone = " + su_phone + "\n* su_acctbal = " + su_acctbal - + "\n* su_comment = " + su_comment + "\n**********************************************"); - } + public int su_suppkey; // PRIMARY KEY + public String su_name; + public String su_address; + public int su_nationkey; + public String su_phone; + public float su_acctbal; + public String su_comment; + @Override + public String toString() { + return ("\n***************** Supplier ********************" + + "\n* su_suppkey = " + + su_suppkey + + "\n* su_name = " + + su_name + + "\n* su_address = " + + su_address + + "\n* su_nationkey = " + + su_nationkey + + "\n* su_phone = " + + su_phone + + "\n* su_acctbal = " + + su_acctbal + + "\n* su_comment = " + + su_comment + + "\n**********************************************"); + } } -//<<< CH-benCHmark \ No newline at end of file +// <<< CH-benCHmark diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/GenericQuery.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/GenericQuery.java index f1ddf5d2f..cbf1e1f76 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/GenericQuery.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/GenericQuery.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,13 +26,14 @@ public abstract class GenericQuery extends Procedure { - protected abstract SQLStmt get_query(); + protected abstract SQLStmt get_query(); - public void run(Connection conn) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, get_query()); ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - //do nothing - } - } + public void run(Connection conn) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, get_query()); + ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + // do nothing + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q1.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q1.java index 3d011bd6c..f7af88cf7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q1.java @@ -21,20 +21,20 @@ public class Q1 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT ol_number, " - + "sum(ol_quantity) AS sum_qty, " - + "sum(ol_amount) AS sum_amount, " - + "avg(ol_quantity) AS avg_qty, " - + "avg(ol_amount) AS avg_amount, " - + "count(*) AS count_order " - + "FROM order_line " - + "WHERE ol_delivery_d > '2007-01-02 00:00:00.000000' " - + "GROUP BY ol_number " - + "ORDER BY ol_number" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT ol_number, " + + "sum(ol_quantity) AS sum_qty, " + + "sum(ol_amount) AS sum_amount, " + + "avg(ol_quantity) AS avg_qty, " + + "avg(ol_amount) AS avg_amount, " + + "count(*) AS count_order " + + "FROM order_line " + + "WHERE ol_delivery_d > '2007-01-02 00:00:00.000000' " + + "GROUP BY ol_number " + + "ORDER BY ol_number"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q10.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q10.java index e9778af0b..b1d88f2a5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q10.java @@ -21,35 +21,35 @@ public class Q10 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT c_id, " - + "c_last, " - + "sum(ol_amount) AS revenue, " - + "c_city, " - + "c_phone, " - + "n_name " - + "FROM customer, " - + "oorder, " - + "order_line, " - + "nation " - + "WHERE c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND o_entry_d >= '2007-01-02 00:00:00.000000' " - + "AND o_entry_d <= ol_delivery_d " - + "AND n_nationkey = ascii(substring(c_state from 1 for 1)) " - + "GROUP BY c_id, " - + "c_last, " - + "c_city, " - + "c_phone, " - + "n_name " - + "ORDER BY revenue DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT c_id, " + + "c_last, " + + "sum(ol_amount) AS revenue, " + + "c_city, " + + "c_phone, " + + "n_name " + + "FROM customer, " + + "oorder, " + + "order_line, " + + "nation " + + "WHERE c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND o_entry_d >= '2007-01-02 00:00:00.000000' " + + "AND o_entry_d <= ol_delivery_d " + + "AND n_nationkey = ascii(substring(c_state from 1 for 1)) " + + "GROUP BY c_id, " + + "c_last, " + + "c_city, " + + "c_phone, " + + "n_name " + + "ORDER BY revenue DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q11.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q11.java index a4cd0997c..404eadeb9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q11.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q11.java @@ -21,27 +21,27 @@ public class Q11 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT s_i_id, " - + "sum(s_order_cnt) AS ordercount " - + "FROM stock, " - + "supplier, " - + "nation " - + "WHERE mod((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND su_nationkey = n_nationkey " - + "AND n_name = 'Germany' " - + "GROUP BY s_i_id HAVING sum(s_order_cnt) > " - + "(SELECT sum(s_order_cnt) * .005 " - + "FROM stock, " - + "supplier, " - + "nation " - + "WHERE mod((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND su_nationkey = n_nationkey " - + "AND n_name = 'Germany') " - + "ORDER BY ordercount DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT s_i_id, " + + "sum(s_order_cnt) AS ordercount " + + "FROM stock, " + + "supplier, " + + "nation " + + "WHERE mod((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND su_nationkey = n_nationkey " + + "AND n_name = 'Germany' " + + "GROUP BY s_i_id HAVING sum(s_order_cnt) > " + + "(SELECT sum(s_order_cnt) * .005 " + + "FROM stock, " + + "supplier, " + + "nation " + + "WHERE mod((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND su_nationkey = n_nationkey " + + "AND n_name = 'Germany') " + + "ORDER BY ordercount DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q12.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q12.java index 01b0e4d8e..9c862922e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q12.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q12.java @@ -21,24 +21,24 @@ public class Q12 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT o_ol_cnt, " - + "sum(CASE WHEN o_carrier_id = 1 " - + "OR o_carrier_id = 2 THEN 1 ELSE 0 END) AS high_line_count, " - + "sum(CASE WHEN o_carrier_id <> 1 " - + "AND o_carrier_id <> 2 THEN 1 ELSE 0 END) AS low_line_count " - + "FROM oorder, " - + "order_line " - + "WHERE ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND o_entry_d <= ol_delivery_d " - + "AND ol_delivery_d < '2020-01-01 00:00:00.000000' " - + "GROUP BY o_ol_cnt " - + "ORDER BY o_ol_cnt" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT o_ol_cnt, " + + "sum(CASE WHEN o_carrier_id = 1 " + + "OR o_carrier_id = 2 THEN 1 ELSE 0 END) AS high_line_count, " + + "sum(CASE WHEN o_carrier_id <> 1 " + + "AND o_carrier_id <> 2 THEN 1 ELSE 0 END) AS low_line_count " + + "FROM oorder, " + + "order_line " + + "WHERE ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND o_entry_d <= ol_delivery_d " + + "AND ol_delivery_d < '2020-01-01 00:00:00.000000' " + + "GROUP BY o_ol_cnt " + + "ORDER BY o_ol_cnt"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q13.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q13.java index 29e3b227b..8740ad079 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q13.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q13.java @@ -21,23 +21,23 @@ public class Q13 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT c_count, " - + "count(*) AS custdist " - + "FROM " - + "(SELECT c_id, " - + "count(o_id) AS c_count " - + "FROM customer " - + "LEFT OUTER JOIN oorder ON (c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND c_id = o_c_id " - + "AND o_carrier_id > 8) " - + "GROUP BY c_id) AS c_orders " - + "GROUP BY c_count " - + "ORDER BY custdist DESC, c_count DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT c_count, " + + "count(*) AS custdist " + + "FROM " + + "(SELECT c_id, " + + "count(o_id) AS c_count " + + "FROM customer " + + "LEFT OUTER JOIN oorder ON (c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND c_id = o_c_id " + + "AND o_carrier_id > 8) " + + "GROUP BY c_id) AS c_orders " + + "GROUP BY c_count " + + "ORDER BY custdist DESC, c_count DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q14.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q14.java index 99899a7d2..d67f830e3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q14.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q14.java @@ -21,16 +21,16 @@ public class Q14 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT (100.00 * sum(CASE WHEN i_data LIKE 'PR%' THEN ol_amount ELSE 0 END) / (1 + sum(ol_amount))) AS promo_revenue " - + "FROM order_line, " - + "item " - + "WHERE ol_i_id = i_id " - + "AND ol_delivery_d >= '2007-01-02 00:00:00.000000' " - + "AND ol_delivery_d < '2020-01-02 00:00:00.000000'" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT (100.00 * sum(CASE WHEN i_data LIKE 'PR%' THEN ol_amount ELSE 0 END) / (1 + sum(ol_amount))) AS promo_revenue " + + "FROM order_line, " + + "item " + + "WHERE ol_i_id = i_id " + + "AND ol_delivery_d >= '2007-01-02 00:00:00.000000' " + + "AND ol_delivery_d < '2020-01-02 00:00:00.000000'"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q15.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q15.java index eedbf8863..94f7694cc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q15.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q15.java @@ -18,58 +18,55 @@ package com.oltpbenchmark.benchmarks.chbenchmark.queries; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; public class Q15 extends GenericQuery { - public final SQLStmt createview_stmt = new SQLStmt( - "CREATE view revenue0 (supplier_no, total_revenue) AS " - + "SELECT " - + "mod((s_w_id * s_i_id),10000) as supplier_no, " - + "sum(ol_amount) as total_revenue " - + "FROM " - + "order_line, stock " - + "WHERE " - + "ol_i_id = s_i_id " - + "AND ol_supply_w_id = s_w_id " - + "AND ol_delivery_d >= '2007-01-02 00:00:00.000000' " - + "GROUP BY " - + "supplier_no" - ); + public final SQLStmt createview_stmt = + new SQLStmt( + "CREATE view revenue0 (supplier_no, total_revenue) AS " + + "SELECT " + + "mod((s_w_id * s_i_id),10000) as supplier_no, " + + "sum(ol_amount) as total_revenue " + + "FROM " + + "order_line, stock " + + "WHERE " + + "ol_i_id = s_i_id " + + "AND ol_supply_w_id = s_w_id " + + "AND ol_delivery_d >= '2007-01-02 00:00:00.000000' " + + "GROUP BY " + + "supplier_no"); - public final SQLStmt query_stmt = new SQLStmt( - "SELECT su_suppkey, " - + "su_name, " - + "su_address, " - + "su_phone, " - + "total_revenue " - + "FROM supplier, revenue0 " - + "WHERE su_suppkey = supplier_no " - + "AND total_revenue = (select max(total_revenue) from revenue0) " - + "ORDER BY su_suppkey" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT su_suppkey, " + + "su_name, " + + "su_address, " + + "su_phone, " + + "total_revenue " + + "FROM supplier, revenue0 " + + "WHERE su_suppkey = supplier_no " + + "AND total_revenue = (select max(total_revenue) from revenue0) " + + "ORDER BY su_suppkey"); - public final SQLStmt dropview_stmt = new SQLStmt( - "DROP VIEW revenue0" - ); + public final SQLStmt dropview_stmt = new SQLStmt("DROP VIEW revenue0"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } - public void run(Connection conn) throws SQLException { - // With this query, we have to set up a view before we execute the - // query, then drop it once we're done. - try (Statement stmt = conn.createStatement()) { - try { - stmt.executeUpdate(createview_stmt.getSQL()); - super.run(conn); - } finally { - stmt.executeUpdate(dropview_stmt.getSQL()); - } - } + public void run(Connection conn) throws SQLException { + // With this query, we have to set up a view before we execute the + // query, then drop it once we're done. + try (Statement stmt = conn.createStatement()) { + try { + stmt.executeUpdate(createview_stmt.getSQL()); + super.run(conn); + } finally { + stmt.executeUpdate(dropview_stmt.getSQL()); + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q16.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q16.java index a85f4d479..e213e40a6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q16.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q16.java @@ -21,26 +21,26 @@ public class Q16 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT i_name, " - + "substring(i_data from 1 for 3) AS brand, " - + "i_price, " - + "count(DISTINCT (mod((s_w_id * s_i_id),10000))) AS supplier_cnt " - + "FROM stock, " - + "item " - + "WHERE i_id = s_i_id " - + "AND i_data NOT LIKE 'zz%' " - + "AND (mod((s_w_id * s_i_id),10000) NOT IN " - + "(SELECT su_suppkey " - + "FROM supplier " - + "WHERE su_comment LIKE '%bad%')) " - + "GROUP BY i_name, " - + "brand, " - + "i_price " - + "ORDER BY supplier_cnt DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT i_name, " + + "substring(i_data from 1 for 3) AS brand, " + + "i_price, " + + "count(DISTINCT (mod((s_w_id * s_i_id),10000))) AS supplier_cnt " + + "FROM stock, " + + "item " + + "WHERE i_id = s_i_id " + + "AND i_data NOT LIKE 'zz%' " + + "AND (mod((s_w_id * s_i_id),10000) NOT IN " + + "(SELECT su_suppkey " + + "FROM supplier " + + "WHERE su_comment LIKE '%bad%')) " + + "GROUP BY i_name, " + + "brand, " + + "i_price " + + "ORDER BY supplier_cnt DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q17.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q17.java index 57f8b637a..d208aaf64 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q17.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q17.java @@ -21,20 +21,20 @@ public class Q17 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT SUM(ol_amount) / 2.0 AS avg_yearly " - + "FROM order_line, " - + "(SELECT i_id, AVG (ol_quantity) AS a " - + "FROM item, " - + "order_line " - + "WHERE i_data LIKE '%b' " - + "AND ol_i_id = i_id " - + "GROUP BY i_id) t " - + "WHERE ol_i_id = t.i_id " - + "AND ol_quantity < t.a" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT SUM(ol_amount) / 2.0 AS avg_yearly " + + "FROM order_line, " + + "(SELECT i_id, AVG (ol_quantity) AS a " + + "FROM item, " + + "order_line " + + "WHERE i_data LIKE '%b' " + + "AND ol_i_id = i_id " + + "GROUP BY i_id) t " + + "WHERE ol_i_id = t.i_id " + + "AND ol_quantity < t.a"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q18.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q18.java index 4f7948e4f..f6b89d23f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q18.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q18.java @@ -21,33 +21,33 @@ public class Q18 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT c_last, " - + "c_id, " - + "o_id, " - + "o_entry_d, " - + "o_ol_cnt, " - + "sum(ol_amount) AS amount_sum " - + "FROM customer, " - + "oorder, " - + "order_line " - + "WHERE c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "GROUP BY o_id, " - + "o_w_id, " - + "o_d_id, " - + "c_id, " - + "c_last, " - + "o_entry_d, " - + "o_ol_cnt HAVING sum(ol_amount) > 200 " - + "ORDER BY amount_sum DESC, o_entry_d" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT c_last, " + + "c_id, " + + "o_id, " + + "o_entry_d, " + + "o_ol_cnt, " + + "sum(ol_amount) AS amount_sum " + + "FROM customer, " + + "oorder, " + + "order_line " + + "WHERE c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "GROUP BY o_id, " + + "o_w_id, " + + "o_d_id, " + + "c_id, " + + "c_last, " + + "o_entry_d, " + + "o_ol_cnt HAVING sum(ol_amount) > 200 " + + "ORDER BY amount_sum DESC, o_entry_d"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q19.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q19.java index 9043d1fde..237147d6f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q19.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q19.java @@ -21,37 +21,37 @@ public class Q19 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT sum(ol_amount) AS revenue " - + "FROM order_line, " - + "item " - + "WHERE (ol_i_id = i_id " - + "AND i_data LIKE '%a' " - + "AND ol_quantity >= 1 " - + "AND ol_quantity <= 10 " - + "AND i_price BETWEEN 1 AND 400000 " - + "AND ol_w_id IN (1, " - + "2, " - + "3)) " - + "OR (ol_i_id = i_id " - + "AND i_data LIKE '%b' " - + "AND ol_quantity >= 1 " - + "AND ol_quantity <= 10 " - + "AND i_price BETWEEN 1 AND 400000 " - + "AND ol_w_id IN (1, " - + "2, " - + "4)) " - + "OR (ol_i_id = i_id " - + "AND i_data LIKE '%c' " - + "AND ol_quantity >= 1 " - + "AND ol_quantity <= 10 " - + "AND i_price BETWEEN 1 AND 400000 " - + "AND ol_w_id IN (1, " - + "5, " - + "3))" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT sum(ol_amount) AS revenue " + + "FROM order_line, " + + "item " + + "WHERE (ol_i_id = i_id " + + "AND i_data LIKE '%a' " + + "AND ol_quantity >= 1 " + + "AND ol_quantity <= 10 " + + "AND i_price BETWEEN 1 AND 400000 " + + "AND ol_w_id IN (1, " + + "2, " + + "3)) " + + "OR (ol_i_id = i_id " + + "AND i_data LIKE '%b' " + + "AND ol_quantity >= 1 " + + "AND ol_quantity <= 10 " + + "AND i_price BETWEEN 1 AND 400000 " + + "AND ol_w_id IN (1, " + + "2, " + + "4)) " + + "OR (ol_i_id = i_id " + + "AND i_data LIKE '%c' " + + "AND ol_quantity >= 1 " + + "AND ol_quantity <= 10 " + + "AND i_price BETWEEN 1 AND 400000 " + + "AND ol_w_id IN (1, " + + "5, " + + "3))"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q2.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q2.java index dfc6b2a8f..94600a81f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q2.java @@ -21,40 +21,40 @@ public class Q2 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT su_suppkey, " - + "su_name, " - + "n_name, " - + "i_id, " - + "i_name, " - + "su_address, " - + "su_phone, " - + "su_comment " - + "FROM item, supplier, stock, nation, region, " - + "(SELECT s_i_id AS m_i_id, MIN(s_quantity) AS m_s_quantity " - + "FROM stock, " - + "supplier, " - + "nation, " - + "region " - + "WHERE MOD((s_w_id*s_i_id), 10000)=su_suppkey " - + "AND su_nationkey=n_nationkey " - + "AND n_regionkey=r_regionkey " - + "AND r_name LIKE 'Europ%' " - + "GROUP BY s_i_id) m " - + "WHERE i_id = s_i_id " - + "AND MOD((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND su_nationkey = n_nationkey " - + "AND n_regionkey = r_regionkey " - + "AND i_data LIKE '%b' " - + "AND r_name LIKE 'Europ%' " - + "AND i_id=m_i_id " - + "AND s_quantity = m_s_quantity " - + "ORDER BY n_name, " - + "su_name, " - + "i_id" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT su_suppkey, " + + "su_name, " + + "n_name, " + + "i_id, " + + "i_name, " + + "su_address, " + + "su_phone, " + + "su_comment " + + "FROM item, supplier, stock, nation, region, " + + "(SELECT s_i_id AS m_i_id, MIN(s_quantity) AS m_s_quantity " + + "FROM stock, " + + "supplier, " + + "nation, " + + "region " + + "WHERE MOD((s_w_id*s_i_id), 10000)=su_suppkey " + + "AND su_nationkey=n_nationkey " + + "AND n_regionkey=r_regionkey " + + "AND r_name LIKE 'Europ%' " + + "GROUP BY s_i_id) m " + + "WHERE i_id = s_i_id " + + "AND MOD((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND su_nationkey = n_nationkey " + + "AND n_regionkey = r_regionkey " + + "AND i_data LIKE '%b' " + + "AND r_name LIKE 'Europ%' " + + "AND i_id=m_i_id " + + "AND s_quantity = m_s_quantity " + + "ORDER BY n_name, " + + "su_name, " + + "i_id"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q20.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q20.java index 08de4692a..5fcca80e3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q20.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q20.java @@ -21,27 +21,27 @@ public class Q20 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT su_name, " - + "su_address " - + "FROM supplier, " - + "nation " - + "WHERE su_suppkey IN " - + "(SELECT mod(s_i_id * s_w_id, 10000) " - + "FROM stock " - + "INNER JOIN item ON i_id = s_i_id " - + "INNER JOIN order_line ON ol_i_id = s_i_id " - + "WHERE ol_delivery_d > '2010-05-23 12:00:00' " - + "AND i_data LIKE 'co%' " - + "GROUP BY s_i_id, " - + "s_w_id, " - + "s_quantity HAVING 2*s_quantity > sum(ol_quantity)) " - + "AND su_nationkey = n_nationkey " - + "AND n_name = 'Germany' " - + "ORDER BY su_name" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT su_name, " + + "su_address " + + "FROM supplier, " + + "nation " + + "WHERE su_suppkey IN " + + "(SELECT mod(s_i_id * s_w_id, 10000) " + + "FROM stock " + + "INNER JOIN item ON i_id = s_i_id " + + "INNER JOIN order_line ON ol_i_id = s_i_id " + + "WHERE ol_delivery_d > '2010-05-23 12:00:00' " + + "AND i_data LIKE 'co%' " + + "GROUP BY s_i_id, " + + "s_w_id, " + + "s_quantity HAVING 2*s_quantity > sum(ol_quantity)) " + + "AND su_nationkey = n_nationkey " + + "AND n_name = 'Germany' " + + "ORDER BY su_name"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q21.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q21.java index 0f85b76fb..b466c849a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q21.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q21.java @@ -21,35 +21,35 @@ public class Q21 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT su_name, " - + "count(*) AS numwait " - + "FROM supplier, " - + "order_line l1, " - + "oorder, " - + "stock, " - + "nation " - + "WHERE ol_o_id = o_id " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_w_id = s_w_id " - + "AND ol_i_id = s_i_id " - + "AND mod((s_w_id * s_i_id),10000) = su_suppkey " - + "AND l1.ol_delivery_d > o_entry_d " - + "AND NOT EXISTS " - + "(SELECT * " - + "FROM order_line l2 " - + "WHERE l2.ol_o_id = l1.ol_o_id " - + "AND l2.ol_w_id = l1.ol_w_id " - + "AND l2.ol_d_id = l1.ol_d_id " - + "AND l2.ol_delivery_d > l1.ol_delivery_d) " - + "AND su_nationkey = n_nationkey " - + "AND n_name = 'Germany' " - + "GROUP BY su_name " - + "ORDER BY numwait DESC, su_name" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT su_name, " + + "count(*) AS numwait " + + "FROM supplier, " + + "order_line l1, " + + "oorder, " + + "stock, " + + "nation " + + "WHERE ol_o_id = o_id " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_w_id = s_w_id " + + "AND ol_i_id = s_i_id " + + "AND mod((s_w_id * s_i_id),10000) = su_suppkey " + + "AND l1.ol_delivery_d > o_entry_d " + + "AND NOT EXISTS " + + "(SELECT * " + + "FROM order_line l2 " + + "WHERE l2.ol_o_id = l1.ol_o_id " + + "AND l2.ol_w_id = l1.ol_w_id " + + "AND l2.ol_d_id = l1.ol_d_id " + + "AND l2.ol_delivery_d > l1.ol_delivery_d) " + + "AND su_nationkey = n_nationkey " + + "AND n_name = 'Germany' " + + "GROUP BY su_name " + + "ORDER BY numwait DESC, su_name"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q22.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q22.java index 2fc5fae39..137c417d5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q22.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q22.java @@ -21,40 +21,40 @@ public class Q22 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT substring(c_state from 1 for 1) AS country, " - + "count(*) AS numcust, " - + "sum(c_balance) AS totacctbal " - + "FROM customer " - + "WHERE substring(c_phone from 1 for 1) IN ('1', " - + "'2', " - + "'3', " - + "'4', " - + "'5', " - + "'6', " - + "'7') " - + "AND c_balance > " - + "(SELECT avg(c_balance) " - + "FROM customer " - + "WHERE c_balance > 0.00 " - + "AND substring(c_phone from 1 for 1) IN ('1', " - + "'2', " - + "'3', " - + "'4', " - + "'5', " - + "'6', " - + "'7')) " - + "AND NOT EXISTS " - + "(SELECT * " - + "FROM oorder " - + "WHERE o_c_id = c_id " - + "AND o_w_id = c_w_id " - + "AND o_d_id = c_d_id) " - + "GROUP BY substring(c_state from 1 for 1) " - + "ORDER BY substring(c_state,1,1)" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT substring(c_state from 1 for 1) AS country, " + + "count(*) AS numcust, " + + "sum(c_balance) AS totacctbal " + + "FROM customer " + + "WHERE substring(c_phone from 1 for 1) IN ('1', " + + "'2', " + + "'3', " + + "'4', " + + "'5', " + + "'6', " + + "'7') " + + "AND c_balance > " + + "(SELECT avg(c_balance) " + + "FROM customer " + + "WHERE c_balance > 0.00 " + + "AND substring(c_phone from 1 for 1) IN ('1', " + + "'2', " + + "'3', " + + "'4', " + + "'5', " + + "'6', " + + "'7')) " + + "AND NOT EXISTS " + + "(SELECT * " + + "FROM oorder " + + "WHERE o_c_id = c_id " + + "AND o_w_id = c_w_id " + + "AND o_d_id = c_d_id) " + + "GROUP BY substring(c_state from 1 for 1) " + + "ORDER BY substring(c_state,1,1)"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q3.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q3.java index 3b7229021..acb4a93b4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q3.java @@ -21,35 +21,35 @@ public class Q3 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT ol_o_id, " - + "ol_w_id, " - + "ol_d_id, " - + "sum(ol_amount) AS revenue, " - + "o_entry_d " - + "FROM customer, " - + "new_order, " - + "oorder, " - + "order_line " - + "WHERE c_state LIKE 'A%' " - + "AND c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND no_w_id = o_w_id " - + "AND no_d_id = o_d_id " - + "AND no_o_id = o_id " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND o_entry_d > '2007-01-02 00:00:00.000000' " - + "GROUP BY ol_o_id, " - + "ol_w_id, " - + "ol_d_id, " - + "o_entry_d " - + "ORDER BY revenue DESC , o_entry_d" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT ol_o_id, " + + "ol_w_id, " + + "ol_d_id, " + + "sum(ol_amount) AS revenue, " + + "o_entry_d " + + "FROM customer, " + + "new_order, " + + "oorder, " + + "order_line " + + "WHERE c_state LIKE 'A%' " + + "AND c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND no_w_id = o_w_id " + + "AND no_d_id = o_d_id " + + "AND no_o_id = o_id " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND o_entry_d > '2007-01-02 00:00:00.000000' " + + "GROUP BY ol_o_id, " + + "ol_w_id, " + + "ol_d_id, " + + "o_entry_d " + + "ORDER BY revenue DESC , o_entry_d"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q4.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q4.java index 1be4638ea..fa00d6e48 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q4.java @@ -21,22 +21,22 @@ public class Q4 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT o_ol_cnt, " - + "count(*) AS order_count " - + "FROM oorder " - + "WHERE exists " - + "(SELECT * " - + "FROM order_line " - + "WHERE o_id = ol_o_id " - + "AND o_w_id = ol_w_id " - + "AND o_d_id = ol_d_id " - + "AND ol_delivery_d >= o_entry_d) " - + "GROUP BY o_ol_cnt " - + "ORDER BY o_ol_cnt" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT o_ol_cnt, " + + "count(*) AS order_count " + + "FROM oorder " + + "WHERE exists " + + "(SELECT * " + + "FROM order_line " + + "WHERE o_id = ol_o_id " + + "AND o_w_id = ol_w_id " + + "AND o_d_id = ol_d_id " + + "AND ol_delivery_d >= o_entry_d) " + + "GROUP BY o_ol_cnt " + + "ORDER BY o_ol_cnt"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q5.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q5.java index 7dc0dec77..195cf3314 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q5.java @@ -21,35 +21,35 @@ public class Q5 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT n_name, " - + "sum(ol_amount) AS revenue " - + "FROM customer, " - + "oorder, " - + "order_line, " - + "stock, " - + "supplier, " - + "nation, " - + "region " - + "WHERE c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id=o_d_id " - + "AND ol_w_id = s_w_id " - + "AND ol_i_id = s_i_id " - + "AND MOD((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND ascii(substring(c_state from 1 for 1)) = su_nationkey " - + "AND su_nationkey = n_nationkey " - + "AND n_regionkey = r_regionkey " - + "AND r_name = 'Europe' " - + "AND o_entry_d >= '2007-01-02 00:00:00.000000' " - + "GROUP BY n_name " - + "ORDER BY revenue DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT n_name, " + + "sum(ol_amount) AS revenue " + + "FROM customer, " + + "oorder, " + + "order_line, " + + "stock, " + + "supplier, " + + "nation, " + + "region " + + "WHERE c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id=o_d_id " + + "AND ol_w_id = s_w_id " + + "AND ol_i_id = s_i_id " + + "AND MOD((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND ascii(substring(c_state from 1 for 1)) = su_nationkey " + + "AND su_nationkey = n_nationkey " + + "AND n_regionkey = r_regionkey " + + "AND r_name = 'Europe' " + + "AND o_entry_d >= '2007-01-02 00:00:00.000000' " + + "GROUP BY n_name " + + "ORDER BY revenue DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q6.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q6.java index 9841e8786..3350e1509 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q6.java @@ -21,15 +21,15 @@ public class Q6 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT sum(ol_amount) AS revenue " - + "FROM order_line " - + "WHERE ol_delivery_d >= '1999-01-01 00:00:00.000000' " - + "AND ol_delivery_d < '2020-01-01 00:00:00.000000' " - + "AND ol_quantity BETWEEN 1 AND 100000" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT sum(ol_amount) AS revenue " + + "FROM order_line " + + "WHERE ol_delivery_d >= '1999-01-01 00:00:00.000000' " + + "AND ol_delivery_d < '2020-01-01 00:00:00.000000' " + + "AND ol_quantity BETWEEN 1 AND 100000"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q7.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q7.java index 4d4a9d41e..907c4eea2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q7.java @@ -21,43 +21,43 @@ public class Q7 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT su_nationkey AS supp_nation, " - + "substring(c_state from 1 for 1) AS cust_nation, " - + "extract(YEAR " - + "FROM o_entry_d) AS l_year, " - + "sum(ol_amount) AS revenue " - + "FROM supplier, " - + "stock, " - + "order_line, " - + "oorder, " - + "customer, " - + "nation n1, " - + "nation n2 " - + "WHERE ol_supply_w_id = s_w_id " - + "AND ol_i_id = s_i_id " - + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND su_nationkey = n1.n_nationkey " - + "AND ascii(substring(c_state from 1 for 1)) = n2.n_nationkey " - + "AND ((n1.n_name = 'Germany' " - + "AND n2.n_name = 'Cambodia') " - + "OR (n1.n_name = 'Cambodia' " - + "AND n2.n_name = 'Germany')) " - + "GROUP BY su_nationkey, " - + "cust_nation, " - + "l_year " - + "ORDER BY su_nationkey, " - + "cust_nation, " - + "l_year" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT su_nationkey AS supp_nation, " + + "substring(c_state from 1 for 1) AS cust_nation, " + + "extract(YEAR " + + "FROM o_entry_d) AS l_year, " + + "sum(ol_amount) AS revenue " + + "FROM supplier, " + + "stock, " + + "order_line, " + + "oorder, " + + "customer, " + + "nation n1, " + + "nation n2 " + + "WHERE ol_supply_w_id = s_w_id " + + "AND ol_i_id = s_i_id " + + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND su_nationkey = n1.n_nationkey " + + "AND ascii(substring(c_state from 1 for 1)) = n2.n_nationkey " + + "AND ((n1.n_name = 'Germany' " + + "AND n2.n_name = 'Cambodia') " + + "OR (n1.n_name = 'Cambodia' " + + "AND n2.n_name = 'Germany')) " + + "GROUP BY su_nationkey, " + + "cust_nation, " + + "l_year " + + "ORDER BY su_nationkey, " + + "cust_nation, " + + "l_year"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q8.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q8.java index 377a15c7a..3bb302efb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q8.java @@ -21,41 +21,41 @@ public class Q8 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT extract(YEAR " - + "FROM o_entry_d) AS l_year, " - + "sum(CASE WHEN n2.n_name = 'Germany' THEN ol_amount ELSE 0 END) / sum(ol_amount) AS mkt_share " - + "FROM item, " - + "supplier, " - + "stock, " - + "order_line, " - + "oorder, " - + "customer, " - + "nation n1, " - + "nation n2, " - + "region " - + "WHERE i_id = s_i_id " - + "AND ol_i_id = s_i_id " - + "AND ol_supply_w_id = s_w_id " - + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND c_id = o_c_id " - + "AND c_w_id = o_w_id " - + "AND c_d_id = o_d_id " - + "AND n1.n_nationkey = ascii(substring(c_state from 1 for 1)) " - + "AND n1.n_regionkey = r_regionkey " - + "AND ol_i_id < 1000 " - + "AND r_name = 'Europe' " - + "AND su_nationkey = n2.n_nationkey " - + "AND i_data LIKE '%b' " - + "AND i_id = ol_i_id " - + "GROUP BY l_year " - + "ORDER BY l_year" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT extract(YEAR " + + "FROM o_entry_d) AS l_year, " + + "sum(CASE WHEN n2.n_name = 'Germany' THEN ol_amount ELSE 0 END) / sum(ol_amount) AS mkt_share " + + "FROM item, " + + "supplier, " + + "stock, " + + "order_line, " + + "oorder, " + + "customer, " + + "nation n1, " + + "nation n2, " + + "region " + + "WHERE i_id = s_i_id " + + "AND ol_i_id = s_i_id " + + "AND ol_supply_w_id = s_w_id " + + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND c_id = o_c_id " + + "AND c_w_id = o_w_id " + + "AND c_d_id = o_d_id " + + "AND n1.n_nationkey = ascii(substring(c_state from 1 for 1)) " + + "AND n1.n_regionkey = r_regionkey " + + "AND ol_i_id < 1000 " + + "AND r_name = 'Europe' " + + "AND su_nationkey = n2.n_nationkey " + + "AND i_data LIKE '%b' " + + "AND i_id = ol_i_id " + + "GROUP BY l_year " + + "ORDER BY l_year"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q9.java b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q9.java index a67275025..b535ebfc9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/chbenchmark/queries/Q9.java @@ -21,33 +21,33 @@ public class Q9 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt( - "SELECT n_name, " - + "extract(YEAR " - + "FROM o_entry_d) AS l_year, " - + "sum(ol_amount) AS sum_profit " - + "FROM item, " - + "stock, " - + "supplier, " - + "order_line, " - + "oorder, " - + "nation " - + "WHERE ol_i_id = s_i_id " - + "AND ol_supply_w_id = s_w_id " - + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " - + "AND ol_w_id = o_w_id " - + "AND ol_d_id = o_d_id " - + "AND ol_o_id = o_id " - + "AND ol_i_id = i_id " - + "AND su_nationkey = n_nationkey " - + "AND i_data LIKE '%bb' " - + "GROUP BY n_name, " - + "l_year " - + "ORDER BY n_name, " - + "l_year DESC" - ); + public final SQLStmt query_stmt = + new SQLStmt( + "SELECT n_name, " + + "extract(YEAR " + + "FROM o_entry_d) AS l_year, " + + "sum(ol_amount) AS sum_profit " + + "FROM item, " + + "stock, " + + "supplier, " + + "order_line, " + + "oorder, " + + "nation " + + "WHERE ol_i_id = s_i_id " + + "AND ol_supply_w_id = s_w_id " + + "AND MOD ((s_w_id * s_i_id), 10000) = su_suppkey " + + "AND ol_w_id = o_w_id " + + "AND ol_d_id = o_d_id " + + "AND ol_o_id = o_id " + + "AND ol_i_id = i_id " + + "AND su_nationkey = n_nationkey " + + "AND i_data LIKE '%bb' " + + "GROUP BY n_name, " + + "l_year " + + "ORDER BY n_name, " + + "l_year DESC"); - protected SQLStmt get_query() { - return query_stmt; - } + protected SQLStmt get_query() { + return query_stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsBenchmark.java index 991236988..e43c0dfc2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.epinions; import com.oltpbenchmark.WorkloadConfiguration; @@ -26,87 +25,82 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class EpinionsBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(EpinionsBenchmark.class); - - public EpinionsBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } + private static final Logger LOG = LoggerFactory.getLogger(EpinionsBenchmark.class); - @Override - protected Package getProcedurePackageImpl() { - return GetAverageRatingByTrustedUser.class.getPackage(); - } + public EpinionsBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - DatabaseType databaseType = this.getWorkloadConfiguration().getDatabaseType(); + @Override + protected Package getProcedurePackageImpl() { + return GetAverageRatingByTrustedUser.class.getPackage(); + } - try { + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + DatabaseType databaseType = this.getWorkloadConfiguration().getDatabaseType(); + try { - // LOADING FROM THE DATABASE IMPORTANT INFORMATION - // LIST OF USERS + // LOADING FROM THE DATABASE IMPORTANT INFORMATION + // LIST OF USERS - Table t = this.getCatalog().getTable("USERACCT"); + Table t = this.getCatalog().getTable("USERACCT"); + ArrayList user_ids = new ArrayList<>(); + ArrayList item_ids = new ArrayList<>(); + String userCount = SQLUtil.selectColValues(databaseType, t, "u_id"); - ArrayList user_ids = new ArrayList<>(); - ArrayList item_ids = new ArrayList<>(); - String userCount = SQLUtil.selectColValues(databaseType, t, "u_id"); - - try (Connection metaConn = this.makeConnection()) { - try (Statement stmt = metaConn.createStatement()) { - try (ResultSet res = stmt.executeQuery(userCount)) { - while (res.next()) { - user_ids.add(res.getString(1)); - } - } - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded: {} User ids", user_ids.size()); - } - // LIST OF ITEMS AND - t = this.getCatalog().getTable("ITEM"); - - - String itemCount = SQLUtil.selectColValues(databaseType, t, "i_id"); - try (ResultSet res = stmt.executeQuery(itemCount)) { - while (res.next()) { - item_ids.add(res.getString(1)); - } - } - } - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded: {} Item ids", item_ids.size()); - } + try (Connection metaConn = this.makeConnection()) { + try (Statement stmt = metaConn.createStatement()) { + try (ResultSet res = stmt.executeQuery(userCount)) { + while (res.next()) { + user_ids.add(res.getString(1)); } - - // Now create the workers. - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new EpinionsWorker(this, i, user_ids, item_ids)); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Loaded: {} User ids", user_ids.size()); + } + // LIST OF ITEMS AND + t = this.getCatalog().getTable("ITEM"); + + String itemCount = SQLUtil.selectColValues(databaseType, t, "i_id"); + try (ResultSet res = stmt.executeQuery(itemCount)) { + while (res.next()) { + item_ids.add(res.getString(1)); } - - } catch (SQLException e) { - LOG.error(e.getMessage(), e); + } } - return workers; - } + if (LOG.isDebugEnabled()) { + LOG.debug("Loaded: {} Item ids", item_ids.size()); + } + } + + // Now create the workers. + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new EpinionsWorker(this, i, user_ids, item_ids)); + } - @Override - protected Loader makeLoaderImpl() { - return new EpinionsLoader(this); + } catch (SQLException e) { + LOG.error(e.getMessage(), e); } + return workers; + } + @Override + protected Loader makeLoaderImpl() { + return new EpinionsLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsConstants.java index 73ac45aa0..3313629c0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsConstants.java @@ -19,18 +19,17 @@ public abstract class EpinionsConstants { - // Constants - public static final int NUM_USERS = 2000; // Number of baseline Users - public static final int NUM_ITEMS = 1000; // Number of baseline pages + // Constants + public static final int NUM_USERS = 2000; // Number of baseline Users + public static final int NUM_ITEMS = 1000; // Number of baseline pages - public static final int NAME_LENGTH = 24; // Length of user's name - public static final int EMAIL_LENGTH = 24; // Length of user's email - public static final int TITLE_LENGTH = 128; - public static final int DESCRIPTION_LENGTH = 512; - public static final int COMMENT_LENGTH = 256; - public static final int COMMENT_MIN_LENGTH = 32; - - public static final int REVIEW = 500; // this is the average .. expand to max - public static final int TRUST = 200; // this is the average .. expand to max + public static final int NAME_LENGTH = 24; // Length of user's name + public static final int EMAIL_LENGTH = 24; // Length of user's email + public static final int TITLE_LENGTH = 128; + public static final int DESCRIPTION_LENGTH = 512; + public static final int COMMENT_LENGTH = 256; + public static final int COMMENT_MIN_LENGTH = 32; + public static final int REVIEW = 500; // this is the average .. expand to max + public static final int TRUST = 200; // this is the average .. expand to max } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsLoader.java index 837c81b2a..c8ea0a519 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsLoader.java @@ -24,7 +24,6 @@ import com.oltpbenchmark.distributions.ZipfianGenerator; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -34,339 +33,345 @@ public final class EpinionsLoader extends Loader { - private final int num_users; - private final int num_items; - private final long num_reviews; - private final int num_trust; - - public EpinionsLoader(EpinionsBenchmark benchmark) { - super(benchmark); - this.num_users = (int) Math.round(EpinionsConstants.NUM_USERS * this.scaleFactor); - this.num_items = (int) Math.round(EpinionsConstants.NUM_ITEMS * this.scaleFactor); - this.num_reviews = (int) Math.round(EpinionsConstants.REVIEW * this.scaleFactor); - this.num_trust = (int) Math.round(EpinionsConstants.TRUST * this.scaleFactor); - if (LOG.isDebugEnabled()) { - LOG.debug("# USERS: {}", this.num_users); - LOG.debug("# ITEMS: {}", this.num_items); - LOG.debug("# Max of REVIEWS per item: {}", this.num_reviews); - LOG.debug("# Max of TRUSTS per user: {}", this.num_trust); - } + private final int num_users; + private final int num_items; + private final long num_reviews; + private final int num_trust; + + public EpinionsLoader(EpinionsBenchmark benchmark) { + super(benchmark); + this.num_users = (int) Math.round(EpinionsConstants.NUM_USERS * this.scaleFactor); + this.num_items = (int) Math.round(EpinionsConstants.NUM_ITEMS * this.scaleFactor); + this.num_reviews = (int) Math.round(EpinionsConstants.REVIEW * this.scaleFactor); + this.num_trust = (int) Math.round(EpinionsConstants.TRUST * this.scaleFactor); + if (LOG.isDebugEnabled()) { + LOG.debug("# USERS: {}", this.num_users); + LOG.debug("# ITEMS: {}", this.num_items); + LOG.debug("# Max of REVIEWS per item: {}", this.num_reviews); + LOG.debug("# Max of TRUSTS per user: {}", this.num_trust); } + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + final int numToLoad = this.num_items + this.num_users; + final int loadPerThread = Math.max(numToLoad / numLoaders, 1); + final int numUserThreads = (int) Math.ceil((double) this.num_users / loadPerThread); + final int numItemThreads = (int) Math.ceil((double) this.num_items / loadPerThread); + + final CountDownLatch userLatch = new CountDownLatch(numUserThreads); + final CountDownLatch itemLatch = new CountDownLatch(numItemThreads); + + // USERACCT + for (int i = 0; i < numUserThreads; i++) { + final int lo = i * loadPerThread; + final int hi = Math.min(this.num_users, (i + 1) * loadPerThread); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadUsers(conn, lo, hi); + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - final int numToLoad = this.num_items + this.num_users; - final int loadPerThread = Math.max(numToLoad / numLoaders, 1); - final int numUserThreads = (int) Math.ceil((double) this.num_users / loadPerThread); - final int numItemThreads = (int) Math.ceil((double) this.num_items / loadPerThread); - - final CountDownLatch userLatch = new CountDownLatch(numUserThreads); - final CountDownLatch itemLatch = new CountDownLatch(numItemThreads); - - // USERACCT - for (int i = 0; i < numUserThreads; i++) { - final int lo = i * loadPerThread; - final int hi = Math.min(this.num_users, (i + 1) * loadPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadUsers(conn, lo, hi); - - } - - @Override - public void afterLoad() { - userLatch.countDown(); - } - }); - } - - // ITEM - for (int i = 0; i < numItemThreads; i++) { - final int lo = i * loadPerThread; - final int hi = Math.min(this.num_items, (i + 1) * loadPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadItems(conn, lo, hi); - - } - - @Override - public void afterLoad() { - itemLatch.countDown(); - } - }); - } + @Override + public void afterLoad() { + userLatch.countDown(); + } + }); + } - // TRUST depends on USERACCT - for (int i = 0; i < numItemThreads; i++) { - final int lo = i * loadPerThread; - final int hi = Math.min(this.num_users, (i + 1) * loadPerThread); - - // To ensure that we don't wind up with an empty trust table for - // small scales we have the first loader thread ensure that at - // least a single trust record is inserted. - final boolean firstLoader = (i == 0); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTrust(conn, lo, hi, firstLoader); - } - - @Override - public void beforeLoad() { - try { - userLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - } + // ITEM + for (int i = 0; i < numItemThreads; i++) { + final int lo = i * loadPerThread; + final int hi = Math.min(this.num_items, (i + 1) * loadPerThread); - // REVIEWS depends on USERACCT, ITEM - for (int i = 0; i < numItemThreads; i++) { - final int lo = i * loadPerThread; - final int hi = Math.min(this.num_items, (i + 1) * loadPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadReviews(conn, lo, hi); - } - - @Override - public void beforeLoad() { - try { - userLatch.await(); - itemLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadItems(conn, lo, hi); + } - return threads; + @Override + public void afterLoad() { + itemLatch.countDown(); + } + }); } - /** - * @throws SQLException - * @author Djellel Load num_users users. - */ - private void loadUsers(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable("useracct"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - int total = 0; - int batch = 0; - try (PreparedStatement userInsert = conn.prepareStatement(sql)) { - long timestamp = System.currentTimeMillis(); - for (int i = lo; i < hi; i++) { - String name = TextGenerator.randomStr(rng(), EpinionsConstants.NAME_LENGTH); - String email = TextGenerator.randomStr(rng(), EpinionsConstants.EMAIL_LENGTH); - - userInsert.setInt(1, i); - userInsert.setString(2, name); - userInsert.setString(3, email); - userInsert.setTimestamp(4, new Timestamp(timestamp)); - userInsert.addBatch(); - total++; - - if ((++batch % workConf.getBatchSize()) == 0) { - userInsert.executeBatch(); - batch = 0; - userInsert.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Users %d / %d", total, num_users)); - } - } + // TRUST depends on USERACCT + for (int i = 0; i < numItemThreads; i++) { + final int lo = i * loadPerThread; + final int hi = Math.min(this.num_users, (i + 1) * loadPerThread); + + // To ensure that we don't wind up with an empty trust table for + // small scales we have the first loader thread ensure that at + // least a single trust record is inserted. + final boolean firstLoader = (i == 0); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTrust(conn, lo, hi, firstLoader); } - if (batch > 0) { - userInsert.executeBatch(); - userInsert.clearBatch(); + + @Override + public void beforeLoad() { + try { + userLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Users Loaded [%d]", total)); - } + }); } - /** - * @throws SQLException - * @author Djellel Load num_items items. - */ - private void loadItems(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable("item"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - int total = 0; - int batch = 0; - try (PreparedStatement itemInsert = conn.prepareStatement(sql)) { - ZipfianGenerator descLength = new ZipfianGenerator(rng(), EpinionsConstants.DESCRIPTION_LENGTH); - long timestamp = System.currentTimeMillis(); - - for (int i = lo; i < hi; i++) { - String title = TextGenerator.randomStr(rng(), EpinionsConstants.TITLE_LENGTH); - String desc = TextGenerator.randomStr(rng(), descLength.nextInt()); - - itemInsert.setInt(1, i); - itemInsert.setString(2, title); - itemInsert.setString(3, desc); - itemInsert.setTimestamp(4, new Timestamp(timestamp)); - itemInsert.addBatch(); - total++; - - if ((++batch % workConf.getBatchSize()) == 0) { - itemInsert.executeBatch(); - batch = 0; - itemInsert.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Items %d / %d", total, num_items)); - } - } + // REVIEWS depends on USERACCT, ITEM + for (int i = 0; i < numItemThreads; i++) { + final int lo = i * loadPerThread; + final int hi = Math.min(this.num_items, (i + 1) * loadPerThread); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadReviews(conn, lo, hi); } - if (batch > 0) { - itemInsert.executeBatch(); - itemInsert.clearBatch(); + + @Override + public void beforeLoad() { + try { + userLatch.await(); + itemLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Items Loaded [%d]", total)); - } + }); } - /** - * @throws SQLException - * @author Djellel What's going on here?: For each item we Loaded, we are - * going to generate reviews The number of reviews per Item selected - * from num_reviews. Who gives the reviews is selected from - * num_users and added to reviewers list. Note: the selection is - * based on Zipfian distribution. - */ - private void loadReviews(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable("review"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - int total = 0; - int batch = 0; - - try (PreparedStatement reviewInsert = conn.prepareStatement(sql)) { - ZipfianGenerator numReviews = new ZipfianGenerator(rng(), num_reviews, 1.8); - ZipfianGenerator reviewer = new ZipfianGenerator(rng(), num_users); - ZipfianGenerator commentLength = new ZipfianGenerator(rng(), EpinionsConstants.COMMENT_LENGTH - EpinionsConstants.COMMENT_MIN_LENGTH); - Set reviewers = new HashSet<>(); - - for (int i = lo; i < hi; i++) { - // make sure each item has at least one review - int review_count = numReviews.nextInt() + 1; - long timestamp = System.currentTimeMillis(); - - for (int rc = 0; rc < review_count; ) { - int u_id = reviewer.nextInt(); - if (!reviewers.contains(u_id)) { - String comment = TextGenerator.randomStr(rng(), commentLength.nextInt() + EpinionsConstants.COMMENT_MIN_LENGTH); - reviewInsert.setInt(1, total); - reviewInsert.setInt(2, u_id); - reviewInsert.setInt(3, i); - reviewInsert.setInt(4, rng().nextInt(5));// rating - reviewInsert.setNull(5, java.sql.Types.INTEGER); - reviewInsert.setString(6, comment); - reviewInsert.setTimestamp(7, new Timestamp(timestamp)); - reviewInsert.addBatch(); - reviewers.add(u_id); - total++; - rc++; - if ((++batch % workConf.getBatchSize()) == 0) { - reviewInsert.executeBatch(); - batch = 0; - reviewInsert.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug("Reviewed items % {}", (int) (((double) i / (double) this.num_items) * 100)); - } - } - } - } - reviewers.clear(); - } - if (batch > 0) { - reviewInsert.executeBatch(); - reviewInsert.clearBatch(); - } + return threads; + } + + /** + * @throws SQLException + * @author Djellel Load num_users users. + */ + private void loadUsers(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable("useracct"); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + int batch = 0; + try (PreparedStatement userInsert = conn.prepareStatement(sql)) { + long timestamp = System.currentTimeMillis(); + for (int i = lo; i < hi; i++) { + String name = TextGenerator.randomStr(rng(), EpinionsConstants.NAME_LENGTH); + String email = TextGenerator.randomStr(rng(), EpinionsConstants.EMAIL_LENGTH); + + userInsert.setInt(1, i); + userInsert.setString(2, name); + userInsert.setString(3, email); + userInsert.setTimestamp(4, new Timestamp(timestamp)); + userInsert.addBatch(); + total++; + + if ((++batch % workConf.getBatchSize()) == 0) { + userInsert.executeBatch(); + batch = 0; + userInsert.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Users %d / %d", total, num_users)); + } } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Reviews Loaded [%d]", total)); + } + if (batch > 0) { + userInsert.executeBatch(); + userInsert.clearBatch(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Users Loaded [%d]", total)); + } + } + + /** + * @throws SQLException + * @author Djellel Load num_items items. + */ + private void loadItems(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable("item"); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + int batch = 0; + try (PreparedStatement itemInsert = conn.prepareStatement(sql)) { + ZipfianGenerator descLength = + new ZipfianGenerator(rng(), EpinionsConstants.DESCRIPTION_LENGTH); + long timestamp = System.currentTimeMillis(); + + for (int i = lo; i < hi; i++) { + String title = TextGenerator.randomStr(rng(), EpinionsConstants.TITLE_LENGTH); + String desc = TextGenerator.randomStr(rng(), descLength.nextInt()); + + itemInsert.setInt(1, i); + itemInsert.setString(2, title); + itemInsert.setString(3, desc); + itemInsert.setTimestamp(4, new Timestamp(timestamp)); + itemInsert.addBatch(); + total++; + + if ((++batch % workConf.getBatchSize()) == 0) { + itemInsert.executeBatch(); + batch = 0; + itemInsert.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Items %d / %d", total, num_items)); + } } + } + if (batch > 0) { + itemInsert.executeBatch(); + itemInsert.clearBatch(); + } } - - /** - * @throws SQLException - * @author Djellel What's going on here?: For each user, select a number - * num_trust of trust-feedbacks (given by others users). Then we - * select the users who are part of that list. The actual feedback - * can be 1/0 with uniform distribution. Note: Select is based on - * Zipfian distribution Trusted users are not correlated to heavy - * reviewers (drawn using a scrambled distribution) - */ - public void loadTrust(Connection conn, int lo, int hi, boolean firstLoader) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable("trust"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - int total = 0; - int batch = 0; - - try (PreparedStatement trustInsert = conn.prepareStatement(sql)) { - ZipfianGenerator numTrust = new ZipfianGenerator(rng(), num_trust, 1.95); - ScrambledZipfianGenerator reviewed = new ScrambledZipfianGenerator(num_users); - Set trusted = new HashSet<>(); - - for (int i = lo; i < hi; i++) { - long timestamp = System.currentTimeMillis(); - int trust_count = numTrust.nextInt(); - // To avoid having an empty trust table during small scale - // tests, we make sure that at least one trust record is - // inserted to the table. - if (firstLoader && i == lo) { - trust_count = Math.max(trust_count, 1); - } - for (int tc = 0; tc < trust_count; ) { - int u_id = reviewed.nextInt(); - if (!trusted.contains(u_id)) { - tc++; - trustInsert.setInt(1, i); - trustInsert.setInt(2, u_id); - trustInsert.setInt(3, rng().nextInt(2)); - trustInsert.setDate(4, new java.sql.Date(timestamp)); - trustInsert.addBatch(); - trusted.add(u_id); - total++; - - if ((++batch % workConf.getBatchSize()) == 0) { - trustInsert.executeBatch(); - batch = 0; - trustInsert.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug("Rated users % {}", (int) (((double) i / (double) this.num_users) * 100)); - } - - } - } - } - trusted.clear(); - } - if (batch > 0) { - trustInsert.executeBatch(); - trustInsert.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Items Loaded [%d]", total)); + } + } + + /** + * @throws SQLException + * @author Djellel What's going on here?: For each item we Loaded, we are going to generate + * reviews The number of reviews per Item selected from num_reviews. Who gives the reviews is + * selected from num_users and added to reviewers list. Note: the selection is based on + * Zipfian distribution. + */ + private void loadReviews(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable("review"); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + int batch = 0; + + try (PreparedStatement reviewInsert = conn.prepareStatement(sql)) { + ZipfianGenerator numReviews = new ZipfianGenerator(rng(), num_reviews, 1.8); + ZipfianGenerator reviewer = new ZipfianGenerator(rng(), num_users); + ZipfianGenerator commentLength = + new ZipfianGenerator( + rng(), EpinionsConstants.COMMENT_LENGTH - EpinionsConstants.COMMENT_MIN_LENGTH); + Set reviewers = new HashSet<>(); + + for (int i = lo; i < hi; i++) { + // make sure each item has at least one review + int review_count = numReviews.nextInt() + 1; + long timestamp = System.currentTimeMillis(); + + for (int rc = 0; rc < review_count; ) { + int u_id = reviewer.nextInt(); + if (!reviewers.contains(u_id)) { + String comment = + TextGenerator.randomStr( + rng(), commentLength.nextInt() + EpinionsConstants.COMMENT_MIN_LENGTH); + reviewInsert.setInt(1, total); + reviewInsert.setInt(2, u_id); + reviewInsert.setInt(3, i); + reviewInsert.setInt(4, rng().nextInt(5)); // rating + reviewInsert.setNull(5, java.sql.Types.INTEGER); + reviewInsert.setString(6, comment); + reviewInsert.setTimestamp(7, new Timestamp(timestamp)); + reviewInsert.addBatch(); + reviewers.add(u_id); + total++; + rc++; + if ((++batch % workConf.getBatchSize()) == 0) { + reviewInsert.executeBatch(); + batch = 0; + reviewInsert.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug( + "Reviewed items % {}", (int) (((double) i / (double) this.num_items) * 100)); + } } + } + } + reviewers.clear(); + } + if (batch > 0) { + reviewInsert.executeBatch(); + reviewInsert.clearBatch(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Reviews Loaded [%d]", total)); + } + } + + /** + * @throws SQLException + * @author Djellel What's going on here?: For each user, select a number num_trust of + * trust-feedbacks (given by others users). Then we select the users who are part of that + * list. The actual feedback can be 1/0 with uniform distribution. Note: Select is based on + * Zipfian distribution Trusted users are not correlated to heavy reviewers (drawn using a + * scrambled distribution) + */ + public void loadTrust(Connection conn, int lo, int hi, boolean firstLoader) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable("trust"); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + int batch = 0; + + try (PreparedStatement trustInsert = conn.prepareStatement(sql)) { + ZipfianGenerator numTrust = new ZipfianGenerator(rng(), num_trust, 1.95); + ScrambledZipfianGenerator reviewed = new ScrambledZipfianGenerator(num_users); + Set trusted = new HashSet<>(); + + for (int i = lo; i < hi; i++) { + long timestamp = System.currentTimeMillis(); + int trust_count = numTrust.nextInt(); + // To avoid having an empty trust table during small scale + // tests, we make sure that at least one trust record is + // inserted to the table. + if (firstLoader && i == lo) { + trust_count = Math.max(trust_count, 1); } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Trust Loaded [%d]", total)); + for (int tc = 0; tc < trust_count; ) { + int u_id = reviewed.nextInt(); + if (!trusted.contains(u_id)) { + tc++; + trustInsert.setInt(1, i); + trustInsert.setInt(2, u_id); + trustInsert.setInt(3, rng().nextInt(2)); + trustInsert.setDate(4, new java.sql.Date(timestamp)); + trustInsert.addBatch(); + trusted.add(u_id); + total++; + + if ((++batch % workConf.getBatchSize()) == 0) { + trustInsert.executeBatch(); + batch = 0; + trustInsert.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug( + "Rated users % {}", (int) (((double) i / (double) this.num_users) * 100)); + } + } + } } + trusted.clear(); + } + if (batch > 0) { + trustInsert.executeBatch(); + trustInsert.clearBatch(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Trust Loaded [%d]", total)); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java index fb774a904..ade2543fa 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/EpinionsWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.epinions; import com.oltpbenchmark.api.Procedure.UserAbortException; @@ -24,120 +23,123 @@ import com.oltpbenchmark.benchmarks.epinions.procedures.*; import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.TextGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class EpinionsWorker extends Worker { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(EpinionsWorker.class); - - private final ArrayList user_ids; - private final ArrayList item_ids; - - public EpinionsWorker(EpinionsBenchmark benchmarkModule, int id, ArrayList user_ids, ArrayList item_ids) { - super(benchmarkModule, id); - this.user_ids = user_ids; - this.item_ids = item_ids; - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - if (nextTrans.getProcedureClass().equals(GetReviewItemById.class)) { - reviewItemByID(conn); - } else if (nextTrans.getProcedureClass().equals(GetReviewsByUser.class)) { - reviewsByUser(conn); - } else if (nextTrans.getProcedureClass().equals(GetAverageRatingByTrustedUser.class)) { - averageRatingByTrustedUser(conn); - } else if (nextTrans.getProcedureClass().equals(GetItemAverageRating.class)) { - averageRatingOfItem(conn); - } else if (nextTrans.getProcedureClass().equals(GetItemReviewsByTrustedUser.class)) { - itemReviewsByTrustedUser(conn); - } else if (nextTrans.getProcedureClass().equals(UpdateUserName.class)) { - updateUserName(conn); - } else if (nextTrans.getProcedureClass().equals(UpdateItemTitle.class)) { - updateItemTitle(conn); - } else if (nextTrans.getProcedureClass().equals(UpdateReviewRating.class)) { - updateReviewRating(conn); - } else if (nextTrans.getProcedureClass().equals(UpdateTrustRating.class)) { - updateTrustRating(conn); - } - return (TransactionStatus.SUCCESS); - } - - public void reviewItemByID(Connection conn) throws SQLException { - GetReviewItemById proc = this.getProcedure(GetReviewItemById.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - proc.run(conn, iid); - } - - public void reviewsByUser(Connection conn) throws SQLException { - GetReviewsByUser proc = this.getProcedure(GetReviewsByUser.class); - - long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); - proc.run(conn, uid); - } - - public void averageRatingByTrustedUser(Connection conn) throws SQLException { - GetAverageRatingByTrustedUser proc = this.getProcedure(GetAverageRatingByTrustedUser.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); - proc.run(conn, iid, uid); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(EpinionsWorker.class); + + private final ArrayList user_ids; + private final ArrayList item_ids; + + public EpinionsWorker( + EpinionsBenchmark benchmarkModule, + int id, + ArrayList user_ids, + ArrayList item_ids) { + super(benchmarkModule, id); + this.user_ids = user_ids; + this.item_ids = item_ids; + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + if (nextTrans.getProcedureClass().equals(GetReviewItemById.class)) { + reviewItemByID(conn); + } else if (nextTrans.getProcedureClass().equals(GetReviewsByUser.class)) { + reviewsByUser(conn); + } else if (nextTrans.getProcedureClass().equals(GetAverageRatingByTrustedUser.class)) { + averageRatingByTrustedUser(conn); + } else if (nextTrans.getProcedureClass().equals(GetItemAverageRating.class)) { + averageRatingOfItem(conn); + } else if (nextTrans.getProcedureClass().equals(GetItemReviewsByTrustedUser.class)) { + itemReviewsByTrustedUser(conn); + } else if (nextTrans.getProcedureClass().equals(UpdateUserName.class)) { + updateUserName(conn); + } else if (nextTrans.getProcedureClass().equals(UpdateItemTitle.class)) { + updateItemTitle(conn); + } else if (nextTrans.getProcedureClass().equals(UpdateReviewRating.class)) { + updateReviewRating(conn); + } else if (nextTrans.getProcedureClass().equals(UpdateTrustRating.class)) { + updateTrustRating(conn); } - - public void averageRatingOfItem(Connection conn) throws SQLException { - GetItemAverageRating proc = this.getProcedure(GetItemAverageRating.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - proc.run(conn, iid); - } - - public void itemReviewsByTrustedUser(Connection conn) throws SQLException { - GetItemReviewsByTrustedUser proc = this.getProcedure(GetItemReviewsByTrustedUser.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); - proc.run(conn, iid, uid); - } - - public void updateUserName(Connection conn) throws SQLException { - UpdateUserName proc = this.getProcedure(UpdateUserName.class); - - long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); - String name = TextGenerator.randomStr(rng(), EpinionsConstants.NAME_LENGTH); // FIXME - proc.run(conn, uid, name); - } - - public void updateItemTitle(Connection conn) throws SQLException { - UpdateItemTitle proc = this.getProcedure(UpdateItemTitle.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - String title = TextGenerator.randomStr(rng(), EpinionsConstants.TITLE_LENGTH); // FIXME - proc.run(conn, iid, title); - } - - public void updateReviewRating(Connection conn) throws SQLException { - UpdateReviewRating proc = this.getProcedure(UpdateReviewRating.class); - - long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); - long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); - int rating = rng().nextInt(1000); // ??? - proc.run(conn, iid, uid, rating); - } - - public void updateTrustRating(Connection conn) throws SQLException { - UpdateTrustRating proc = this.getProcedure(UpdateTrustRating.class); - int uix = rng().nextInt(user_ids.size()); - int uix2 = rng().nextInt(user_ids.size()); - long uid = Long.valueOf(user_ids.get(uix)); - long uid2 = Long.valueOf(user_ids.get(uix2)); - int trust = rng().nextInt(2); - proc.run(conn, uid, uid2, trust); - } - + return (TransactionStatus.SUCCESS); + } + + public void reviewItemByID(Connection conn) throws SQLException { + GetReviewItemById proc = this.getProcedure(GetReviewItemById.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + proc.run(conn, iid); + } + + public void reviewsByUser(Connection conn) throws SQLException { + GetReviewsByUser proc = this.getProcedure(GetReviewsByUser.class); + + long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); + proc.run(conn, uid); + } + + public void averageRatingByTrustedUser(Connection conn) throws SQLException { + GetAverageRatingByTrustedUser proc = this.getProcedure(GetAverageRatingByTrustedUser.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); + proc.run(conn, iid, uid); + } + + public void averageRatingOfItem(Connection conn) throws SQLException { + GetItemAverageRating proc = this.getProcedure(GetItemAverageRating.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + proc.run(conn, iid); + } + + public void itemReviewsByTrustedUser(Connection conn) throws SQLException { + GetItemReviewsByTrustedUser proc = this.getProcedure(GetItemReviewsByTrustedUser.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); + proc.run(conn, iid, uid); + } + + public void updateUserName(Connection conn) throws SQLException { + UpdateUserName proc = this.getProcedure(UpdateUserName.class); + + long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); + String name = TextGenerator.randomStr(rng(), EpinionsConstants.NAME_LENGTH); // FIXME + proc.run(conn, uid, name); + } + + public void updateItemTitle(Connection conn) throws SQLException { + UpdateItemTitle proc = this.getProcedure(UpdateItemTitle.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + String title = TextGenerator.randomStr(rng(), EpinionsConstants.TITLE_LENGTH); // FIXME + proc.run(conn, iid, title); + } + + public void updateReviewRating(Connection conn) throws SQLException { + UpdateReviewRating proc = this.getProcedure(UpdateReviewRating.class); + + long iid = Long.valueOf(item_ids.get(rng().nextInt(item_ids.size()))); + long uid = Long.valueOf(user_ids.get(rng().nextInt(user_ids.size()))); + int rating = rng().nextInt(1000); // ??? + proc.run(conn, iid, uid, rating); + } + + public void updateTrustRating(Connection conn) throws SQLException { + UpdateTrustRating proc = this.getProcedure(UpdateTrustRating.class); + int uix = rng().nextInt(user_ids.size()); + int uix2 = rng().nextInt(user_ids.size()); + long uid = Long.valueOf(user_ids.get(uix)); + long uid2 = Long.valueOf(user_ids.get(uix2)); + int trust = rng().nextInt(2); + proc.run(conn, uid, uid2, trust); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetAverageRatingByTrustedUser.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetAverageRatingByTrustedUser.java index bc6095c7a..335fb9072 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetAverageRatingByTrustedUser.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetAverageRatingByTrustedUser.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,20 +26,19 @@ public class GetAverageRatingByTrustedUser extends Procedure { - public final SQLStmt getAverageRating = new SQLStmt( - "SELECT avg(rating) FROM review r, trust t WHERE r.u_id=t.target_u_id AND r.i_id=? AND t.source_u_id=?" - ); + public final SQLStmt getAverageRating = + new SQLStmt( + "SELECT avg(rating) FROM review r, trust t WHERE r.u_id=t.target_u_id AND r.i_id=? AND t.source_u_id=?"); - public void run(Connection conn, long iid, long uid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getAverageRating)) { - stmt.setLong(1, iid); - stmt.setLong(2, uid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + public void run(Connection conn, long iid, long uid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getAverageRating)) { + stmt.setLong(1, iid); + stmt.setLong(2, uid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemAverageRating.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemAverageRating.java index 79794376d..f7001e080 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemAverageRating.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemAverageRating.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,18 +26,17 @@ public class GetItemAverageRating extends Procedure { - public final SQLStmt getAverageRating = new SQLStmt( - "SELECT avg(rating) FROM review r WHERE r.i_id=?" - ); + public final SQLStmt getAverageRating = + new SQLStmt("SELECT avg(rating) FROM review r WHERE r.i_id=?"); - public void run(Connection conn, long iid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getAverageRating)) { - stmt.setLong(1, iid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + public void run(Connection conn, long iid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getAverageRating)) { + stmt.setLong(1, iid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemReviewsByTrustedUser.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemReviewsByTrustedUser.java index 522a386d6..d62fff576 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemReviewsByTrustedUser.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetItemReviewsByTrustedUser.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,32 +26,28 @@ public class GetItemReviewsByTrustedUser extends Procedure { - //FIXME: CARLO, does this make sense? - public final SQLStmt getReview = new SQLStmt( - "SELECT * FROM review r WHERE r.i_id=? ORDER BY creation_date DESC" - ); + // FIXME: CARLO, does this make sense? + public final SQLStmt getReview = + new SQLStmt("SELECT * FROM review r WHERE r.i_id=? ORDER BY creation_date DESC"); - public final SQLStmt getTrust = new SQLStmt( - "SELECT * FROM trust t WHERE t.source_u_id=?" - ); + public final SQLStmt getTrust = new SQLStmt("SELECT * FROM trust t WHERE t.source_u_id=?"); - public void run(Connection conn, long iid, long uid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getReview)) { - stmt.setLong(1, iid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + public void run(Connection conn, long iid, long uid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getReview)) { + stmt.setLong(1, iid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } - try (PreparedStatement stmt = this.getPreparedStatement(conn, getTrust)) { - stmt.setLong(1, uid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + } + } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getTrust)) { + stmt.setLong(1, uid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewItemById.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewItemById.java index 99366e8d3..04e77bf16 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewItemById.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewItemById.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,20 +26,19 @@ public class GetReviewItemById extends Procedure { - public final SQLStmt getReviewItem = new SQLStmt( - "SELECT * FROM review r, item i WHERE i.i_id = r.i_id and r.i_id=? " + - "ORDER BY rating DESC, r.creation_date DESC LIMIT 10;" - ); + public final SQLStmt getReviewItem = + new SQLStmt( + "SELECT * FROM review r, item i WHERE i.i_id = r.i_id and r.i_id=? " + + "ORDER BY rating DESC, r.creation_date DESC LIMIT 10;"); - public void run(Connection conn, long iid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getReviewItem)) { - stmt.setLong(1, iid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + public void run(Connection conn, long iid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getReviewItem)) { + stmt.setLong(1, iid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewsByUser.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewsByUser.java index 6a13a783a..12b2fb4bc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewsByUser.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/GetReviewsByUser.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,19 +26,19 @@ public class GetReviewsByUser extends Procedure { - public final SQLStmt getReviewUser = new SQLStmt( - "SELECT * FROM review r, useracct u WHERE u.u_id = r.u_id AND r.u_id=? " + - "ORDER BY rating DESC, r.creation_date DESC LIMIT 10" - ); + public final SQLStmt getReviewUser = + new SQLStmt( + "SELECT * FROM review r, useracct u WHERE u.u_id = r.u_id AND r.u_id=? " + + "ORDER BY rating DESC, r.creation_date DESC LIMIT 10"); - public void run(Connection conn, long uid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getReviewUser)) { - stmt.setLong(1, uid); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - continue; - } - } + public void run(Connection conn, long uid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getReviewUser)) { + stmt.setLong(1, uid); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + continue; } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateItemTitle.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateItemTitle.java index ebb1c57ca..480b47db0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateItemTitle.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateItemTitle.java @@ -19,22 +19,19 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateItemTitle extends Procedure { - public final SQLStmt updateItem = new SQLStmt( - "UPDATE item SET title = ? WHERE i_id=?" - ); + public final SQLStmt updateItem = new SQLStmt("UPDATE item SET title = ? WHERE i_id=?"); - public void run(Connection conn, long iid, String title) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateItem)) { - stmt.setString(1, title); - stmt.setLong(2, iid); - stmt.executeUpdate(); - } + public void run(Connection conn, long iid, String title) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateItem)) { + stmt.setString(1, title); + stmt.setLong(2, iid); + stmt.executeUpdate(); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateReviewRating.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateReviewRating.java index cfc46e9b3..6d9865789 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateReviewRating.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateReviewRating.java @@ -19,23 +19,21 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateReviewRating extends Procedure { - public final SQLStmt updateReview = new SQLStmt( - "UPDATE review SET rating = ? WHERE i_id=? AND u_id=?" - ); + public final SQLStmt updateReview = + new SQLStmt("UPDATE review SET rating = ? WHERE i_id=? AND u_id=?"); - public void run(Connection conn, long iid, long uid, int rating) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateReview)) { - stmt.setInt(1, rating); - stmt.setLong(2, iid); - stmt.setLong(3, uid); - stmt.executeUpdate(); - } + public void run(Connection conn, long iid, long uid, int rating) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateReview)) { + stmt.setInt(1, rating); + stmt.setLong(2, iid); + stmt.setLong(3, uid); + stmt.executeUpdate(); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateTrustRating.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateTrustRating.java index 7e7777e6c..3ea5fcefe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateTrustRating.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateTrustRating.java @@ -19,23 +19,22 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateTrustRating extends Procedure { - public final SQLStmt updateTrust = new SQLStmt( - "UPDATE trust SET trust = ? WHERE source_u_id=? AND target_u_id=?" - ); + public final SQLStmt updateTrust = + new SQLStmt("UPDATE trust SET trust = ? WHERE source_u_id=? AND target_u_id=?"); - public void run(Connection conn, long source_uid, long target_uid, int trust) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateTrust)) { - stmt.setInt(1, trust); - stmt.setLong(2, source_uid); - stmt.setLong(3, target_uid); - stmt.executeUpdate(); - } + public void run(Connection conn, long source_uid, long target_uid, int trust) + throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateTrust)) { + stmt.setInt(1, trust); + stmt.setLong(2, source_uid); + stmt.setLong(3, target_uid); + stmt.executeUpdate(); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateUserName.java b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateUserName.java index 5678ab15c..61fe391f4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateUserName.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/epinions/procedures/UpdateUserName.java @@ -19,20 +19,19 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateUserName extends Procedure { - public final SQLStmt updateUser = new SQLStmt("UPDATE useracct SET name = ? WHERE u_id=?"); + public final SQLStmt updateUser = new SQLStmt("UPDATE useracct SET name = ? WHERE u_id=?"); - public void run(Connection conn, long uid, String name) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateUser)) { - stmt.setString(1, name); - stmt.setLong(2, uid); - stmt.executeUpdate(); - } + public void run(Connection conn, long uid, String name) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateUser)) { + stmt.setString(1, name); + stmt.setLong(2, uid); + stmt.executeUpdate(); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTBenchmark.java index 4d85c1ad5..b3251c800 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTBenchmark.java @@ -24,69 +24,65 @@ import com.oltpbenchmark.benchmarks.hyadapt.procedures.ReadRecord1; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class HYADAPTBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(HYADAPTBenchmark.class); - - public HYADAPTBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - + private static final Logger LOG = LoggerFactory.getLogger(HYADAPTBenchmark.class); - // LOADING FROM THE DATABASE IMPORTANT INFORMATION - // LIST OF USERS + public HYADAPTBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - Table t = this.getCatalog().getTable("HTABLE"); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); - String userCount = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), t); - int init_record_count = 0; - try (Connection metaConn = this.makeConnection()) { + // LOADING FROM THE DATABASE IMPORTANT INFORMATION + // LIST OF USERS - try (Statement stmt = metaConn.createStatement()) { - try (ResultSet res = stmt.executeQuery(userCount)) { - while (res.next()) { - init_record_count = res.getInt(1); - } + Table t = this.getCatalog().getTable("HTABLE"); - } - } - // - for (int i = 0; i < workConf.getTerminals(); ++i) { -// Connection conn = this.makeConnection(); -// conn.setAutoCommit(false); - workers.add(new HYADAPTWorker(this, i, init_record_count + 1)); - } + String userCount = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), t); + int init_record_count = 0; + try (Connection metaConn = this.makeConnection()) { - LOG.info("Init Record Count :: {}", init_record_count); - } catch (SQLException e) { - LOG.error(e.getMessage(), e); + try (Statement stmt = metaConn.createStatement()) { + try (ResultSet res = stmt.executeQuery(userCount)) { + while (res.next()) { + init_record_count = res.getInt(1); + } } - - return workers; + } + // + for (int i = 0; i < workConf.getTerminals(); ++i) { + // Connection conn = this.makeConnection(); + // conn.setAutoCommit(false); + workers.add(new HYADAPTWorker(this, i, init_record_count + 1)); + } + + LOG.info("Init Record Count :: {}", init_record_count); + } catch (SQLException e) { + LOG.error(e.getMessage(), e); } - @Override - protected Loader makeLoaderImpl() { - return new HYADAPTLoader(this); - } + return workers; + } - @Override - protected Package getProcedurePackageImpl() { - // TODO Auto-generated method stub - return ReadRecord1.class.getPackage(); - } + @Override + protected Loader makeLoaderImpl() { + return new HYADAPTLoader(this); + } + @Override + protected Package getProcedurePackageImpl() { + // TODO Auto-generated method stub + return ReadRecord1.class.getPackage(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTConstants.java index 6bedd1cdf..bf88cc97e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTConstants.java @@ -19,12 +19,11 @@ public abstract class HYADAPTConstants { - public static final int RECORD_COUNT = 1000; + public static final int RECORD_COUNT = 1000; - public static final int FIELD_COUNT = 250; + public static final int FIELD_COUNT = 250; - public static final int RANGE = 1000000; - - static final int MAX_SCAN = 1000; + public static final int RANGE = 1000000; + static final int MAX_SCAN = 1000; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java index 2a9a5f241..61f882d63 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTLoader.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -30,74 +29,71 @@ import java.util.Random; public final class HYADAPTLoader extends Loader { - private final int num_record; - private static final Random rand = new Random(); - - public HYADAPTLoader(HYADAPTBenchmark benchmark) { - super(benchmark); - this.num_record = (int) Math.round(HYADAPTConstants.RECORD_COUNT * this.scaleFactor); - LOG.info("# of RECORDS: {}", this.num_record); - } - - /** - * Returns a pseudo-random number between min and max, inclusive. - * The difference between min and max can be at most - * Integer.MAX_VALUE - 1. - * - * @return Integer between min and max, inclusive. - * @see java.util.Random#nextInt(int) - */ - public static int getRandInt() { - // nextInt is normally exclusive of the top value, - // so add 1 to make it inclusive - int min = 0; - int max = HYADAPTConstants.RANGE; - - return rand.nextInt((max - min) + 1) + min; - } - - @Override - public List createLoaderThreads() { - - List threads = new ArrayList<>(); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable("HTABLE"); - - - String sql = SQLUtil.getInsertSQL(catalog_tbl, getDatabaseType()); - - - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - long total = 0; - int batch = 0; - for (int i = 0; i < num_record; i++) { - stmt.setInt(1, i); - for (int j = 2; j <= HYADAPTConstants.FIELD_COUNT + 1; j++) { - stmt.setInt(j, getRandInt()); - } - stmt.addBatch(); - total++; - if (++batch >= workConf.getBatchSize()) { - int[] result = stmt.executeBatch(); - assert result != null; - - batch = 0; - LOG.info(String.format("Records Loaded %d / %d", total, num_record)); - } - } - if (batch > 0) { - stmt.executeBatch(); - LOG.info(String.format("Records Loaded %d / %d", total, num_record)); - } + private final int num_record; + private static final Random rand = new Random(); + + public HYADAPTLoader(HYADAPTBenchmark benchmark) { + super(benchmark); + this.num_record = (int) Math.round(HYADAPTConstants.RECORD_COUNT * this.scaleFactor); + LOG.info("# of RECORDS: {}", this.num_record); + } + + /** + * Returns a pseudo-random number between min and max, inclusive. The difference between min and + * max can be at most Integer.MAX_VALUE - 1. + * + * @return Integer between min and max, inclusive. + * @see java.util.Random#nextInt(int) + */ + public static int getRandInt() { + // nextInt is normally exclusive of the top value, + // so add 1 to make it inclusive + int min = 0; + int max = HYADAPTConstants.RANGE; + + return rand.nextInt((max - min) + 1) + min; + } + + @Override + public List createLoaderThreads() { + + List threads = new ArrayList<>(); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable("HTABLE"); + + String sql = SQLUtil.getInsertSQL(catalog_tbl, getDatabaseType()); + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + long total = 0; + int batch = 0; + for (int i = 0; i < num_record; i++) { + stmt.setInt(1, i); + for (int j = 2; j <= HYADAPTConstants.FIELD_COUNT + 1; j++) { + stmt.setInt(j, getRandInt()); + } + stmt.addBatch(); + total++; + if (++batch >= workConf.getBatchSize()) { + int[] result = stmt.executeBatch(); + assert result != null; + + batch = 0; + LOG.info(String.format("Records Loaded %d / %d", total, num_record)); } - LOG.info("Finished loading {}", catalog_tbl.getName()); + } + if (batch > 0) { + stmt.executeBatch(); + LOG.info(String.format("Records Loaded %d / %d", total, num_record)); + } } + LOG.info("Finished loading {}", catalog_tbl.getName()); + } }); - return threads; - } - + return threads; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTWorker.java index b82a9a61f..6e3ddaa94 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/HYADAPTWorker.java @@ -24,291 +24,290 @@ import com.oltpbenchmark.benchmarks.hyadapt.procedures.*; import com.oltpbenchmark.distributions.CounterGenerator; import com.oltpbenchmark.types.TransactionStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class HYADAPTWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(HYADAPTWorker.class); - - private static CounterGenerator insertRecord; - private final double selectivity = configuration.getSelectivity(); - private final int key_lower_bound = (int) ((1 - selectivity) * HYADAPTConstants.RANGE); - - public HYADAPTWorker(HYADAPTBenchmark benchmarkModule, int id, int init_record_count) { - super(benchmarkModule, id); - LOG.info("Key lower bound :: {}", key_lower_bound); - - synchronized (HYADAPTWorker.class) { - // We must know where to start inserting - if (insertRecord == null) { - insertRecord = new CounterGenerator(init_record_count); - } - } - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - Class procClass = nextTrans.getProcedureClass(); - - if (procClass.equals(ReadRecord1.class)) { - readRecord1(conn); - } else if (procClass.equals(ReadRecord2.class)) { - readRecord2(conn); - } else if (procClass.equals(ReadRecord3.class)) { - readRecord3(conn); - } else if (procClass.equals(ReadRecord4.class)) { - readRecord4(conn); - } else if (procClass.equals(ReadRecord5.class)) { - readRecord5(conn); - } else if (procClass.equals(ReadRecord6.class)) { - readRecord6(conn); - } else if (procClass.equals(ReadRecord7.class)) { - readRecord7(conn); - } else if (procClass.equals(ReadRecord8.class)) { - readRecord8(conn); - } else if (procClass.equals(ReadRecord9.class)) { - readRecord9(conn); - } else if (procClass.equals(ReadRecord10.class)) { - readRecord10(conn); - } else if (procClass.equals(MaxRecord1.class)) { - maxRecord1(conn); - } else if (procClass.equals(MaxRecord2.class)) { - maxRecord2(conn); - } else if (procClass.equals(MaxRecord3.class)) { - maxRecord3(conn); - } else if (procClass.equals(MaxRecord4.class)) { - maxRecord4(conn); - } else if (procClass.equals(MaxRecord5.class)) { - maxRecord5(conn); - } else if (procClass.equals(MaxRecord6.class)) { - maxRecord6(conn); - } else if (procClass.equals(MaxRecord7.class)) { - maxRecord7(conn); - } else if (procClass.equals(MaxRecord8.class)) { - maxRecord8(conn); - } else if (procClass.equals(MaxRecord9.class)) { - maxRecord9(conn); - } else if (procClass.equals(MaxRecord10.class)) { - maxRecord10(conn); - } else if (procClass.equals(SumRecord1.class)) { - sumRecord1(conn); - } else if (procClass.equals(SumRecord2.class)) { - sumRecord2(conn); - } else if (procClass.equals(SumRecord3.class)) { - sumRecord3(conn); - } else if (procClass.equals(SumRecord4.class)) { - sumRecord4(conn); - } else if (procClass.equals(SumRecord5.class)) { - sumRecord5(conn); - } else if (procClass.equals(SumRecord6.class)) { - sumRecord6(conn); - } else if (procClass.equals(SumRecord7.class)) { - sumRecord7(conn); - } else if (procClass.equals(SumRecord8.class)) { - sumRecord8(conn); - } else if (procClass.equals(SumRecord9.class)) { - sumRecord9(conn); - } else if (procClass.equals(SumRecord10.class)) { - sumRecord10(conn); - } - - return (TransactionStatus.SUCCESS); - } - - ///////////////////////// - // READ - ///////////////////////// - - private void readRecord1(Connection conn) throws SQLException { - ReadRecord1 proc = this.getProcedure(ReadRecord1.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } - - private void readRecord2(Connection conn) throws SQLException { - ReadRecord2 proc = this.getProcedure(ReadRecord2.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } - - private void readRecord3(Connection conn) throws SQLException { - ReadRecord3 proc = this.getProcedure(ReadRecord3.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } - - private void readRecord4(Connection conn) throws SQLException { - ReadRecord4 proc = this.getProcedure(ReadRecord4.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } - - private void readRecord5(Connection conn) throws SQLException { - ReadRecord5 proc = this.getProcedure(ReadRecord5.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } - - private void readRecord6(Connection conn) throws SQLException { - ReadRecord6 proc = this.getProcedure(ReadRecord6.class); - - proc.run(conn, key_lower_bound, new HashMap<>()); - } + private static final Logger LOG = LoggerFactory.getLogger(HYADAPTWorker.class); + + private static CounterGenerator insertRecord; + private final double selectivity = configuration.getSelectivity(); + private final int key_lower_bound = (int) ((1 - selectivity) * HYADAPTConstants.RANGE); + + public HYADAPTWorker(HYADAPTBenchmark benchmarkModule, int id, int init_record_count) { + super(benchmarkModule, id); + LOG.info("Key lower bound :: {}", key_lower_bound); + + synchronized (HYADAPTWorker.class) { + // We must know where to start inserting + if (insertRecord == null) { + insertRecord = new CounterGenerator(init_record_count); + } + } + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + Class procClass = nextTrans.getProcedureClass(); + + if (procClass.equals(ReadRecord1.class)) { + readRecord1(conn); + } else if (procClass.equals(ReadRecord2.class)) { + readRecord2(conn); + } else if (procClass.equals(ReadRecord3.class)) { + readRecord3(conn); + } else if (procClass.equals(ReadRecord4.class)) { + readRecord4(conn); + } else if (procClass.equals(ReadRecord5.class)) { + readRecord5(conn); + } else if (procClass.equals(ReadRecord6.class)) { + readRecord6(conn); + } else if (procClass.equals(ReadRecord7.class)) { + readRecord7(conn); + } else if (procClass.equals(ReadRecord8.class)) { + readRecord8(conn); + } else if (procClass.equals(ReadRecord9.class)) { + readRecord9(conn); + } else if (procClass.equals(ReadRecord10.class)) { + readRecord10(conn); + } else if (procClass.equals(MaxRecord1.class)) { + maxRecord1(conn); + } else if (procClass.equals(MaxRecord2.class)) { + maxRecord2(conn); + } else if (procClass.equals(MaxRecord3.class)) { + maxRecord3(conn); + } else if (procClass.equals(MaxRecord4.class)) { + maxRecord4(conn); + } else if (procClass.equals(MaxRecord5.class)) { + maxRecord5(conn); + } else if (procClass.equals(MaxRecord6.class)) { + maxRecord6(conn); + } else if (procClass.equals(MaxRecord7.class)) { + maxRecord7(conn); + } else if (procClass.equals(MaxRecord8.class)) { + maxRecord8(conn); + } else if (procClass.equals(MaxRecord9.class)) { + maxRecord9(conn); + } else if (procClass.equals(MaxRecord10.class)) { + maxRecord10(conn); + } else if (procClass.equals(SumRecord1.class)) { + sumRecord1(conn); + } else if (procClass.equals(SumRecord2.class)) { + sumRecord2(conn); + } else if (procClass.equals(SumRecord3.class)) { + sumRecord3(conn); + } else if (procClass.equals(SumRecord4.class)) { + sumRecord4(conn); + } else if (procClass.equals(SumRecord5.class)) { + sumRecord5(conn); + } else if (procClass.equals(SumRecord6.class)) { + sumRecord6(conn); + } else if (procClass.equals(SumRecord7.class)) { + sumRecord7(conn); + } else if (procClass.equals(SumRecord8.class)) { + sumRecord8(conn); + } else if (procClass.equals(SumRecord9.class)) { + sumRecord9(conn); + } else if (procClass.equals(SumRecord10.class)) { + sumRecord10(conn); + } + + return (TransactionStatus.SUCCESS); + } + + ///////////////////////// + // READ + ///////////////////////// + + private void readRecord1(Connection conn) throws SQLException { + ReadRecord1 proc = this.getProcedure(ReadRecord1.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord2(Connection conn) throws SQLException { + ReadRecord2 proc = this.getProcedure(ReadRecord2.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord3(Connection conn) throws SQLException { + ReadRecord3 proc = this.getProcedure(ReadRecord3.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord4(Connection conn) throws SQLException { + ReadRecord4 proc = this.getProcedure(ReadRecord4.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord5(Connection conn) throws SQLException { + ReadRecord5 proc = this.getProcedure(ReadRecord5.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord6(Connection conn) throws SQLException { + ReadRecord6 proc = this.getProcedure(ReadRecord6.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } + + private void readRecord7(Connection conn) throws SQLException { + ReadRecord7 proc = this.getProcedure(ReadRecord7.class); + + proc.run(conn, key_lower_bound, new HashMap<>()); + } - private void readRecord7(Connection conn) throws SQLException { - ReadRecord7 proc = this.getProcedure(ReadRecord7.class); + private void readRecord8(Connection conn) throws SQLException { + ReadRecord8 proc = this.getProcedure(ReadRecord8.class); - proc.run(conn, key_lower_bound, new HashMap<>()); - } + proc.run(conn, key_lower_bound, new HashMap<>()); + } - private void readRecord8(Connection conn) throws SQLException { - ReadRecord8 proc = this.getProcedure(ReadRecord8.class); + private void readRecord9(Connection conn) throws SQLException { + ReadRecord9 proc = this.getProcedure(ReadRecord9.class); - proc.run(conn, key_lower_bound, new HashMap<>()); - } + proc.run(conn, key_lower_bound, new HashMap<>()); + } - private void readRecord9(Connection conn) throws SQLException { - ReadRecord9 proc = this.getProcedure(ReadRecord9.class); + private void readRecord10(Connection conn) throws SQLException { + ReadRecord10 proc = this.getProcedure(ReadRecord10.class); - proc.run(conn, key_lower_bound, new HashMap<>()); - } + proc.run(conn, key_lower_bound, new HashMap<>()); + } - private void readRecord10(Connection conn) throws SQLException { - ReadRecord10 proc = this.getProcedure(ReadRecord10.class); + ///////////////////////// + // MAX + ///////////////////////// - proc.run(conn, key_lower_bound, new HashMap<>()); - } + private void maxRecord1(Connection conn) throws SQLException { + MaxRecord1 proc = this.getProcedure(MaxRecord1.class); - ///////////////////////// - // MAX - ///////////////////////// + proc.run(conn, key_lower_bound); + } - private void maxRecord1(Connection conn) throws SQLException { - MaxRecord1 proc = this.getProcedure(MaxRecord1.class); + private void maxRecord2(Connection conn) throws SQLException { + MaxRecord2 proc = this.getProcedure(MaxRecord2.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord2(Connection conn) throws SQLException { - MaxRecord2 proc = this.getProcedure(MaxRecord2.class); + private void maxRecord3(Connection conn) throws SQLException { + MaxRecord3 proc = this.getProcedure(MaxRecord3.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord3(Connection conn) throws SQLException { - MaxRecord3 proc = this.getProcedure(MaxRecord3.class); + private void maxRecord4(Connection conn) throws SQLException { + MaxRecord4 proc = this.getProcedure(MaxRecord4.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord4(Connection conn) throws SQLException { - MaxRecord4 proc = this.getProcedure(MaxRecord4.class); + private void maxRecord5(Connection conn) throws SQLException { + MaxRecord5 proc = this.getProcedure(MaxRecord5.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord5(Connection conn) throws SQLException { - MaxRecord5 proc = this.getProcedure(MaxRecord5.class); + private void maxRecord6(Connection conn) throws SQLException { + MaxRecord6 proc = this.getProcedure(MaxRecord6.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord6(Connection conn) throws SQLException { - MaxRecord6 proc = this.getProcedure(MaxRecord6.class); + private void maxRecord7(Connection conn) throws SQLException { + MaxRecord7 proc = this.getProcedure(MaxRecord7.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord7(Connection conn) throws SQLException { - MaxRecord7 proc = this.getProcedure(MaxRecord7.class); + private void maxRecord8(Connection conn) throws SQLException { + MaxRecord8 proc = this.getProcedure(MaxRecord8.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord8(Connection conn) throws SQLException { - MaxRecord8 proc = this.getProcedure(MaxRecord8.class); + private void maxRecord9(Connection conn) throws SQLException { + MaxRecord9 proc = this.getProcedure(MaxRecord9.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord9(Connection conn) throws SQLException { - MaxRecord9 proc = this.getProcedure(MaxRecord9.class); + private void maxRecord10(Connection conn) throws SQLException { + MaxRecord10 proc = this.getProcedure(MaxRecord10.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void maxRecord10(Connection conn) throws SQLException { - MaxRecord10 proc = this.getProcedure(MaxRecord10.class); + ///////////////////////// + // SUM + ///////////////////////// - proc.run(conn, key_lower_bound); - } + private void sumRecord1(Connection conn) throws SQLException { + SumRecord1 proc = this.getProcedure(SumRecord1.class); - ///////////////////////// - // SUM - ///////////////////////// + proc.run(conn, key_lower_bound); + } - private void sumRecord1(Connection conn) throws SQLException { - SumRecord1 proc = this.getProcedure(SumRecord1.class); + private void sumRecord2(Connection conn) throws SQLException { + SumRecord2 proc = this.getProcedure(SumRecord2.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord2(Connection conn) throws SQLException { - SumRecord2 proc = this.getProcedure(SumRecord2.class); + private void sumRecord3(Connection conn) throws SQLException { + SumRecord3 proc = this.getProcedure(SumRecord3.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord3(Connection conn) throws SQLException { - SumRecord3 proc = this.getProcedure(SumRecord3.class); + private void sumRecord4(Connection conn) throws SQLException { + SumRecord4 proc = this.getProcedure(SumRecord4.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord4(Connection conn) throws SQLException { - SumRecord4 proc = this.getProcedure(SumRecord4.class); + private void sumRecord5(Connection conn) throws SQLException { + SumRecord5 proc = this.getProcedure(SumRecord5.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord5(Connection conn) throws SQLException { - SumRecord5 proc = this.getProcedure(SumRecord5.class); + private void sumRecord6(Connection conn) throws SQLException { + SumRecord6 proc = this.getProcedure(SumRecord6.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord6(Connection conn) throws SQLException { - SumRecord6 proc = this.getProcedure(SumRecord6.class); + private void sumRecord7(Connection conn) throws SQLException { + SumRecord7 proc = this.getProcedure(SumRecord7.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord7(Connection conn) throws SQLException { - SumRecord7 proc = this.getProcedure(SumRecord7.class); + private void sumRecord8(Connection conn) throws SQLException { + SumRecord8 proc = this.getProcedure(SumRecord8.class); - proc.run(conn, key_lower_bound); - } + proc.run(conn, key_lower_bound); + } - private void sumRecord8(Connection conn) throws SQLException { - SumRecord8 proc = this.getProcedure(SumRecord8.class); + private void sumRecord9(Connection conn) throws SQLException { + SumRecord9 proc = this.getProcedure(SumRecord9.class); - proc.run(conn, key_lower_bound); - } - - private void sumRecord9(Connection conn) throws SQLException { - SumRecord9 proc = this.getProcedure(SumRecord9.class); - - proc.run(conn, key_lower_bound); - } - - private void sumRecord10(Connection conn) throws SQLException { - SumRecord10 proc = this.getProcedure(SumRecord10.class); + proc.run(conn, key_lower_bound); + } - proc.run(conn, key_lower_bound); - } + private void sumRecord10(Connection conn) throws SQLException { + SumRecord10 proc = this.getProcedure(SumRecord10.class); + proc.run(conn, key_lower_bound); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java index e141c3daf..3663affd7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord1.java @@ -19,33 +19,32 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MaxRecord1 extends Procedure { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(MaxRecord1.class); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(MaxRecord1.class); - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - int max = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } + public void run(Connection conn, int keyname) throws SQLException { + int max = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } - assert max != -1; + } } - + assert max != -1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java index 37bfd3377..220f39245 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord10.java @@ -19,37 +19,36 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord10 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " - + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " - + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " - + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231), " - + "MAX(FIELD222), MAX(FIELD70), MAX(FIELD191), MAX(FIELD52), MAX(FIELD72), MAX(FIELD155), MAX(FIELD88), MAX(FIELD175), MAX(FIELD43), MAX(FIELD172), MAX(FIELD173), MAX(FIELD13), MAX(FIELD152), MAX(FIELD180), MAX(FIELD62), MAX(FIELD121), MAX(FIELD25), MAX(FIELD55), MAX(FIELD247), MAX(FIELD36), MAX(FIELD15), MAX(FIELD210), MAX(FIELD56), MAX(FIELD6), MAX(FIELD104), " - + "MAX(FIELD14), MAX(FIELD132), MAX(FIELD135), MAX(FIELD168), MAX(FIELD176), MAX(FIELD28), MAX(FIELD245), MAX(FIELD11), MAX(FIELD184), MAX(FIELD131), MAX(FIELD161), MAX(FIELD5), MAX(FIELD21), MAX(FIELD242), MAX(FIELD87), MAX(FIELD44), MAX(FIELD45), MAX(FIELD205), MAX(FIELD57), MAX(FIELD19), MAX(FIELD33), MAX(FIELD90), MAX(FIELD240), MAX(FIELD79), MAX(FIELD82) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " + + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " + + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " + + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231), " + + "MAX(FIELD222), MAX(FIELD70), MAX(FIELD191), MAX(FIELD52), MAX(FIELD72), MAX(FIELD155), MAX(FIELD88), MAX(FIELD175), MAX(FIELD43), MAX(FIELD172), MAX(FIELD173), MAX(FIELD13), MAX(FIELD152), MAX(FIELD180), MAX(FIELD62), MAX(FIELD121), MAX(FIELD25), MAX(FIELD55), MAX(FIELD247), MAX(FIELD36), MAX(FIELD15), MAX(FIELD210), MAX(FIELD56), MAX(FIELD6), MAX(FIELD104), " + + "MAX(FIELD14), MAX(FIELD132), MAX(FIELD135), MAX(FIELD168), MAX(FIELD176), MAX(FIELD28), MAX(FIELD245), MAX(FIELD11), MAX(FIELD184), MAX(FIELD131), MAX(FIELD161), MAX(FIELD5), MAX(FIELD21), MAX(FIELD242), MAX(FIELD87), MAX(FIELD44), MAX(FIELD45), MAX(FIELD205), MAX(FIELD57), MAX(FIELD19), MAX(FIELD33), MAX(FIELD90), MAX(FIELD240), MAX(FIELD79), MAX(FIELD82) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - int max = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } + public void run(Connection conn, int keyname) throws SQLException { + int max = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } - assert max != -1; + } } - + assert max != -1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java index 2a0a3d227..25fedc209 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord2.java @@ -19,29 +19,28 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord2 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - int max = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } + public void run(Connection conn, int keyname) throws SQLException { + int max = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } - assert max != -1; + } } - + assert max != -1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java index efca4788f..ddd8a676a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord3.java @@ -19,29 +19,29 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord3 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - int max = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } - assert max != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + int max = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } + } + assert max != -1; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java index 2061715fe..3a184ead3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord4.java @@ -19,31 +19,30 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord4 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - int max = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } + public void run(Connection conn, int keyname) throws SQLException { + int max = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } - assert max != -1; + } } - + assert max != -1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java index b1f54d74b..58bd4c265 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord5.java @@ -19,32 +19,31 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord5 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - int max = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } + public void run(Connection conn, int keyname) throws SQLException { + int max = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } - assert max != -1; + } } - + assert max != -1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java index bb2e3daa8..8611f268f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord6.java @@ -19,33 +19,32 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord6 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " - + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " + + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - int max = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } - assert max != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + int max = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } + } + assert max != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java index 3ae087a3f..4d8a500ba 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord7.java @@ -19,34 +19,33 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord7 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " - + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " - + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " + + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " + + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - int max = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } - assert max != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + int max = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } + } + assert max != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java index e43881edc..00896ce42 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord8.java @@ -19,35 +19,34 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord8 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " - + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " - + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " - + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " + + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " + + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " + + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - int max = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } - assert max != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + int max = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } + } + assert max != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java index 7099acfed..409443b40 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/MaxRecord9.java @@ -19,36 +19,35 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class MaxRecord9 extends Procedure { - public final SQLStmt maxStmt = new SQLStmt( - "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " - + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " - + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " - + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " - + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " - + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " - + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " - + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231), " - + "MAX(FIELD222), MAX(FIELD70), MAX(FIELD191), MAX(FIELD52), MAX(FIELD72), MAX(FIELD155), MAX(FIELD88), MAX(FIELD175), MAX(FIELD43), MAX(FIELD172), MAX(FIELD173), MAX(FIELD13), MAX(FIELD152), MAX(FIELD180), MAX(FIELD62), MAX(FIELD121), MAX(FIELD25), MAX(FIELD55), MAX(FIELD247), MAX(FIELD36), MAX(FIELD15), MAX(FIELD210), MAX(FIELD56), MAX(FIELD6), MAX(FIELD104) " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt maxStmt = + new SQLStmt( + "SELECT MAX(FIELD198), MAX(FIELD206), MAX(FIELD169), MAX(FIELD119), MAX(FIELD9), MAX(FIELD220), MAX(FIELD2), MAX(FIELD230), MAX(FIELD212), MAX(FIELD164), MAX(FIELD111), MAX(FIELD136), MAX(FIELD106), MAX(FIELD8), MAX(FIELD112), MAX(FIELD4), MAX(FIELD234), MAX(FIELD147), MAX(FIELD35), MAX(FIELD114), MAX(FIELD89), MAX(FIELD127), MAX(FIELD144), MAX(FIELD71), MAX(FIELD186), " + + "MAX(FIELD34), MAX(FIELD145), MAX(FIELD124), MAX(FIELD146), MAX(FIELD7), MAX(FIELD40), MAX(FIELD227), MAX(FIELD59), MAX(FIELD190), MAX(FIELD249), MAX(FIELD157), MAX(FIELD38), MAX(FIELD64), MAX(FIELD134), MAX(FIELD167), MAX(FIELD63), MAX(FIELD178), MAX(FIELD156), MAX(FIELD94), MAX(FIELD84), MAX(FIELD187), MAX(FIELD153), MAX(FIELD158), MAX(FIELD42), MAX(FIELD236), " + + "MAX(FIELD83), MAX(FIELD182), MAX(FIELD107), MAX(FIELD76), MAX(FIELD58), MAX(FIELD102), MAX(FIELD96), MAX(FIELD31), MAX(FIELD244), MAX(FIELD54), MAX(FIELD37), MAX(FIELD228), MAX(FIELD24), MAX(FIELD120), MAX(FIELD92), MAX(FIELD233), MAX(FIELD170), MAX(FIELD209), MAX(FIELD93), MAX(FIELD12), MAX(FIELD47), MAX(FIELD200), MAX(FIELD248), MAX(FIELD171), MAX(FIELD22), " + + "MAX(FIELD166), MAX(FIELD213), MAX(FIELD101), MAX(FIELD97), MAX(FIELD29), MAX(FIELD237), MAX(FIELD149), MAX(FIELD49), MAX(FIELD142), MAX(FIELD181), MAX(FIELD196), MAX(FIELD75), MAX(FIELD188), MAX(FIELD208), MAX(FIELD218), MAX(FIELD183), MAX(FIELD250), MAX(FIELD151), MAX(FIELD189), MAX(FIELD60), MAX(FIELD226), MAX(FIELD214), MAX(FIELD174), MAX(FIELD128), MAX(FIELD239), " + + "MAX(FIELD27), MAX(FIELD235), MAX(FIELD217), MAX(FIELD98), MAX(FIELD143), MAX(FIELD165), MAX(FIELD160), MAX(FIELD109), MAX(FIELD65), MAX(FIELD23), MAX(FIELD74), MAX(FIELD207), MAX(FIELD115), MAX(FIELD69), MAX(FIELD108), MAX(FIELD30), MAX(FIELD201), MAX(FIELD221), MAX(FIELD202), MAX(FIELD20), MAX(FIELD225), MAX(FIELD105), MAX(FIELD91), MAX(FIELD95), MAX(FIELD150), " + + "MAX(FIELD123), MAX(FIELD16), MAX(FIELD238), MAX(FIELD81), MAX(FIELD3), MAX(FIELD219), MAX(FIELD204), MAX(FIELD68), MAX(FIELD203), MAX(FIELD73), MAX(FIELD41), MAX(FIELD66), MAX(FIELD192), MAX(FIELD113), MAX(FIELD216), MAX(FIELD117), MAX(FIELD99), MAX(FIELD126), MAX(FIELD53), MAX(FIELD1), MAX(FIELD139), MAX(FIELD116), MAX(FIELD229), MAX(FIELD100), MAX(FIELD215), " + + "MAX(FIELD48), MAX(FIELD10), MAX(FIELD86), MAX(FIELD211), MAX(FIELD17), MAX(FIELD224), MAX(FIELD122), MAX(FIELD51), MAX(FIELD103), MAX(FIELD85), MAX(FIELD110), MAX(FIELD50), MAX(FIELD162), MAX(FIELD129), MAX(FIELD243), MAX(FIELD67), MAX(FIELD133), MAX(FIELD138), MAX(FIELD193), MAX(FIELD141), MAX(FIELD232), MAX(FIELD118), MAX(FIELD159), MAX(FIELD199), MAX(FIELD39), " + + "MAX(FIELD154), MAX(FIELD137), MAX(FIELD163), MAX(FIELD179), MAX(FIELD77), MAX(FIELD194), MAX(FIELD130), MAX(FIELD46), MAX(FIELD32), MAX(FIELD125), MAX(FIELD241), MAX(FIELD246), MAX(FIELD140), MAX(FIELD26), MAX(FIELD78), MAX(FIELD177), MAX(FIELD148), MAX(FIELD223), MAX(FIELD185), MAX(FIELD197), MAX(FIELD61), MAX(FIELD195), MAX(FIELD18), MAX(FIELD80), MAX(FIELD231), " + + "MAX(FIELD222), MAX(FIELD70), MAX(FIELD191), MAX(FIELD52), MAX(FIELD72), MAX(FIELD155), MAX(FIELD88), MAX(FIELD175), MAX(FIELD43), MAX(FIELD172), MAX(FIELD173), MAX(FIELD13), MAX(FIELD152), MAX(FIELD180), MAX(FIELD62), MAX(FIELD121), MAX(FIELD25), MAX(FIELD55), MAX(FIELD247), MAX(FIELD36), MAX(FIELD15), MAX(FIELD210), MAX(FIELD56), MAX(FIELD6), MAX(FIELD104) " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { - stmt.setInt(1, keyname); - int max = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - max = r.getInt(1); - } - } - assert max != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, maxStmt)) { + stmt.setInt(1, keyname); + int max = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + max = r.getInt(1); } + } + assert max != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord1.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord1.java index 7402e046f..14631fc92 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord1.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,22 +28,22 @@ public class ReadRecord1 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 1); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 1); i++) { + results.put(i, r.getInt(i)); + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord10.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord10.java index d74f1cf9b..2a9b09fc6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord10.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,32 +27,31 @@ import java.util.Map; public class ReadRecord10 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " - + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " - + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " - + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231, " - + "FIELD222, FIELD70, FIELD191, FIELD52, FIELD72, FIELD155, FIELD88, FIELD175, FIELD43, FIELD172, FIELD173, FIELD13, FIELD152, FIELD180, FIELD62, FIELD121, FIELD25, FIELD55, FIELD247, FIELD36, FIELD15, FIELD210, FIELD56, FIELD6, FIELD104, " - + "FIELD14, FIELD132, FIELD135, FIELD168, FIELD176, FIELD28, FIELD245, FIELD11, FIELD184, FIELD131, FIELD161, FIELD5, FIELD21, FIELD242, FIELD87, FIELD44, FIELD45, FIELD205, FIELD57, FIELD19, FIELD33, FIELD90, FIELD240, FIELD79, FIELD82 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " + + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " + + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " + + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231, " + + "FIELD222, FIELD70, FIELD191, FIELD52, FIELD72, FIELD155, FIELD88, FIELD175, FIELD43, FIELD172, FIELD173, FIELD13, FIELD152, FIELD180, FIELD62, FIELD121, FIELD25, FIELD55, FIELD247, FIELD36, FIELD15, FIELD210, FIELD56, FIELD6, FIELD104, " + + "FIELD14, FIELD132, FIELD135, FIELD168, FIELD176, FIELD28, FIELD245, FIELD11, FIELD184, FIELD131, FIELD161, FIELD5, FIELD21, FIELD242, FIELD87, FIELD44, FIELD45, FIELD205, FIELD57, FIELD19, FIELD33, FIELD90, FIELD240, FIELD79, FIELD82 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 10); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 10); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord2.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord2.java index 42516289e..4217a811d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord2.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,23 +27,23 @@ import java.util.Map; public class ReadRecord2 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 2); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 2); i++) { + results.put(i, r.getInt(i)); + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord3.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord3.java index d599a759a..75cf77cef 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord3.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,25 +27,24 @@ import java.util.Map; public class ReadRecord3 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 3); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 3); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord4.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord4.java index 321708cac..2067e9c0b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord4.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,26 +27,25 @@ import java.util.Map; public class ReadRecord4 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 4); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 4); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord5.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord5.java index 90b4e5515..33b1d6869 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord5.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,27 +27,26 @@ import java.util.Map; public class ReadRecord5 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 5); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 5); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord6.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord6.java index 96d15dbd0..181433ffe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord6.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,28 +27,27 @@ import java.util.Map; public class ReadRecord6 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " - + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " + + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 6); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 6); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord7.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord7.java index 06744abcb..26a6e31cb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord7.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,29 +27,28 @@ import java.util.Map; public class ReadRecord7 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " - + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " - + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " + + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " + + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 7); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 7); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord8.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord8.java index 154367c85..aa98b2fc6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord8.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,30 +27,29 @@ import java.util.Map; public class ReadRecord8 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " - + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " - + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " - + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " + + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " + + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " + + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 8); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 8); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord9.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord9.java index f9e5ca836..1a703fda5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/ReadRecord9.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.hyadapt.HYADAPTConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,31 +27,30 @@ import java.util.Map; public class ReadRecord9 extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " - + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " - + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " - + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " - + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " - + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " - + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " - + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231, " - + "FIELD222, FIELD70, FIELD191, FIELD52, FIELD72, FIELD155, FIELD88, FIELD175, FIELD43, FIELD172, FIELD173, FIELD13, FIELD152, FIELD180, FIELD62, FIELD121, FIELD25, FIELD55, FIELD247, FIELD36, FIELD15, FIELD210, FIELD56, FIELD6, FIELD104 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt readStmt = + new SQLStmt( + "SELECT FIELD198, FIELD206, FIELD169, FIELD119, FIELD9, FIELD220, FIELD2, FIELD230, FIELD212, FIELD164, FIELD111, FIELD136, FIELD106, FIELD8, FIELD112, FIELD4, FIELD234, FIELD147, FIELD35, FIELD114, FIELD89, FIELD127, FIELD144, FIELD71, FIELD186, " + + "FIELD34, FIELD145, FIELD124, FIELD146, FIELD7, FIELD40, FIELD227, FIELD59, FIELD190, FIELD249, FIELD157, FIELD38, FIELD64, FIELD134, FIELD167, FIELD63, FIELD178, FIELD156, FIELD94, FIELD84, FIELD187, FIELD153, FIELD158, FIELD42, FIELD236, " + + "FIELD83, FIELD182, FIELD107, FIELD76, FIELD58, FIELD102, FIELD96, FIELD31, FIELD244, FIELD54, FIELD37, FIELD228, FIELD24, FIELD120, FIELD92, FIELD233, FIELD170, FIELD209, FIELD93, FIELD12, FIELD47, FIELD200, FIELD248, FIELD171, FIELD22, " + + "FIELD166, FIELD213, FIELD101, FIELD97, FIELD29, FIELD237, FIELD149, FIELD49, FIELD142, FIELD181, FIELD196, FIELD75, FIELD188, FIELD208, FIELD218, FIELD183, FIELD250, FIELD151, FIELD189, FIELD60, FIELD226, FIELD214, FIELD174, FIELD128, FIELD239, " + + "FIELD27, FIELD235, FIELD217, FIELD98, FIELD143, FIELD165, FIELD160, FIELD109, FIELD65, FIELD23, FIELD74, FIELD207, FIELD115, FIELD69, FIELD108, FIELD30, FIELD201, FIELD221, FIELD202, FIELD20, FIELD225, FIELD105, FIELD91, FIELD95, FIELD150, " + + "FIELD123, FIELD16, FIELD238, FIELD81, FIELD3, FIELD219, FIELD204, FIELD68, FIELD203, FIELD73, FIELD41, FIELD66, FIELD192, FIELD113, FIELD216, FIELD117, FIELD99, FIELD126, FIELD53, FIELD1, FIELD139, FIELD116, FIELD229, FIELD100, FIELD215, " + + "FIELD48, FIELD10, FIELD86, FIELD211, FIELD17, FIELD224, FIELD122, FIELD51, FIELD103, FIELD85, FIELD110, FIELD50, FIELD162, FIELD129, FIELD243, FIELD67, FIELD133, FIELD138, FIELD193, FIELD141, FIELD232, FIELD118, FIELD159, FIELD199, FIELD39, " + + "FIELD154, FIELD137, FIELD163, FIELD179, FIELD77, FIELD194, FIELD130, FIELD46, FIELD32, FIELD125, FIELD241, FIELD246, FIELD140, FIELD26, FIELD78, FIELD177, FIELD148, FIELD223, FIELD185, FIELD197, FIELD61, FIELD195, FIELD18, FIELD80, FIELD231, " + + "FIELD222, FIELD70, FIELD191, FIELD52, FIELD72, FIELD155, FIELD88, FIELD175, FIELD43, FIELD172, FIELD173, FIELD13, FIELD152, FIELD180, FIELD62, FIELD121, FIELD25, FIELD55, FIELD247, FIELD36, FIELD15, FIELD210, FIELD56, FIELD6, FIELD104 " + + "FROM htable WHERE FIELD1>?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, Map results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 9); i++) { - results.put(i, r.getInt(i)); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, Map results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 1; i <= ((HYADAPTConstants.FIELD_COUNT / 10) * 9); i++) { + results.put(i, r.getInt(i)); + } } + } } - - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java index 372634d91..b92b397f5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord1.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -27,22 +26,22 @@ public class SumRecord1 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java index a9730dec7..145d6f934 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord10.java @@ -19,37 +19,36 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord10 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " - + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " - + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " - + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 + " - + "FIELD222 + FIELD70 + FIELD191 + FIELD52 + FIELD72 + FIELD155 + FIELD88 + FIELD175 + FIELD43 + FIELD172 + FIELD173 + FIELD13 + FIELD152 + FIELD180 + FIELD62 + FIELD121 + FIELD25 + FIELD55 + FIELD247 + FIELD36 + FIELD15 + FIELD210 + FIELD56 + FIELD6 + FIELD104 + " - + "FIELD14 + FIELD132 + FIELD135 + FIELD168 + FIELD176 + FIELD28 + FIELD245 + FIELD11 + FIELD184 + FIELD131 + FIELD161 + FIELD5 + FIELD21 + FIELD242 + FIELD87 + FIELD44 + FIELD45 + FIELD205 + FIELD57 + FIELD19 + FIELD33 + FIELD90 + FIELD240 + FIELD79 + FIELD82 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " + + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " + + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " + + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 + " + + "FIELD222 + FIELD70 + FIELD191 + FIELD52 + FIELD72 + FIELD155 + FIELD88 + FIELD175 + FIELD43 + FIELD172 + FIELD173 + FIELD13 + FIELD152 + FIELD180 + FIELD62 + FIELD121 + FIELD25 + FIELD55 + FIELD247 + FIELD36 + FIELD15 + FIELD210 + FIELD56 + FIELD6 + FIELD104 + " + + "FIELD14 + FIELD132 + FIELD135 + FIELD168 + FIELD176 + FIELD28 + FIELD245 + FIELD11 + FIELD184 + FIELD131 + FIELD161 + FIELD5 + FIELD21 + FIELD242 + FIELD87 + FIELD44 + FIELD45 + FIELD205 + FIELD57 + FIELD19 + FIELD33 + FIELD90 + FIELD240 + FIELD79 + FIELD82 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java index 34d3b1765..11f9a0a5b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord2.java @@ -19,29 +19,28 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord2 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java index b144da52a..d8186299d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord3.java @@ -19,30 +19,29 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord3 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java index bfef02bfa..76f72928b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord4.java @@ -19,30 +19,30 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord4 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java index 30aa5f4fe..b45501072 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord5.java @@ -19,32 +19,31 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord5 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java index 57ef98115..8170b6fa2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord6.java @@ -19,33 +19,32 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord6 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " - + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " + + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java index 310110eb0..2fffe3240 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord7.java @@ -19,34 +19,33 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord7 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " - + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " - + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " + + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " + + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java index e6c902d45..64309b19f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord8.java @@ -19,35 +19,34 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord8 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " - + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " - + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " - + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " + + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " + + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " + + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java index 9329ac523..9f15f62d9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/hyadapt/procedures/SumRecord9.java @@ -19,36 +19,35 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SumRecord9 extends Procedure { - public final SQLStmt sumStmt = new SQLStmt( - "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " - + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " - + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " - + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " - + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " - + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " - + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " - + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 + " - + "FIELD222 + FIELD70 + FIELD191 + FIELD52 + FIELD72 + FIELD155 + FIELD88 + FIELD175 + FIELD43 + FIELD172 + FIELD173 + FIELD13 + FIELD152 + FIELD180 + FIELD62 + FIELD121 + FIELD25 + FIELD55 + FIELD247 + FIELD36 + FIELD15 + FIELD210 + FIELD56 + FIELD6 + FIELD104 " - + "FROM htable WHERE FIELD1>?"); + public final SQLStmt sumStmt = + new SQLStmt( + "SELECT FIELD198 + FIELD206 + FIELD169 + FIELD119 + FIELD9 + FIELD220 + FIELD2 + FIELD230 + FIELD212 + FIELD164 + FIELD111 + FIELD136 + FIELD106 + FIELD8 + FIELD112 + FIELD4 + FIELD234 + FIELD147 + FIELD35 + FIELD114 + FIELD89 + FIELD127 + FIELD144 + FIELD71 + FIELD186 + " + + "FIELD34 + FIELD145 + FIELD124 + FIELD146 + FIELD7 + FIELD40 + FIELD227 + FIELD59 + FIELD190 + FIELD249 + FIELD157 + FIELD38 + FIELD64 + FIELD134 + FIELD167 + FIELD63 + FIELD178 + FIELD156 + FIELD94 + FIELD84 + FIELD187 + FIELD153 + FIELD158 + FIELD42 + FIELD236 + " + + "FIELD83 + FIELD182 + FIELD107 + FIELD76 + FIELD58 + FIELD102 + FIELD96 + FIELD31 + FIELD244 + FIELD54 + FIELD37 + FIELD228 + FIELD24 + FIELD120 + FIELD92 + FIELD233 + FIELD170 + FIELD209 + FIELD93 + FIELD12 + FIELD47 + FIELD200 + FIELD248 + FIELD171 + FIELD22 + " + + "FIELD166 + FIELD213 + FIELD101 + FIELD97 + FIELD29 + FIELD237 + FIELD149 + FIELD49 + FIELD142 + FIELD181 + FIELD196 + FIELD75 + FIELD188 + FIELD208 + FIELD218 + FIELD183 + FIELD250 + FIELD151 + FIELD189 + FIELD60 + FIELD226 + FIELD214 + FIELD174 + FIELD128 + FIELD239 + " + + "FIELD27 + FIELD235 + FIELD217 + FIELD98 + FIELD143 + FIELD165 + FIELD160 + FIELD109 + FIELD65 + FIELD23 + FIELD74 + FIELD207 + FIELD115 + FIELD69 + FIELD108 + FIELD30 + FIELD201 + FIELD221 + FIELD202 + FIELD20 + FIELD225 + FIELD105 + FIELD91 + FIELD95 + FIELD150 + " + + "FIELD123 + FIELD16 + FIELD238 + FIELD81 + FIELD3 + FIELD219 + FIELD204 + FIELD68 + FIELD203 + FIELD73 + FIELD41 + FIELD66 + FIELD192 + FIELD113 + FIELD216 + FIELD117 + FIELD99 + FIELD126 + FIELD53 + FIELD1 + FIELD139 + FIELD116 + FIELD229 + FIELD100 + FIELD215 + " + + "FIELD48 + FIELD10 + FIELD86 + FIELD211 + FIELD17 + FIELD224 + FIELD122 + FIELD51 + FIELD103 + FIELD85 + FIELD110 + FIELD50 + FIELD162 + FIELD129 + FIELD243 + FIELD67 + FIELD133 + FIELD138 + FIELD193 + FIELD141 + FIELD232 + FIELD118 + FIELD159 + FIELD199 + FIELD39 + " + + "FIELD154 + FIELD137 + FIELD163 + FIELD179 + FIELD77 + FIELD194 + FIELD130 + FIELD46 + FIELD32 + FIELD125 + FIELD241 + FIELD246 + FIELD140 + FIELD26 + FIELD78 + FIELD177 + FIELD148 + FIELD223 + FIELD185 + FIELD197 + FIELD61 + FIELD195 + FIELD18 + FIELD80 + FIELD231 + " + + "FIELD222 + FIELD70 + FIELD191 + FIELD52 + FIELD72 + FIELD155 + FIELD88 + FIELD175 + FIELD43 + FIELD172 + FIELD173 + FIELD13 + FIELD152 + FIELD180 + FIELD62 + FIELD121 + FIELD25 + FIELD55 + FIELD247 + FIELD36 + FIELD15 + FIELD210 + FIELD56 + FIELD6 + FIELD104 " + + "FROM htable WHERE FIELD1>?"); - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { - stmt.setInt(1, keyname); - int sum = -1; - try (ResultSet r = stmt.executeQuery()) { - if (r.next()) { - sum = r.getInt(1); - } - } - assert sum != -1; + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, sumStmt)) { + stmt.setInt(1, keyname); + int sum = -1; + try (ResultSet r = stmt.executeQuery()) { + if (r.next()) { + sum = r.getInt(1); } + } + assert sum != -1; } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpBenchmark.java index 9d0b502bd..c5b1d1fe4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpBenchmark.java @@ -22,40 +22,38 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.noop.procedures.NoOp; - import java.util.ArrayList; import java.util.List; /** - * The NoOp Benchmark doesn't have any tables or execute any queries. - * It's just how fast the DBMS can process NoOps + * The NoOp Benchmark doesn't have any tables or execute any queries. It's just how fast the DBMS + * can process NoOps * * @author pavlo * @author eric-haibin-lin */ public final class NoOpBenchmark extends BenchmarkModule { - public NoOpBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new NoOpWorker(this, i)); - } - return workers; - } + public NoOpBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected Loader makeLoaderImpl() { - return new NoOpLoader(this); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new NoOpWorker(this, i)); } - - @Override - protected Package getProcedurePackageImpl() { - return NoOp.class.getPackage(); - } - + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new NoOpLoader(this); + } + + @Override + protected Package getProcedurePackageImpl() { + return NoOp.class.getPackage(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpLoader.java index 9e69074f8..b071ed343 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpLoader.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.LoaderThread; - import java.util.ArrayList; import java.util.List; @@ -30,13 +29,12 @@ * @author eric-haibin-lin */ public final class NoOpLoader extends Loader { - public NoOpLoader(NoOpBenchmark benchmark) { - super(benchmark); - } - - @Override - public List createLoaderThreads() { - return new ArrayList<>(); - } + public NoOpLoader(NoOpBenchmark benchmark) { + super(benchmark); + } + @Override + public List createLoaderThreads() { + return new ArrayList<>(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpWorker.java index 1fbee1442..4d5ff8aac 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/noop/NoOpWorker.java @@ -22,38 +22,38 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.noop.procedures.NoOp; import com.oltpbenchmark.types.TransactionStatus; +import java.sql.Connection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Connection; - /** * @author pavlo * @author eric-haibin-lin */ public final class NoOpWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(NoOpWorker.class); - - private final NoOp procNoOp; - - public NoOpWorker(NoOpBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - this.procNoOp = this.getProcedure(NoOp.class); + private static final Logger LOG = LoggerFactory.getLogger(NoOpWorker.class); + + private final NoOp procNoOp; + + public NoOpWorker(NoOpBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + this.procNoOp = this.getProcedure(NoOp.class); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException { + + LOG.debug("Executing {}", this.procNoOp); + try { + this.procNoOp.run(conn); + if (LOG.isDebugEnabled()) { + LOG.debug("Successfully completed {} execution!", this.procNoOp); + } + } catch (Exception ex) { + LOG.error(ex.getMessage(), ex); } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException { - - LOG.debug("Executing {}", this.procNoOp); - try { - this.procNoOp.run(conn); - if (LOG.isDebugEnabled()) { - LOG.debug("Successfully completed {} execution!", this.procNoOp); - } - } catch (Exception ex) { - LOG.error(ex.getMessage(), ex); - } - - return (TransactionStatus.SUCCESS); - } + return (TransactionStatus.SUCCESS); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/noop/procedures/NoOp.java b/src/main/java/com/oltpbenchmark/benchmarks/noop/procedures/NoOp.java index a67548804..43a4e32fa 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/noop/procedures/NoOp.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/noop/procedures/NoOp.java @@ -19,12 +19,11 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The actual NoOp implementation @@ -33,37 +32,35 @@ * @author eric-haibin-lin */ public class NoOp extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(NoOp.class); + private static final Logger LOG = LoggerFactory.getLogger(NoOp.class); + // The query only contains a semi-colon + // That is enough for the DBMS to have to parse it and do something + public final SQLStmt noopStmt = new SQLStmt(";"); - // The query only contains a semi-colon - // That is enough for the DBMS to have to parse it and do something - public final SQLStmt noopStmt = new SQLStmt(";"); + public void run(Connection conn) { + try (PreparedStatement stmt = this.getPreparedStatement(conn, noopStmt)) { + // IMPORTANT: + // Some DBMSs will throw an exception here when you execute + // a query that does not return a result. So we are just + // going to catch the exception and ignore it. If you are porting + // a new DBMS to this benchmark, then you should disable this + // exception here and check whether it is actually working + // correctly. - public void run(Connection conn) { - try (PreparedStatement stmt = this.getPreparedStatement(conn, noopStmt)) { - // IMPORTANT: - // Some DBMSs will throw an exception here when you execute - // a query that does not return a result. So we are just - // going to catch the exception and ignore it. If you are porting - // a new DBMS to this benchmark, then you should disable this - // exception here and check whether it is actually working - // correctly. - - if (stmt.execute()) { - ResultSet r = stmt.getResultSet(); - while (r.next()) { - // Do nothing - } - r.close(); - } - - } catch (Exception ex) { - // This error should be something like "No results were returned by the query." - if (LOG.isDebugEnabled()) { - LOG.debug("Exception for NoOp query. This may be expected!", ex); - } + if (stmt.execute()) { + ResultSet r = stmt.getResultSet(); + while (r.next()) { + // Do nothing } - } + r.close(); + } + } catch (Exception ex) { + // This error should be something like "No results were returned by the query." + if (LOG.isDebugEnabled()) { + LOG.debug("Exception for NoOp query. This may be expected!", ex); + } + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java index d129d43b1..393385923 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsBenchmark.java @@ -21,50 +21,51 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.otmetrics.procedures.GetSessionRange; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * OtterTune Metrics Timeseries Benchmark + * * @author pavlo */ public final class OTMetricsBenchmark extends BenchmarkModule { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(OTMetricsBenchmark.class); + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(OTMetricsBenchmark.class); - protected final int num_sources; - protected final int num_sessions; - protected final long num_observations; + protected final int num_sources; + protected final int num_sessions; + protected final long num_observations; - public OTMetricsBenchmark(WorkloadConfiguration workConf) { - super(workConf); + public OTMetricsBenchmark(WorkloadConfiguration workConf) { + super(workConf); - // Compute the number of records per table. - this.num_sources = (int) Math.round(OTMetricsConstants.NUM_SOURCES * workConf.getScaleFactor()); - this.num_sessions = (int) Math.round(OTMetricsConstants.NUM_SESSIONS * workConf.getScaleFactor()); - this.num_observations = Math.round(OTMetricsConstants.NUM_OBSERVATIONS * workConf.getScaleFactor()); - } + // Compute the number of records per table. + this.num_sources = (int) Math.round(OTMetricsConstants.NUM_SOURCES * workConf.getScaleFactor()); + this.num_sessions = + (int) Math.round(OTMetricsConstants.NUM_SESSIONS * workConf.getScaleFactor()); + this.num_observations = + Math.round(OTMetricsConstants.NUM_OBSERVATIONS * workConf.getScaleFactor()); + } - @Override - protected Package getProcedurePackageImpl() { - return GetSessionRange.class.getPackage(); - } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new OTMetricsWorker(this, i)); - } - return workers; - } + @Override + protected Package getProcedurePackageImpl() { + return GetSessionRange.class.getPackage(); + } - @Override - protected Loader makeLoaderImpl() { - return new OTMetricsLoader(this); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new OTMetricsWorker(this, i)); } + return workers; + } + @Override + protected Loader makeLoaderImpl() { + return new OTMetricsLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsConstants.java index 6ba4f8a38..c35989df2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsConstants.java @@ -22,26 +22,23 @@ public abstract class OTMetricsConstants { - /** - * Table Names - */ - public static final String TABLENAME_SOURCES = "sources"; - public static final String TABLENAME_SESSIONS = "sessions"; - public static final String TABLENAME_TYPES = "types"; - public static final String TABLENAME_OBSERVATIONS = "observations"; - - /** - * Number of records per table. - * All of the tables in this benchmark will scale as you change the benchmark scalefactor - */ - public static final int NUM_SOURCES = 100; - public static final int NUM_SESSIONS = 1000; - public static final int NUM_TYPES = 500; // FIXED SIZE - public static final int NUM_OBSERVATIONS = 10000; - - /** - * All objects in the database will be created starting after this date - */ - public static final LocalDateTime START_DATE = LocalDateTime.of(2022, Month.JANUARY, 1, 0, 0); + /** Table Names */ + public static final String TABLENAME_SOURCES = "sources"; + public static final String TABLENAME_SESSIONS = "sessions"; + public static final String TABLENAME_TYPES = "types"; + public static final String TABLENAME_OBSERVATIONS = "observations"; + + /** + * Number of records per table. All of the tables in this benchmark will scale as you change the + * benchmark scalefactor + */ + public static final int NUM_SOURCES = 100; + + public static final int NUM_SESSIONS = 1000; + public static final int NUM_TYPES = 500; // FIXED SIZE + public static final int NUM_OBSERVATIONS = 10000; + + /** All objects in the database will be created starting after this date */ + public static final LocalDateTime START_DATE = LocalDateTime.of(2022, Month.JANUARY, 1, 0, 0); } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsLoader.java index f1a3a6de4..358ccc6b3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsLoader.java @@ -24,7 +24,6 @@ import com.oltpbenchmark.util.Pair; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -36,278 +35,290 @@ /** * OtterTune Metrics Timeseries Benchmark + * * @author pavlo */ public final class OTMetricsLoader extends Loader { - public OTMetricsLoader(OTMetricsBenchmark benchmark) { - super(benchmark); - } - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - final int loadPerThread = Math.max(this.benchmark.num_sessions / numLoaders, 1); + public OTMetricsLoader(OTMetricsBenchmark benchmark) { + super(benchmark); + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + final int loadPerThread = Math.max(this.benchmark.num_sessions / numLoaders, 1); + + // SOURCES + final CountDownLatch sourcesLatch = new CountDownLatch(1); + final CountDownLatch typesLatch = new CountDownLatch(1); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadSources(conn); + } + + @Override + public void afterLoad() { + sourcesLatch.countDown(); + } + }); - // SOURCES - final CountDownLatch sourcesLatch = new CountDownLatch(1); - final CountDownLatch typesLatch = new CountDownLatch(1); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadSources(conn); - } - @Override - public void afterLoad() { - sourcesLatch.countDown(); - } + // TYPES + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTypes(conn); + } + + @Override + public void afterLoad() { + typesLatch.countDown(); + } }); - // TYPES - threads.add(new LoaderThread(this.benchmark) { + // SESSIONS + for (int i = 0; i < numLoaders; i++) { + final int lo = i * loadPerThread; + final int hi = Math.min(this.benchmark.num_sessions, (i + 1) * loadPerThread); + + threads.add( + new LoaderThread(this.benchmark) { @Override public void load(Connection conn) throws SQLException { - loadTypes(conn); + loadSessions(conn, lo, hi); } + @Override - public void afterLoad() { - typesLatch.countDown(); + public void beforeLoad() { + try { + sourcesLatch.await(); + typesLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - }); - - // SESSIONS - for (int i = 0; i < numLoaders; i++) { - final int lo = i * loadPerThread; - final int hi = Math.min(this.benchmark.num_sessions, (i + 1) * loadPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadSessions(conn, lo, hi); - } - - @Override - public void beforeLoad() { - try { - sourcesLatch.await(); - typesLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - } - - return threads; + }); } - private void loadSessions(Connection conn, int low, int high) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_SESSIONS); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + return threads; + } - int total = 0; - int batch = 0; + private void loadSessions(Connection conn, int low, int high) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_SESSIONS); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - // SourceId/SessionId Pairs - List> observations = new ArrayList<>(); + int total = 0; + int batch = 0; - try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { - for (int i = low; i < high; i++) { - int offset = 1; + // SourceId/SessionId Pairs + List> observations = new ArrayList<>(); - // ID - insertBatch.setInt(offset++, i); + try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { + for (int i = low; i < high; i++) { + int offset = 1; - // SOURCE_ID - int source_id = i % this.benchmark.num_sources; - insertBatch.setInt(offset++, source_id); + // ID + insertBatch.setInt(offset++, i); - // AGENT - String agent = String.format("agent-%016d-v%d", source_id, rng().nextInt(10)); - insertBatch.setString(offset++, agent); + // SOURCE_ID + int source_id = i % this.benchmark.num_sources; + insertBatch.setInt(offset++, source_id); - // CREATED_TIME - // This should be the same time as the source's created_time - insertBatch.setTimestamp(offset++, Timestamp.valueOf(OTMetricsUtil.getCreateDateTime(source_id))); + // AGENT + String agent = String.format("agent-%016d-v%d", source_id, rng().nextInt(10)); + insertBatch.setString(offset++, agent); - observations.add(Pair.of(source_id, i)); + // CREATED_TIME + // This should be the same time as the source's created_time + insertBatch.setTimestamp( + offset++, Timestamp.valueOf(OTMetricsUtil.getCreateDateTime(source_id))); - insertBatch.addBatch(); - total++; + observations.add(Pair.of(source_id, i)); - if ((++batch % workConf.getBatchSize()) == 0) { - insertBatch.executeBatch(); - batch = 0; - insertBatch.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Sessions %d / %d", total, this.benchmark.num_sessions)); - } - } - } - if (batch > 0) { - insertBatch.executeBatch(); - } - LOG.debug("Loaded {} records into {}", total, catalog_tbl.getName()); - } - this.addToTableCount(catalog_tbl.getName(), total); + insertBatch.addBatch(); + total++; - // Load Observations - int total_observations = 0; - for (Pair p : observations) { - total_observations += loadObservations(conn, p.first, p.second); + if ((++batch % workConf.getBatchSize()) == 0) { + insertBatch.executeBatch(); + batch = 0; + insertBatch.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Sessions %d / %d", total, this.benchmark.num_sessions)); + } } - LOG.debug("Loaded {} records into {}", total_observations, OTMetricsConstants.TABLENAME_OBSERVATIONS); + } + if (batch > 0) { + insertBatch.executeBatch(); + } + LOG.debug("Loaded {} records into {}", total, catalog_tbl.getName()); } + this.addToTableCount(catalog_tbl.getName(), total); - private int loadObservations(Connection conn, int source_id, int session_id) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_OBSERVATIONS); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + // Load Observations + int total_observations = 0; + for (Pair p : observations) { + total_observations += loadObservations(conn, p.first, p.second); + } + LOG.debug( + "Loaded {} records into {}", total_observations, OTMetricsConstants.TABLENAME_OBSERVATIONS); + } - int total = 0; - int batch = 0; + private int loadObservations(Connection conn, int source_id, int session_id) throws SQLException { + Table catalog_tbl = + this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_OBSERVATIONS); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - // For each session_id / source_id, we will divide the # of observations that we - // insert into timeticks. Then for each timetick, we will insert NUM_TYPES observations - int timetick = 0; + int total = 0; + int batch = 0; - int type_category = (int)Math.floor(source_id / OTMetricsConstants.NUM_TYPES); + // For each session_id / source_id, we will divide the # of observations that we + // insert into timeticks. Then for each timetick, we will insert NUM_TYPES observations + int timetick = 0; - try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { - for (int i = 1; i <= OTMetricsConstants.NUM_OBSERVATIONS; i++) { - // SOURCE_ID - int offset = 1; + int type_category = (int) Math.floor(source_id / OTMetricsConstants.NUM_TYPES); - // SOURCE_ID - insertBatch.setInt(offset++, source_id); + try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { + for (int i = 1; i <= OTMetricsConstants.NUM_OBSERVATIONS; i++) { + // SOURCE_ID + int offset = 1; - // SESSION_ID - insertBatch.setInt(offset++, session_id); + // SOURCE_ID + insertBatch.setInt(offset++, source_id); - // TYPE_ID - int type_id = (i % OTMetricsConstants.NUM_TYPES); - insertBatch.setInt(offset++, type_id + type_category); + // SESSION_ID + insertBatch.setInt(offset++, session_id); - // VALUE - insertBatch.setFloat(offset++, rng().nextFloat()); + // TYPE_ID + int type_id = (i % OTMetricsConstants.NUM_TYPES); + insertBatch.setInt(offset++, type_id + type_category); - // CREATED_TIME - LocalDateTime created = OTMetricsUtil.getObservationDateTime(source_id, timetick); - insertBatch.setTimestamp(offset++, Timestamp.valueOf(created)); + // VALUE + insertBatch.setFloat(offset++, rng().nextFloat()); - insertBatch.addBatch(); - total++; + // CREATED_TIME + LocalDateTime created = OTMetricsUtil.getObservationDateTime(source_id, timetick); + insertBatch.setTimestamp(offset++, Timestamp.valueOf(created)); - if ((++batch % workConf.getBatchSize()) == 0) { - insertBatch.executeBatch(); - batch = 0; - insertBatch.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Observations %d / %d", total, this.benchmark.num_observations)); - } - } + insertBatch.addBatch(); + total++; - if (type_id == 0) { - timetick++; - } - } // FOR - if (batch > 0) { - insertBatch.executeBatch(); - } + if ((++batch % workConf.getBatchSize()) == 0) { + insertBatch.executeBatch(); + batch = 0; + insertBatch.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format("Observations %d / %d", total, this.benchmark.num_observations)); + } } - this.addToTableCount(catalog_tbl.getName(), total); - return (total); + + if (type_id == 0) { + timetick++; + } + } // FOR + if (batch > 0) { + insertBatch.executeBatch(); + } } + this.addToTableCount(catalog_tbl.getName(), total); + return (total); + } - private void loadSources(Connection conn) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_SOURCES); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + private void loadSources(Connection conn) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_SOURCES); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - int total = 0; - int batch = 0; - char[] baseStr = TextGenerator.randomChars(rng(), 100); + int total = 0; + int batch = 0; + char[] baseStr = TextGenerator.randomChars(rng(), 100); - try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { - for (int record = 0; record < this.benchmark.num_sources; record++) { - int offset = 1; + try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { + for (int record = 0; record < this.benchmark.num_sources; record++) { + int offset = 1; - // ID - insertBatch.setInt(offset++, record); + // ID + insertBatch.setInt(offset++, record); - // NAME - insertBatch.setString(offset++, String.format("source-%025d", record)); + // NAME + insertBatch.setString(offset++, String.format("source-%025d", record)); - // COMMENT - insertBatch.setString(offset++, String.valueOf(TextGenerator.permuteText(rng(), baseStr))); + // COMMENT + insertBatch.setString(offset++, String.valueOf(TextGenerator.permuteText(rng(), baseStr))); - // CREATED_TIME - insertBatch.setTimestamp(offset++, Timestamp.valueOf(OTMetricsUtil.getCreateDateTime(record))); + // CREATED_TIME + insertBatch.setTimestamp( + offset++, Timestamp.valueOf(OTMetricsUtil.getCreateDateTime(record))); - insertBatch.addBatch(); - total++; + insertBatch.addBatch(); + total++; - if ((++batch % workConf.getBatchSize()) == 0) { - insertBatch.executeBatch(); - batch = 0; - insertBatch.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Sources %d / %d", total, this.benchmark.num_sources)); - } - } - } - if (batch > 0) { - insertBatch.executeBatch(); - } + if ((++batch % workConf.getBatchSize()) == 0) { + insertBatch.executeBatch(); + batch = 0; + insertBatch.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Sources %d / %d", total, this.benchmark.num_sources)); + } } - this.addToTableCount(catalog_tbl.getName(), total); - LOG.info("Loaded {} records into {}", total, catalog_tbl.getName()); + } + if (batch > 0) { + insertBatch.executeBatch(); + } } + this.addToTableCount(catalog_tbl.getName(), total); + LOG.info("Loaded {} records into {}", total, catalog_tbl.getName()); + } - private void loadTypes(Connection conn) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_TYPES); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + private void loadTypes(Connection conn) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable(OTMetricsConstants.TABLENAME_TYPES); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - int total = 0; - int batch = 0; - char[] baseStr = TextGenerator.randomChars(rng(), 200); - ZipfianGenerator valueTypeZipf = new ZipfianGenerator(rng(), 8); + int total = 0; + int batch = 0; + char[] baseStr = TextGenerator.randomChars(rng(), 200); + ZipfianGenerator valueTypeZipf = new ZipfianGenerator(rng(), 8); - try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { - for (int record = 0; record < OTMetricsConstants.NUM_TYPES; record++) { - int offset = 1; + try (PreparedStatement insertBatch = conn.prepareStatement(sql)) { + for (int record = 0; record < OTMetricsConstants.NUM_TYPES; record++) { + int offset = 1; - // ID - insertBatch.setInt(offset++, record); + // ID + insertBatch.setInt(offset++, record); - // CATEGORY - insertBatch.setInt(offset++, (int)Math.floor(record / OTMetricsConstants.NUM_TYPES)); + // CATEGORY + insertBatch.setInt(offset++, (int) Math.floor(record / OTMetricsConstants.NUM_TYPES)); - // VALUE_TYPE - insertBatch.setInt(offset++, valueTypeZipf.nextInt(8)); + // VALUE_TYPE + insertBatch.setInt(offset++, valueTypeZipf.nextInt(8)); - // NAME - insertBatch.setString(offset++, String.format("type-%027d", record % OTMetricsConstants.NUM_TYPES)); + // NAME + insertBatch.setString( + offset++, String.format("type-%027d", record % OTMetricsConstants.NUM_TYPES)); - // COMMENT - insertBatch.setString(offset++, String.valueOf(TextGenerator.permuteText(rng(), baseStr))); + // COMMENT + insertBatch.setString(offset++, String.valueOf(TextGenerator.permuteText(rng(), baseStr))); - insertBatch.addBatch(); - total++; + insertBatch.addBatch(); + total++; - if ((++batch % workConf.getBatchSize()) == 0) { - insertBatch.executeBatch(); - batch = 0; - insertBatch.clearBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Types %d / %d", total, OTMetricsConstants.NUM_TYPES)); - } - } - } - if (batch > 0) { - insertBatch.executeBatch(); - } + if ((++batch % workConf.getBatchSize()) == 0) { + insertBatch.executeBatch(); + batch = 0; + insertBatch.clearBatch(); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Types %d / %d", total, OTMetricsConstants.NUM_TYPES)); + } } - this.addToTableCount(catalog_tbl.getName(), total); - LOG.info("Loaded {} records into {}", total, catalog_tbl.getName()); + } + if (batch > 0) { + insertBatch.executeBatch(); + } } + this.addToTableCount(catalog_tbl.getName(), total); + LOG.info("Loaded {} records into {}", total, catalog_tbl.getName()); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsUtil.java index 09e8c5c36..976432639 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsUtil.java @@ -21,28 +21,27 @@ public class OTMetricsUtil { - /** - * For a given source_id, return the starting timestamp for any - * session/observation in the database. - * @param source_id - * @return - */ - public static LocalDateTime getCreateDateTime(int source_id) { - return OTMetricsConstants.START_DATE.plusHours(source_id); - } - - /** - * For a given source_id and timetick within the session, return the timestamp - * for the observations - * @param source_id - * @param timetick - * @return - */ - public static LocalDateTime getObservationDateTime(int source_id, int timetick) { - LocalDateTime base = getCreateDateTime(source_id); - return base.plusMinutes(timetick * 20); - } - - - + /** + * For a given source_id, return the starting timestamp for any session/observation in the + * database. + * + * @param source_id + * @return + */ + public static LocalDateTime getCreateDateTime(int source_id) { + return OTMetricsConstants.START_DATE.plusHours(source_id); + } + + /** + * For a given source_id and timetick within the session, return the timestamp for the + * observations + * + * @param source_id + * @param timetick + * @return + */ + public static LocalDateTime getObservationDateTime(int source_id, int timetick) { + LocalDateTime base = getCreateDateTime(source_id); + return base.plusMinutes(timetick * 20); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsWorker.java index fe8936bc3..6d0f3fef6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/OTMetricsWorker.java @@ -22,60 +22,60 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.otmetrics.procedures.GetSessionRange; import com.oltpbenchmark.types.TransactionStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.Arrays; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * OtterTune Metrics Timeseries Benchmark + * * @author pavlo */ public final class OTMetricsWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(OTMetricsWorker.class); + private static final Logger LOG = LoggerFactory.getLogger(OTMetricsWorker.class); - public OTMetricsWorker(OTMetricsBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - } + public OTMetricsWorker(OTMetricsBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - if (nextTrans.getProcedureClass().equals(GetSessionRange.class)) { - execGetSessionRange(conn); - } - return (TransactionStatus.SUCCESS); + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + if (nextTrans.getProcedureClass().equals(GetSessionRange.class)) { + execGetSessionRange(conn); } + return (TransactionStatus.SUCCESS); + } - public void execGetSessionRange(Connection conn) throws SQLException { - int session_low = rng().nextInt(this.getBenchmark().num_sessions); - int session_high = session_low + rng().nextInt(5) * this.getBenchmark().num_sources; - int source_id = session_low % this.getBenchmark().num_sources; - - int type_category = (int)Math.floor(source_id / OTMetricsConstants.NUM_TYPES); - int type_id = (rng().nextInt(OTMetricsConstants.NUM_TYPES) % OTMetricsConstants.NUM_TYPES); - int num_types = rng().nextInt(3) + 1; - int types[] = new int[num_types]; - for (int i = 0; i < types.length; i++) { - types[i] = type_id + type_category + i; - }; + public void execGetSessionRange(Connection conn) throws SQLException { + int session_low = rng().nextInt(this.getBenchmark().num_sessions); + int session_high = session_low + rng().nextInt(5) * this.getBenchmark().num_sources; + int source_id = session_low % this.getBenchmark().num_sources; - GetSessionRange proc = this.getProcedure(GetSessionRange.class); - List result = proc.run(conn, source_id, session_low, session_high, types); - - if (LOG.isDebugEnabled()) { - StringBuilder sb = new StringBuilder(); - sb.append("source_id=").append(source_id).append(" "); - sb.append("session_low=").append(session_low).append(" "); - sb.append("session_high=").append(session_high).append(" "); - sb.append("type_id=").append(Arrays.toString(types)).append(" "); - sb.append(" -> ").append(result.size()).append(" results"); - LOG.debug(sb.toString()); - } + int type_category = (int) Math.floor(source_id / OTMetricsConstants.NUM_TYPES); + int type_id = (rng().nextInt(OTMetricsConstants.NUM_TYPES) % OTMetricsConstants.NUM_TYPES); + int num_types = rng().nextInt(3) + 1; + int types[] = new int[num_types]; + for (int i = 0; i < types.length; i++) { + types[i] = type_id + type_category + i; } + ; + GetSessionRange proc = this.getProcedure(GetSessionRange.class); + List result = proc.run(conn, source_id, session_low, session_high, types); + if (LOG.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("source_id=").append(source_id).append(" "); + sb.append("session_low=").append(session_low).append(" "); + sb.append("session_high=").append(session_high).append(" "); + sb.append("type_id=").append(Arrays.toString(types)).append(" "); + sb.append(" -> ").append(result.size()).append(" results"); + LOG.debug(sb.toString()); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/procedures/GetSessionRange.java b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/procedures/GetSessionRange.java index e79877ba2..a9cdd7c96 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/procedures/GetSessionRange.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/otmetrics/procedures/GetSessionRange.java @@ -19,60 +19,75 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.*; import java.util.ArrayList; import java.util.List; public class GetSessionRange extends Procedure { - /** - * We do it this way because not all JDBC drivers support using arrays to fill in var-length parameters - */ - private final String baseSQL = - "SELECT * FROM observations" + - " WHERE source_id = ?" + - " AND session_id >= ?" + - " AND session_id <= ?" + - " AND type_id IN (%s)" + - " ORDER BY created_time"; - public final SQLStmt RangeQuery1 = new SQLStmt(String.format(baseSQL, "?")); - public final SQLStmt RangeQuery2 = new SQLStmt(String.format(baseSQL, "?, ?")); - public final SQLStmt RangeQuery3 = new SQLStmt(String.format(baseSQL, "?, ?, ?")); + /** + * We do it this way because not all JDBC drivers support using arrays to fill in var-length + * parameters + */ + private final String baseSQL = + "SELECT * FROM observations" + + " WHERE source_id = ?" + + " AND session_id >= ?" + + " AND session_id <= ?" + + " AND type_id IN (%s)" + + " ORDER BY created_time"; - public List run(Connection conn, int source_id, int session_low, int session_high, int type_ids[]) throws SQLException { - final List finalResults = new ArrayList<>(); + public final SQLStmt RangeQuery1 = new SQLStmt(String.format(baseSQL, "?")); + public final SQLStmt RangeQuery2 = new SQLStmt(String.format(baseSQL, "?, ?")); + public final SQLStmt RangeQuery3 = new SQLStmt(String.format(baseSQL, "?, ?, ?")); - PreparedStatement stmt; - switch (type_ids.length) { - case 1: - stmt = this.getPreparedStatement(conn, RangeQuery1, source_id, session_low, session_high, type_ids[0]); - break; - case 2: - stmt = this.getPreparedStatement(conn, RangeQuery2, source_id, session_low, session_high, type_ids[0], type_ids[1]); - break; - case 3: - stmt = this.getPreparedStatement(conn, RangeQuery3, source_id, session_low, session_high, type_ids[0], type_ids[1], type_ids[2]); - break; - default: - throw new RuntimeException("Unexpected type_id array length of " + type_ids.length); - } // SWITCH - assert(stmt != null); + public List run( + Connection conn, int source_id, int session_low, int session_high, int type_ids[]) + throws SQLException { + final List finalResults = new ArrayList<>(); - // Bombs away! - try (ResultSet results = stmt.executeQuery()) { - while (results.next()) { - int cols = results.getMetaData().getColumnCount(); - Object[] arr = new Object[cols]; - for (int i = 0; i < cols; i++) { - arr[i] = results.getObject(i + 1).toString(); - } - finalResults.add(arr); - } - } - stmt.close(); + PreparedStatement stmt; + switch (type_ids.length) { + case 1: + stmt = + this.getPreparedStatement( + conn, RangeQuery1, source_id, session_low, session_high, type_ids[0]); + break; + case 2: + stmt = + this.getPreparedStatement( + conn, RangeQuery2, source_id, session_low, session_high, type_ids[0], type_ids[1]); + break; + case 3: + stmt = + this.getPreparedStatement( + conn, + RangeQuery3, + source_id, + session_low, + session_high, + type_ids[0], + type_ids[1], + type_ids[2]); + break; + default: + throw new RuntimeException("Unexpected type_id array length of " + type_ids.length); + } // SWITCH + assert (stmt != null); - return (finalResults); + // Bombs away! + try (ResultSet results = stmt.executeQuery()) { + while (results.next()) { + int cols = results.getMetaData().getColumnCount(); + Object[] arr = new Object[cols]; + for (int i = 0; i < cols; i++) { + arr[i] = results.getObject(i + 1).toString(); + } + finalResults.add(arr); + } } + stmt.close(); -} \ No newline at end of file + return (finalResults); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserBenchmark.java index 86c79308b..433ae2dc0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.resourcestresser; import com.oltpbenchmark.WorkloadConfiguration; @@ -23,39 +22,38 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.resourcestresser.procedures.CPU1; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class ResourceStresserBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(ResourceStresserBenchmark.class); - - public ResourceStresserBenchmark(WorkloadConfiguration workConf) { - super(workConf); + private static final Logger LOG = LoggerFactory.getLogger(ResourceStresserBenchmark.class); + + public ResourceStresserBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } + + @Override + protected Package getProcedurePackageImpl() { + return CPU1.class.getPackage(); + } + + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + int numKeys = (int) (workConf.getScaleFactor() * ResourceStresserConstants.RECORD_COUNT); + int keyRange = numKeys / workConf.getTerminals(); + LOG.warn("numkeys={}, keyRange={}", numKeys, keyRange); + for (int i = 0; i < workConf.getTerminals(); i++) { + workers.add(new ResourceStresserWorker(this, i, numKeys, keyRange)); } - @Override - protected Package getProcedurePackageImpl() { - return CPU1.class.getPackage(); - } + return workers; + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - int numKeys = (int) (workConf.getScaleFactor() * ResourceStresserConstants.RECORD_COUNT); - int keyRange = numKeys / workConf.getTerminals(); - LOG.warn("numkeys={}, keyRange={}", numKeys, keyRange); - for (int i = 0; i < workConf.getTerminals(); i++) { - workers.add(new ResourceStresserWorker(this, i, numKeys, keyRange)); - } - - return workers; - } - - @Override - protected Loader makeLoaderImpl() { - return new ResourceStresserLoader(this); - } + @Override + protected Loader makeLoaderImpl() { + return new ResourceStresserLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserConstants.java index a7826fb0c..34f6724b8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserConstants.java @@ -18,16 +18,15 @@ package com.oltpbenchmark.benchmarks.resourcestresser; public class ResourceStresserConstants { - public static final int RECORD_COUNT = 100; + public static final int RECORD_COUNT = 100; - public static final int STRING_LENGTH = 255; + public static final int STRING_LENGTH = 255; - public static final String TABLENAME_CPUTABLE = "cputable"; + public static final String TABLENAME_CPUTABLE = "cputable"; - public static final String TABLENAME_IOTABLE = "iotable"; + public static final String TABLENAME_IOTABLE = "iotable"; - public static final String TABLENAME_IOTABLESMALLROW = "iotablesmallrow"; - - public static final String TABLENAME_LOCKTABLE = "locktable"; + public static final String TABLENAME_IOTABLESMALLROW = "iotablesmallrow"; + public static final String TABLENAME_LOCKTABLE = "locktable"; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java index a39dc2f88..d13308f9a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserLoader.java @@ -22,7 +22,6 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -31,90 +30,94 @@ public final class ResourceStresserLoader extends Loader { - private final int numEmployees; + private final int numEmployees; - public ResourceStresserLoader(ResourceStresserBenchmark benchmark) { - super(benchmark); - this.numEmployees = (int) (this.scaleFactor * ResourceStresserConstants.RECORD_COUNT); - if (LOG.isDebugEnabled()) { - LOG.debug("# of EMPLOYEES: {}", this.numEmployees); - } + public ResourceStresserLoader(ResourceStresserBenchmark benchmark) { + super(benchmark); + this.numEmployees = (int) (this.scaleFactor * ResourceStresserConstants.RECORD_COUNT); + if (LOG.isDebugEnabled()) { + LOG.debug("# of EMPLOYEES: {}", this.numEmployees); } + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, ResourceStresserConstants.TABLENAME_CPUTABLE); - } + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, ResourceStresserConstants.TABLENAME_CPUTABLE); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, ResourceStresserConstants.TABLENAME_IOTABLE); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, ResourceStresserConstants.TABLENAME_IOTABLE); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, ResourceStresserConstants.TABLENAME_IOTABLESMALLROW); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, ResourceStresserConstants.TABLENAME_IOTABLESMALLROW); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, ResourceStresserConstants.TABLENAME_LOCKTABLE); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, ResourceStresserConstants.TABLENAME_LOCKTABLE); + } }); - return (threads); - } - - private void loadTable(Connection conn, String tableName) throws SQLException { - Table catalog_tbl = this.benchmark.getCatalog().getTable(tableName); + return (threads); + } + private void loadTable(Connection conn, String tableName) throws SQLException { + Table catalog_tbl = this.benchmark.getCatalog().getTable(tableName); - if (LOG.isDebugEnabled()) { - LOG.debug("Start loading {}", tableName); + if (LOG.isDebugEnabled()) { + LOG.debug("Start loading {}", tableName); + } + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int batch = 0; + int i; + for (i = 0; i < this.numEmployees; ++i) { + stmt.setInt(1, i); + if (tableName.equals(ResourceStresserConstants.TABLENAME_CPUTABLE)) { + stmt.setString( + 2, TextGenerator.randomStr(rng(), ResourceStresserConstants.STRING_LENGTH)); + } else if (tableName.equals(ResourceStresserConstants.TABLENAME_IOTABLE)) { + for (int j = 2; j <= catalog_tbl.getColumnCount(); ++j) { + stmt.setString( + j, TextGenerator.randomStr(rng(), ResourceStresserConstants.STRING_LENGTH)); + } + } else { + stmt.setInt(2, rng().nextInt()); } - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - int batch = 0; - int i; - for (i = 0; i < this.numEmployees; ++i) { - stmt.setInt(1, i); - if (tableName.equals(ResourceStresserConstants.TABLENAME_CPUTABLE)) { - stmt.setString(2, TextGenerator.randomStr(rng(), ResourceStresserConstants.STRING_LENGTH)); - } else if (tableName.equals(ResourceStresserConstants.TABLENAME_IOTABLE)) { - for (int j = 2; j <= catalog_tbl.getColumnCount(); ++j) { - stmt.setString(j, TextGenerator.randomStr(rng(), ResourceStresserConstants.STRING_LENGTH)); - } - } else { - stmt.setInt(2, rng().nextInt()); - } - stmt.addBatch(); - if (++batch >= workConf.getBatchSize()) { - int[] result = stmt.executeBatch(); - assert result != null; + stmt.addBatch(); + if (++batch >= workConf.getBatchSize()) { + int[] result = stmt.executeBatch(); + assert result != null; - batch = 0; - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Records Loaded %d / %d", i + 1, this.numEmployees)); - } - } - } - if (batch > 0) { - stmt.executeBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Records Loaded %d / %d", i, this.numEmployees)); - } - } + batch = 0; + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Records Loaded %d / %d", i + 1, this.numEmployees)); + } } + } + if (batch > 0) { + stmt.executeBatch(); if (LOG.isDebugEnabled()) { - LOG.debug("Finished loading {}", tableName); + LOG.debug(String.format("Records Loaded %d / %d", i, this.numEmployees)); } + } } - + if (LOG.isDebugEnabled()) { + LOG.debug("Finished loading {}", tableName); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserWorker.java index dffed7b8a..349810960 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/ResourceStresserWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.resourcestresser; import com.oltpbenchmark.api.Procedure.UserAbortException; @@ -23,97 +22,129 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.resourcestresser.procedures.*; import com.oltpbenchmark.types.TransactionStatus; - import java.sql.Connection; import java.sql.SQLException; import java.util.Random; public final class ResourceStresserWorker extends Worker { - public static final int CONTENTION1_howManyKeys = 10; - public static final int CONTENTION1_howManyUpdates = 20; - public static final int CONTENTION1_sleepLength = 1; - - public static final int CONTENTION2_howManyKeys = 10; - public static final int CONTENTION2_howManyUpdates = 5; - public static final int CONTENTION2_sleepLength = 2; - - public static final int IO1_howManyColsPerRow = 16; - public static final int IO1_howManyRowsPerUpdate = 10; - public static final int IO1_howManyUpdatePerTransaction = 10; - - public static final int IO2_howManyUpdatePerTransaction = 50; - public static final boolean IO2_makeSureWorketSetFitsInMemory = true; - - public static final int CPU1_howManyPerTrasaction = 10; - public static final int CPU1_sleep = 1; - public static final int CPU1_nestedLevel = 5; - - public static final int CPU2_howManyPerTrasaction = 5; - public static final int CPU2_sleep = 2; - public static final int CPU2_nestedLevel = 5; - - public static final Random gen = new Random(1); // I change the random seed every time! - - private final int keyRange; - private final int numKeys; - - public ResourceStresserWorker(ResourceStresserBenchmark benchmarkModule, int id, int numKeys, int keyRange) { - super(benchmarkModule, id); - this.numKeys = numKeys; - this.keyRange = keyRange; - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - if (nextTrans.getProcedureClass().equals(CPU1.class)) { - cpu1Transaction(conn, CPU1_howManyPerTrasaction, CPU1_sleep, CPU1_nestedLevel); - } else if (nextTrans.getProcedureClass().equals(CPU2.class)) { - cpu2Transaction(conn, CPU2_howManyPerTrasaction, CPU2_sleep, CPU2_nestedLevel); - } else if (nextTrans.getProcedureClass().equals(IO1.class)) { - io1Transaction(conn, IO1_howManyColsPerRow, IO1_howManyRowsPerUpdate, IO1_howManyUpdatePerTransaction, keyRange); - } else if (nextTrans.getProcedureClass().equals(IO2.class)) { - io2Transaction(conn, IO2_howManyUpdatePerTransaction, IO2_makeSureWorketSetFitsInMemory, keyRange); - } else if (nextTrans.getProcedureClass().equals(Contention1.class)) { - contention1Transaction(conn, CONTENTION1_howManyUpdates, CONTENTION1_sleepLength); - } else if (nextTrans.getProcedureClass().equals(Contention2.class)) { - contention2Transaction(conn, CONTENTION2_howManyKeys, CONTENTION2_howManyUpdates, CONTENTION2_sleepLength); - } - return (TransactionStatus.SUCCESS); - } - - private void contention1Transaction(Connection conn, int howManyUpdates, int sleepLength) throws SQLException { - Contention1 proc = this.getProcedure(Contention1.class); - - proc.run(conn, howManyUpdates, sleepLength, this.numKeys); - } - - private void contention2Transaction(Connection conn, int howManyKeys, int howManyUpdates, int sleepLength) throws SQLException { - Contention2 proc = this.getProcedure(Contention2.class); - - proc.run(conn, howManyKeys, howManyUpdates, sleepLength, this.numKeys); - } - - private void io1Transaction(Connection conn, int howManyColsPerRow, int howManyUpdatesPerTransaction, int howManyRowsPerUpdate, int keyRange) throws SQLException { - IO1 proc = this.getProcedure(IO1.class); - - proc.run(conn, this.getId(), howManyColsPerRow, howManyUpdatesPerTransaction, howManyRowsPerUpdate, keyRange); - } - - private void io2Transaction(Connection conn, int howManyUpdatesPerTransaction, boolean makeSureWorkerSetFitsInMemory, int keyRange) throws SQLException { - IO2 proc = this.getProcedure(IO2.class); - - proc.run(conn, this.getId(), howManyUpdatesPerTransaction, makeSureWorkerSetFitsInMemory, keyRange); - } - - private void cpu1Transaction(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) throws SQLException { - CPU1 proc = this.getProcedure(CPU1.class); - - proc.run(conn, howManyPerTransaction, sleepLength, nestedLevel); - } - - private void cpu2Transaction(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) throws SQLException { - CPU2 proc = this.getProcedure(CPU2.class); - - proc.run(conn, howManyPerTransaction, sleepLength, nestedLevel); + public static final int CONTENTION1_howManyKeys = 10; + public static final int CONTENTION1_howManyUpdates = 20; + public static final int CONTENTION1_sleepLength = 1; + + public static final int CONTENTION2_howManyKeys = 10; + public static final int CONTENTION2_howManyUpdates = 5; + public static final int CONTENTION2_sleepLength = 2; + + public static final int IO1_howManyColsPerRow = 16; + public static final int IO1_howManyRowsPerUpdate = 10; + public static final int IO1_howManyUpdatePerTransaction = 10; + + public static final int IO2_howManyUpdatePerTransaction = 50; + public static final boolean IO2_makeSureWorketSetFitsInMemory = true; + + public static final int CPU1_howManyPerTrasaction = 10; + public static final int CPU1_sleep = 1; + public static final int CPU1_nestedLevel = 5; + + public static final int CPU2_howManyPerTrasaction = 5; + public static final int CPU2_sleep = 2; + public static final int CPU2_nestedLevel = 5; + + public static final Random gen = new Random(1); // I change the random seed every time! + + private final int keyRange; + private final int numKeys; + + public ResourceStresserWorker( + ResourceStresserBenchmark benchmarkModule, int id, int numKeys, int keyRange) { + super(benchmarkModule, id); + this.numKeys = numKeys; + this.keyRange = keyRange; + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + if (nextTrans.getProcedureClass().equals(CPU1.class)) { + cpu1Transaction(conn, CPU1_howManyPerTrasaction, CPU1_sleep, CPU1_nestedLevel); + } else if (nextTrans.getProcedureClass().equals(CPU2.class)) { + cpu2Transaction(conn, CPU2_howManyPerTrasaction, CPU2_sleep, CPU2_nestedLevel); + } else if (nextTrans.getProcedureClass().equals(IO1.class)) { + io1Transaction( + conn, + IO1_howManyColsPerRow, + IO1_howManyRowsPerUpdate, + IO1_howManyUpdatePerTransaction, + keyRange); + } else if (nextTrans.getProcedureClass().equals(IO2.class)) { + io2Transaction( + conn, IO2_howManyUpdatePerTransaction, IO2_makeSureWorketSetFitsInMemory, keyRange); + } else if (nextTrans.getProcedureClass().equals(Contention1.class)) { + contention1Transaction(conn, CONTENTION1_howManyUpdates, CONTENTION1_sleepLength); + } else if (nextTrans.getProcedureClass().equals(Contention2.class)) { + contention2Transaction( + conn, CONTENTION2_howManyKeys, CONTENTION2_howManyUpdates, CONTENTION2_sleepLength); } + return (TransactionStatus.SUCCESS); + } + + private void contention1Transaction(Connection conn, int howManyUpdates, int sleepLength) + throws SQLException { + Contention1 proc = this.getProcedure(Contention1.class); + + proc.run(conn, howManyUpdates, sleepLength, this.numKeys); + } + + private void contention2Transaction( + Connection conn, int howManyKeys, int howManyUpdates, int sleepLength) throws SQLException { + Contention2 proc = this.getProcedure(Contention2.class); + + proc.run(conn, howManyKeys, howManyUpdates, sleepLength, this.numKeys); + } + + private void io1Transaction( + Connection conn, + int howManyColsPerRow, + int howManyUpdatesPerTransaction, + int howManyRowsPerUpdate, + int keyRange) + throws SQLException { + IO1 proc = this.getProcedure(IO1.class); + + proc.run( + conn, + this.getId(), + howManyColsPerRow, + howManyUpdatesPerTransaction, + howManyRowsPerUpdate, + keyRange); + } + + private void io2Transaction( + Connection conn, + int howManyUpdatesPerTransaction, + boolean makeSureWorkerSetFitsInMemory, + int keyRange) + throws SQLException { + IO2 proc = this.getProcedure(IO2.class); + + proc.run( + conn, this.getId(), howManyUpdatesPerTransaction, makeSureWorkerSetFitsInMemory, keyRange); + } + + private void cpu1Transaction( + Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) + throws SQLException { + CPU1 proc = this.getProcedure(CPU1.class); + + proc.run(conn, howManyPerTransaction, sleepLength, nestedLevel); + } + + private void cpu2Transaction( + Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) + throws SQLException { + CPU2 proc = this.getProcedure(CPU2.class); + + proc.run(conn, howManyPerTransaction, sleepLength, nestedLevel); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java index 2df497786..11ac494f4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU1.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,39 +28,44 @@ public class CPU1 extends Procedure { - public final SQLStmt cpuSelect; + public final SQLStmt cpuSelect; - { - String complexClause = "'passwd'"; - for (int i = 1; i <= ResourceStresserWorker.CPU1_nestedLevel; ++i) { - complexClause = "md5(concat(" + complexClause + ",?))"; - } - cpuSelect = new SQLStmt("SELECT count(*) FROM (SELECT " + complexClause + " FROM " + ResourceStresserConstants.TABLENAME_CPUTABLE + " WHERE empid >= 0 AND empid < 100) T1"); + { + String complexClause = "'passwd'"; + for (int i = 1; i <= ResourceStresserWorker.CPU1_nestedLevel; ++i) { + complexClause = "md5(concat(" + complexClause + ",?))"; } + cpuSelect = + new SQLStmt( + "SELECT count(*) FROM (SELECT " + + complexClause + + " FROM " + + ResourceStresserConstants.TABLENAME_CPUTABLE + + " WHERE empid >= 0 AND empid < 100) T1"); + } - public void run(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) throws SQLException { - + public void run(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) + throws SQLException { - for (int tranIdx = 0; tranIdx < howManyPerTransaction; ++tranIdx) { - double randNoise = ResourceStresserWorker.gen.nextDouble(); + for (int tranIdx = 0; tranIdx < howManyPerTransaction; ++tranIdx) { + double randNoise = ResourceStresserWorker.gen.nextDouble(); - try (PreparedStatement stmt = this.getPreparedStatement(conn, cpuSelect)) { + try (PreparedStatement stmt = this.getPreparedStatement(conn, cpuSelect)) { - for (int i = 1; i <= nestedLevel; ++i) { - stmt.setString(i, Double.toString(randNoise)); - } + for (int i = 1; i <= nestedLevel; ++i) { + stmt.setString(i, Double.toString(randNoise)); + } - // TODO: Is this the right place to sleep? With rs open??? - try (ResultSet rs = stmt.executeQuery()) { - assert rs != null; - try { - Thread.sleep(sleepLength); - } catch (InterruptedException e) { - throw new SQLException("Unexpected interupt while sleeping!"); - } - } - } + // TODO: Is this the right place to sleep? With rs open??? + try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; + try { + Thread.sleep(sleepLength); + } catch (InterruptedException e) { + throw new SQLException("Unexpected interupt while sleeping!"); + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java index 194bb6279..443014a0d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/CPU2.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,38 +28,43 @@ public class CPU2 extends Procedure { - public final SQLStmt cpuSelect; + public final SQLStmt cpuSelect; - { - String complexClause = "passwd"; - for (int i = 1; i <= ResourceStresserWorker.CPU2_nestedLevel; ++i) { - complexClause = "md5(concat(" + complexClause + ",?))"; - } - cpuSelect = new SQLStmt("SELECT count(*) FROM (SELECT " + complexClause + " FROM " + ResourceStresserConstants.TABLENAME_CPUTABLE + " WHERE empid >= 0 AND empid < 100) T2"); + { + String complexClause = "passwd"; + for (int i = 1; i <= ResourceStresserWorker.CPU2_nestedLevel; ++i) { + complexClause = "md5(concat(" + complexClause + ",?))"; } + cpuSelect = + new SQLStmt( + "SELECT count(*) FROM (SELECT " + + complexClause + + " FROM " + + ResourceStresserConstants.TABLENAME_CPUTABLE + + " WHERE empid >= 0 AND empid < 100) T2"); + } - public void run(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) throws SQLException { - + public void run(Connection conn, int howManyPerTransaction, int sleepLength, int nestedLevel) + throws SQLException { - for (int tranIdx = 0; tranIdx < howManyPerTransaction; ++tranIdx) { - double randNoise = ResourceStresserWorker.gen.nextDouble(); + for (int tranIdx = 0; tranIdx < howManyPerTransaction; ++tranIdx) { + double randNoise = ResourceStresserWorker.gen.nextDouble(); - try (PreparedStatement stmt = this.getPreparedStatement(conn, cpuSelect)) { - for (int i = 1; i <= nestedLevel; ++i) { - stmt.setString(i, Double.toString(randNoise)); - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, cpuSelect)) { + for (int i = 1; i <= nestedLevel; ++i) { + stmt.setString(i, Double.toString(randNoise)); + } - // TODO: Is this the right place to sleep? With rs open??? - try (ResultSet rs = stmt.executeQuery()) { - assert rs != null; - try { - Thread.sleep(sleepLength); - } catch (InterruptedException e) { - throw new SQLException("Unexpected interupt while sleeping!"); - } - } - } + // TODO: Is this the right place to sleep? With rs open??? + try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; + try { + Thread.sleep(sleepLength); + } catch (InterruptedException e) { + throw new SQLException("Unexpected interupt while sleeping!"); + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention1.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention1.java index 90524b925..d824154b2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention1.java @@ -21,52 +21,55 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Uses random keys and OR on primary key - * WARNING: The reason why I removed howManyKeys from the parameter list is that users might call this function with different arguments and thus, we would need - * to recreate the PreparedStatement every time, which is undesired because of its memory leak. + * Uses random keys and OR on primary key WARNING: The reason why I removed howManyKeys from the + * parameter list is that users might call this function with different arguments and thus, we would + * need to recreate the PreparedStatement every time, which is undesired because of its memory leak. * The best solution is perhaps to */ public class Contention1 extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(Contention1.class); + private static final Logger LOG = LoggerFactory.getLogger(Contention1.class); - public final SQLStmt lockUpdate = new SQLStmt("UPDATE " + ResourceStresserConstants.TABLENAME_LOCKTABLE + " locktable SET salary = ? WHERE empid IN (??)", ResourceStresserWorker.CONTENTION1_howManyKeys); + public final SQLStmt lockUpdate = + new SQLStmt( + "UPDATE " + + ResourceStresserConstants.TABLENAME_LOCKTABLE + + " locktable SET salary = ? WHERE empid IN (??)", + ResourceStresserWorker.CONTENTION1_howManyKeys); - public final SQLStmt lockSleep = new SQLStmt("SELECT SLEEP(?)"); + public final SQLStmt lockSleep = new SQLStmt("SELECT SLEEP(?)"); - public void run(Connection conn, int howManyUpdates, int sleepLength, int numKeys) throws SQLException { - int howManyKeys = ResourceStresserWorker.CONTENTION1_howManyKeys; + public void run(Connection conn, int howManyUpdates, int sleepLength, int numKeys) + throws SQLException { + int howManyKeys = ResourceStresserWorker.CONTENTION1_howManyKeys; - for (int sel = 0; sel < howManyUpdates; ++sel) { + for (int sel = 0; sel < howManyUpdates; ++sel) { - try (PreparedStatement stmtUpdate = this.getPreparedStatement(conn, lockUpdate)) { - int nextKey = -1; - for (int key = 1; key <= howManyKeys; ++key) { - nextKey = ResourceStresserWorker.gen.nextInt(numKeys); - stmtUpdate.setInt(key + 1, nextKey); - } - // setting the parameter that corresponds to the salary in - // the SET clause - stmtUpdate.setInt(1, ResourceStresserWorker.gen.nextInt()); - int result = stmtUpdate.executeUpdate(); - if (result != howManyKeys) { - LOG.warn("LOCK1UPDATE: supposedtochange={} but only changed {}", howManyKeys, result); - } - } - - try (PreparedStatement stmtSleep = this.getPreparedStatement(conn, lockSleep)) { - stmtSleep.setInt(1, sleepLength); - stmtSleep.execute(); - } + try (PreparedStatement stmtUpdate = this.getPreparedStatement(conn, lockUpdate)) { + int nextKey = -1; + for (int key = 1; key <= howManyKeys; ++key) { + nextKey = ResourceStresserWorker.gen.nextInt(numKeys); + stmtUpdate.setInt(key + 1, nextKey); + } + // setting the parameter that corresponds to the salary in + // the SET clause + stmtUpdate.setInt(1, ResourceStresserWorker.gen.nextInt()); + int result = stmtUpdate.executeUpdate(); + if (result != howManyKeys) { + LOG.warn("LOCK1UPDATE: supposedtochange={} but only changed {}", howManyKeys, result); } + } + + try (PreparedStatement stmtSleep = this.getPreparedStatement(conn, lockSleep)) { + stmtSleep.setInt(1, sleepLength); + stmtSleep.execute(); + } } + } } - - diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention2.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention2.java index 070f833d3..137f682b1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/Contention2.java @@ -21,47 +21,47 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** - * Uses a range of primary keys. - */ +/** Uses a range of primary keys. */ public class Contention2 extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(Contention2.class); + private static final Logger LOG = LoggerFactory.getLogger(Contention2.class); - public final SQLStmt lockUpdate = new SQLStmt("UPDATE " + ResourceStresserConstants.TABLENAME_LOCKTABLE + " SET salary = ? WHERE empid >= ? AND empid < ?"); + public final SQLStmt lockUpdate = + new SQLStmt( + "UPDATE " + + ResourceStresserConstants.TABLENAME_LOCKTABLE + + " SET salary = ? WHERE empid >= ? AND empid < ?"); - public final SQLStmt lockSleep = new SQLStmt("SELECT SLEEP(?)"); + public final SQLStmt lockSleep = new SQLStmt("SELECT SLEEP(?)"); - public void run(Connection conn, int howManyKeys, int howManyUpdates, int sleepLength, int numKeys) throws SQLException { + public void run( + Connection conn, int howManyKeys, int howManyUpdates, int sleepLength, int numKeys) + throws SQLException { + for (int sel = 0; sel < howManyUpdates; ++sel) { + int leftKey = ResourceStresserWorker.gen.nextInt(Math.max(1, numKeys - howManyKeys)); + int rightKey = leftKey + howManyKeys; + int salary = ResourceStresserWorker.gen.nextInt(); - for (int sel = 0; sel < howManyUpdates; ++sel) { - int leftKey = ResourceStresserWorker.gen.nextInt(Math.max(1, numKeys - howManyKeys)); - int rightKey = leftKey + howManyKeys; - int salary = ResourceStresserWorker.gen.nextInt(); - - try (PreparedStatement stmtUpdate = this.getPreparedStatement(conn, lockUpdate)) { - stmtUpdate.setInt(1, salary); - stmtUpdate.setInt(2, leftKey + 1); - stmtUpdate.setInt(3, rightKey + 1); - int result = stmtUpdate.executeUpdate(); - if (result != howManyKeys) { - LOG.warn("LOCK1UPDATE: supposedtochange={} but only changed {}", howManyKeys, result); - } - } - - try (PreparedStatement stmtSleep = this.getPreparedStatement(conn, lockSleep)) { - stmtSleep.setInt(1, sleepLength); - stmtSleep.execute(); - } + try (PreparedStatement stmtUpdate = this.getPreparedStatement(conn, lockUpdate)) { + stmtUpdate.setInt(1, salary); + stmtUpdate.setInt(2, leftKey + 1); + stmtUpdate.setInt(3, rightKey + 1); + int result = stmtUpdate.executeUpdate(); + if (result != howManyKeys) { + LOG.warn("LOCK1UPDATE: supposedtochange={} but only changed {}", howManyKeys, result); } - } - + } + try (PreparedStatement stmtSleep = this.getPreparedStatement(conn, lockSleep)) { + stmtSleep.setInt(1, sleepLength); + stmtSleep.execute(); + } + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO1.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO1.java index cb35a8002..bc3e25556 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO1.java @@ -21,50 +21,61 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class IO1 extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(IO1.class); + private static final Logger LOG = LoggerFactory.getLogger(IO1.class); - public final SQLStmt ioUpdate; + public final SQLStmt ioUpdate; - { - String sql = "UPDATE " + ResourceStresserConstants.TABLENAME_IOTABLE + " SET %s WHERE empid >= ? AND empid < ?"; - String setClause = ""; - for (int col = 1; col <= ResourceStresserWorker.IO1_howManyColsPerRow; ++col) { - setClause = setClause + (col > 1 ? "," : "") + " data" + col + "=?"; - } - this.ioUpdate = new SQLStmt(String.format(sql, setClause)); + { + String sql = + "UPDATE " + + ResourceStresserConstants.TABLENAME_IOTABLE + + " SET %s WHERE empid >= ? AND empid < ?"; + String setClause = ""; + for (int col = 1; col <= ResourceStresserWorker.IO1_howManyColsPerRow; ++col) { + setClause = setClause + (col > 1 ? "," : "") + " data" + col + "=?"; } + this.ioUpdate = new SQLStmt(String.format(sql, setClause)); + } - public void run(Connection conn, int myId, int howManyColsPerRow, int howManyUpdatesPerTransaction, int howManyRowsPerUpdate, int keyRange) throws SQLException { + public void run( + Connection conn, + int myId, + int howManyColsPerRow, + int howManyUpdatesPerTransaction, + int howManyRowsPerUpdate, + int keyRange) + throws SQLException { + // int keyRange = 20; //1024000 / 200; // FIXME + int startingKey = myId * keyRange; - //int keyRange = 20; //1024000 / 200; // FIXME - int startingKey = myId * keyRange; + for (int up = 0; up < howManyUpdatesPerTransaction; ++up) { + int leftKey = + ResourceStresserWorker.gen.nextInt(Math.max(1, keyRange - howManyRowsPerUpdate)) + + startingKey; + int rightKey = leftKey + howManyRowsPerUpdate; - for (int up = 0; up < howManyUpdatesPerTransaction; ++up) { - int leftKey = ResourceStresserWorker.gen.nextInt(Math.max(1, keyRange - howManyRowsPerUpdate)) + startingKey; - int rightKey = leftKey + howManyRowsPerUpdate; + try (PreparedStatement stmt = this.getPreparedStatement(conn, ioUpdate)) { - try (PreparedStatement stmt = this.getPreparedStatement(conn, ioUpdate)) { - - for (int col = 1; col <= howManyColsPerRow; ++col) { - double value = ResourceStresserWorker.gen.nextDouble() + ResourceStresserWorker.gen.nextDouble(); - stmt.setString(col, Double.toString(value)); - } - stmt.setInt(howManyColsPerRow + 1, leftKey); - stmt.setInt(howManyColsPerRow + 2, rightKey); - int result = stmt.executeUpdate(); - if (result != howManyRowsPerUpdate) { - LOG.warn("supposedtochange={} but result={}", howManyRowsPerUpdate, result); - } - } + for (int col = 1; col <= howManyColsPerRow; ++col) { + double value = + ResourceStresserWorker.gen.nextDouble() + ResourceStresserWorker.gen.nextDouble(); + stmt.setString(col, Double.toString(value)); + } + stmt.setInt(howManyColsPerRow + 1, leftKey); + stmt.setInt(howManyColsPerRow + 2, rightKey); + int result = stmt.executeUpdate(); + if (result != howManyRowsPerUpdate) { + LOG.warn("supposedtochange={} but result={}", howManyRowsPerUpdate, result); } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java index ef9dae039..0a36a2958 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/resourcestresser/procedures/IO2.java @@ -21,43 +21,49 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserConstants; import com.oltpbenchmark.benchmarks.resourcestresser.ResourceStresserWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * io2Transaction deals with a table that has much smaller rows. - * It runs a given number of updates, where each update only - * changes one row. + * io2Transaction deals with a table that has much smaller rows. It runs a given number of updates, + * where each update only changes one row. */ public class IO2 extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(IO2.class); - - public final SQLStmt ioUpdate = new SQLStmt("UPDATE " + ResourceStresserConstants.TABLENAME_IOTABLESMALLROW + " SET flag1 = ? WHERE empid = ?"); - - public void run(Connection conn, int myId, int howManyUpdatesPerTransaction, boolean makeSureWorkerSetFitsInMemory, int keyRange) throws SQLException { + private static final Logger LOG = LoggerFactory.getLogger(IO2.class); + public final SQLStmt ioUpdate = + new SQLStmt( + "UPDATE " + + ResourceStresserConstants.TABLENAME_IOTABLESMALLROW + + " SET flag1 = ? WHERE empid = ?"); - //int keyRange = (makeSureWorkerSetFitsInMemory ? 16777216 / 160 : 167772160 / 160); // FIXME - int startingKey = myId * keyRange; - //int lastKey = (myId + 1) * keyRange - 1; + public void run( + Connection conn, + int myId, + int howManyUpdatesPerTransaction, + boolean makeSureWorkerSetFitsInMemory, + int keyRange) + throws SQLException { - for (int up = 0; up < howManyUpdatesPerTransaction; ++up) { - int key = ResourceStresserWorker.gen.nextInt(keyRange) + startingKey; - int value = ResourceStresserWorker.gen.nextInt(); - try (PreparedStatement stmt = this.getPreparedStatement(conn, ioUpdate)) { - stmt.setInt(1, value); - stmt.setInt(2, key); + // int keyRange = (makeSureWorkerSetFitsInMemory ? 16777216 / 160 : 167772160 / 160); // FIXME + int startingKey = myId * keyRange; + // int lastKey = (myId + 1) * keyRange - 1; - int result = stmt.executeUpdate(); - if (result != 1) { - LOG.warn("supposedtochange=" + 1 + " but rc={}", result); - } + for (int up = 0; up < howManyUpdatesPerTransaction; ++up) { + int key = ResourceStresserWorker.gen.nextInt(keyRange) + startingKey; + int value = ResourceStresserWorker.gen.nextInt(); + try (PreparedStatement stmt = this.getPreparedStatement(conn, ioUpdate)) { + stmt.setInt(1, value); + stmt.setInt(2, key); - } + int result = stmt.executeUpdate(); + if (result != 1) { + LOG.warn("supposedtochange=" + 1 + " but rc={}", result); } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSBenchmark.java index 35a032e5a..cee47099d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSBenchmark.java @@ -24,56 +24,55 @@ import com.oltpbenchmark.benchmarks.seats.procedures.LoadConfig; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.RandomGenerator; - import java.io.File; import java.util.ArrayList; import java.util.List; public final class SEATSBenchmark extends BenchmarkModule { - private final RandomGenerator rng = new RandomGenerator((int) System.currentTimeMillis()); + private final RandomGenerator rng = new RandomGenerator((int) System.currentTimeMillis()); - public SEATSBenchmark(WorkloadConfiguration workConf) { - super(workConf); - this.registerSupplementalProcedure(LoadConfig.class); - } + public SEATSBenchmark(WorkloadConfiguration workConf) { + super(workConf); + this.registerSupplementalProcedure(LoadConfig.class); + } - public String getDataDir() { - return "/benchmarks/" + getBenchmarkName(); - } + public String getDataDir() { + return "/benchmarks/" + getBenchmarkName(); + } - public RandomGenerator getRandomGenerator() { - return (this.rng); - } + public RandomGenerator getRandomGenerator() { + return (this.rng); + } - @Override - protected Package getProcedurePackageImpl() { - return (LoadConfig.class.getPackage()); - } + @Override + protected Package getProcedurePackageImpl() { + return (LoadConfig.class.getPackage()); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < this.workConf.getTerminals(); ++i) { - workers.add(new SEATSWorker(this, i)); - } - return (workers); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < this.workConf.getTerminals(); ++i) { + workers.add(new SEATSWorker(this, i)); } + return (workers); + } - @Override - protected Loader makeLoaderImpl() { - return new SEATSLoader(this); - } + @Override + protected Loader makeLoaderImpl() { + return new SEATSLoader(this); + } - /** - * Return the path of the CSV file that has data for the given Table catalog - * handle - * - * @param data_dir - * @param catalog_tbl - * @return - */ - public static String getTableDataFilePath(String data_dir, Table catalog_tbl) { - return String.format("%s%stable.%s.csv", data_dir, File.separator, catalog_tbl.getName().toLowerCase()); - } + /** + * Return the path of the CSV file that has data for the given Table catalog handle + * + * @param data_dir + * @param catalog_tbl + * @return + */ + public static String getTableDataFilePath(String data_dir, Table catalog_tbl) { + return String.format( + "%s%stable.%s.csv", data_dir, File.separator, catalog_tbl.getName().toLowerCase()); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSConstants.java index 773dc490d..68de2e9c8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSConstants.java @@ -15,275 +15,226 @@ * */ - package com.oltpbenchmark.benchmarks.seats; import java.util.regex.Pattern; public abstract class SEATSConstants { - // ---------------------------------------------------------------- - // STORED PROCEDURE EXECUTION FREQUENCIES (0% - 100%) - // ---------------------------------------------------------------- - - public static final int FREQUENCY_DELETE_RESERVATION = 10; - public static final int FREQUENCY_FIND_FLIGHTS = 10; - public static final int FREQUENCY_FIND_OPEN_SEATS = 35; - public static final int FREQUENCY_NEW_RESERVATION = 20; - public static final int FREQUENCY_UPDATE_CUSTOMER = 10; - public static final int FREQUENCY_UPDATE_RESERVATION = 15; - - // ---------------------------------------------------------------- - // FLIGHT CONSTANTS - // ---------------------------------------------------------------- - - /** - * The different distances that we can look-up for nearby airports - * This is similar to the customer selecting a dropdown when looking for flights - */ - // public static final int DISTANCES[] = { 5 }; // , 10, 25, 50, 100 }; - - // Zhenwu made the changes. The original code is above - public static final int[] DISTANCES = {5, 10, 25, 50, 100}; - - /** - * The number of days in the past and future that we will generate flight information for - */ - public static final int FLIGHTS_DAYS_PAST = 1; - public static final int FLIGHTS_DAYS_FUTURE = 50; - - /** - * Average # of flights per day - * NUM_FLIGHTS_PER_DAY = 15000 - * Source: http://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=236&DB_Short_Name=On-Time - */ - public static final int FLIGHTS_PER_DAY_MIN = 1125; - public static final int FLIGHTS_PER_DAY_MAX = 1875; - - /** - * Number of seats available per flight - * If you change this then you must also change FindOpenSeats - */ - public static final int FLIGHTS_NUM_SEATS = 150; - - /** - * How many First Class seats are on a given flight - * These reservations are more expensive - */ - public static final int FLIGHTS_FIRST_CLASS_OFFSET = 10; - - /** - * The rate in which a flight can travel between two airports (miles per hour) - */ - public static final double FLIGHT_TRAVEL_RATE = 570.0; // Boeing 747 - - // ---------------------------------------------------------------- - // CUSTOMER CONSTANTS - // ---------------------------------------------------------------- - - /** - * Default number of customers in the database - */ - public static final int CUSTOMERS_COUNT = 100000; - - /** - * Max Number of FREQUENT_FLYER records per CUSTOMER - */ - public static final int CUSTOMER_NUM_FREQUENTFLYERS_MIN = 0; - public static final int CUSTOMER_NUM_FREQUENTFLYERS_MAX = 10; - public static final double CUSTOMER_NUM_FREQUENTFLYERS_SIGMA = 2.0; - - /** - * The maximum number of days that we allow a customer to wait before needing - * a reservation on a return to their original departure airport - */ - public static final int CUSTOMER_RETURN_FLIGHT_DAYS_MIN = 1; - public static final int CUSTOMER_RETURN_FLIGHT_DAYS_MAX = 14; - - // ---------------------------------------------------------------- - // RESERVATION CONSTANTS - // ---------------------------------------------------------------- - - public static final int RESERVATION_PRICE_MIN = 100; - public static final int RESERVATION_PRICE_MAX = 1000; - - public static final int MAX_OPEN_SEATS_PER_TXN = 100; - - // ---------------------------------------------------------------- - // PROBABILITIES - // ---------------------------------------------------------------- - - /** - * Probability that a customer books a non-roundtrip flight (0% - 100%) - */ - public static final int PROB_SINGLE_FLIGHT_RESERVATION = 10; - - /** - * Probability that a customer will invoke DeleteReservation using the string - * version of their Customer Id (0% - 100%) - */ - public static final int PROB_DELETE_WITH_CUSTOMER_ID_STR = 20; - - /** - * Probability that a customer will invoke UpdateCustomer using the string - * version of their Customer Id (0% - 100%) - */ - public static final int PROB_UPDATE_WITH_CUSTOMER_ID_STR = 20; - - /** - * Probability that a customer will invoke DeleteReservation using the string - * version of their FrequentFlyer Id (0% - 100%) - */ - public static final int PROB_DELETE_WITH_FREQUENTFLYER_ID_STR = 20; - - /** - * Probability that is a seat is initially occupied (0% - 100%) - */ - public static final int PROB_SEAT_OCCUPIED = 1; // 25; - - /** - * Probability that UpdateCustomer should update FrequentFlyer records - */ - public static final int PROB_UPDATE_FREQUENT_FLYER = 25; - - /** - * Probability that a new Reservation will be added to the DeleteReservation queue - */ - public static final int PROB_DELETE_RESERVATION = 50; - - /** - * Probability that a new Reservation will be added to the UpdateReservation queue - */ - public static final int PROB_UPDATE_RESERVATION = 50; - - /** - * Probability that a deleted Reservation will be requeued for another NewReservation call - */ - public static final int PROB_REQUEUE_DELETED_RESERVATION = 90; - - /** - * Probability that FindFlights will use the distance search - */ - public static final int PROB_FIND_FLIGHTS_NEARBY_AIRPORT = 25; - - /** - * Probability that FindFlights will use two random airports as its input - */ - public static final int PROB_FIND_FLIGHTS_RANDOM_AIRPORTS = 10; - - // ---------------------------------------------------------------- - // TIME CONSTANTS - // ---------------------------------------------------------------- - - /** - * Number of microseconds in a day - */ - public static final long MILLISECONDS_PER_MINUTE = 60000L; // 60sec * 1,000 - - /** - * Number of microseconds in a day - */ - public static final long MILLISECONDS_PER_DAY = 86400000L; // 60sec * 60min * 24hr * 1,000 - - /** - * The format of the time codes used in HISTOGRAM_FLIGHTS_PER_DEPART_TIMES - */ - public static final Pattern TIMECODE_PATTERN = Pattern.compile("([\\d]{2,2}):([\\d]{2,2})"); - - // ---------------------------------------------------------------- - // CACHE SIZES - // ---------------------------------------------------------------- - - /** - * The number of FlightIds we want to keep cached locally at a client - */ - public static final int CACHE_LIMIT_FLIGHT_IDS = 10000; - - public static final int CACHE_LIMIT_PENDING_INSERTS = 10000; - public static final int CACHE_LIMIT_PENDING_UPDATES = 5000; - public static final int CACHE_LIMIT_PENDING_DELETES = 5000; - - // ---------------------------------------------------------------- - // DATA SET INFORMATION - // ---------------------------------------------------------------- - - /** - * Table Names - */ - public static final String TABLENAME_COUNTRY = "country"; - public static final String TABLENAME_AIRLINE = "airline"; - public static final String TABLENAME_CUSTOMER = "customer"; - public static final String TABLENAME_FREQUENT_FLYER = "frequent_flyer"; - public static final String TABLENAME_AIRPORT = "airport"; - public static final String TABLENAME_AIRPORT_DISTANCE = "airport_distance"; - public static final String TABLENAME_FLIGHT = "flight"; - public static final String TABLENAME_RESERVATION = "reservation"; - - public static final String TABLENAME_CONFIG_PROFILE = "config_profile"; - public static final String TABLENAME_CONFIG_HISTOGRAMS = "config_histograms"; - - /** - * Histogram Data Set Names - */ - public static final String HISTOGRAM_FLIGHTS_PER_AIRPORT = "flights_per_airport"; - public static final String HISTOGRAM_FLIGHTS_PER_DEPART_TIMES = "flights_per_time"; - - /** - * Tables that are loaded from data files - */ - public static final String[] TABLES_DATAFILES = { - SEATSConstants.TABLENAME_COUNTRY, - SEATSConstants.TABLENAME_AIRPORT, - SEATSConstants.TABLENAME_AIRLINE, - }; - - /** - * Tables generated from random data - * IMPORTANT: FLIGHT must come before FREQUENT_FLYER - */ - public static final String[] TABLES_SCALING = { - SEATSConstants.TABLENAME_CUSTOMER, - SEATSConstants.TABLENAME_AIRPORT_DISTANCE, - SEATSConstants.TABLENAME_FLIGHT, - SEATSConstants.TABLENAME_FREQUENT_FLYER, - SEATSConstants.TABLENAME_RESERVATION, - }; - - /** - * Configuration Tables - */ - public static final String[] TABLES_CONFIG = { - SEATSConstants.TABLENAME_CONFIG_PROFILE, - SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS, - }; - - /** - * Histograms generated from data files - */ - public static final String[] HISTOGRAM_DATA_FILES = { - SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT, - SEATSConstants.HISTOGRAM_FLIGHTS_PER_DEPART_TIMES, - }; - - /** - * Tuple Code to Tuple Id Mapping - * For some tables, we want to store a unique code that can be used to map - * to the id of a tuple. Any table that has a foreign key reference to this table - * will use the unique code in the input data tables instead of the id. Thus, we need - * to keep a table of how to map these codes to the ids when loading. - */ - - public static final String AIRPORT_ID = "ap_id"; - public static final String AIRLINE_ID = "al_id"; - public static final String COUNTRY_ID = "co_id"; - public static final String AIRLINE_IATA_CODE = "al_iata_code"; - public static final String AIRPORT_CODE = "ap_code"; - public static final String COUNTRY_CODE = "co_code_3"; - - public static final String[][] CODE_TO_ID_COLUMNS = { - {TABLENAME_COUNTRY, COUNTRY_CODE, COUNTRY_ID}, - {TABLENAME_AIRPORT, AIRPORT_CODE, AIRPORT_ID}, - {TABLENAME_AIRLINE, AIRLINE_IATA_CODE, AIRLINE_ID}, - }; + // ---------------------------------------------------------------- + // STORED PROCEDURE EXECUTION FREQUENCIES (0% - 100%) + // ---------------------------------------------------------------- + + public static final int FREQUENCY_DELETE_RESERVATION = 10; + public static final int FREQUENCY_FIND_FLIGHTS = 10; + public static final int FREQUENCY_FIND_OPEN_SEATS = 35; + public static final int FREQUENCY_NEW_RESERVATION = 20; + public static final int FREQUENCY_UPDATE_CUSTOMER = 10; + public static final int FREQUENCY_UPDATE_RESERVATION = 15; + + // ---------------------------------------------------------------- + // FLIGHT CONSTANTS + // ---------------------------------------------------------------- + + /** + * The different distances that we can look-up for nearby airports This is similar to the customer + * selecting a dropdown when looking for flights + */ + // public static final int DISTANCES[] = { 5 }; // , 10, 25, 50, 100 }; + + // Zhenwu made the changes. The original code is above + public static final int[] DISTANCES = {5, 10, 25, 50, 100}; + + /** The number of days in the past and future that we will generate flight information for */ + public static final int FLIGHTS_DAYS_PAST = 1; + + public static final int FLIGHTS_DAYS_FUTURE = 50; + + /** + * Average # of flights per day NUM_FLIGHTS_PER_DAY = 15000 Source: + * http://www.transtats.bts.gov/DL_SelectFields.asp?Table_ID=236&DB_Short_Name=On-Time + */ + public static final int FLIGHTS_PER_DAY_MIN = 1125; + + public static final int FLIGHTS_PER_DAY_MAX = 1875; + + /** + * Number of seats available per flight If you change this then you must also change FindOpenSeats + */ + public static final int FLIGHTS_NUM_SEATS = 150; + + /** How many First Class seats are on a given flight These reservations are more expensive */ + public static final int FLIGHTS_FIRST_CLASS_OFFSET = 10; + + /** The rate in which a flight can travel between two airports (miles per hour) */ + public static final double FLIGHT_TRAVEL_RATE = 570.0; // Boeing 747 + + // ---------------------------------------------------------------- + // CUSTOMER CONSTANTS + // ---------------------------------------------------------------- + + /** Default number of customers in the database */ + public static final int CUSTOMERS_COUNT = 100000; + + /** Max Number of FREQUENT_FLYER records per CUSTOMER */ + public static final int CUSTOMER_NUM_FREQUENTFLYERS_MIN = 0; + + public static final int CUSTOMER_NUM_FREQUENTFLYERS_MAX = 10; + public static final double CUSTOMER_NUM_FREQUENTFLYERS_SIGMA = 2.0; + + /** + * The maximum number of days that we allow a customer to wait before needing a reservation on a + * return to their original departure airport + */ + public static final int CUSTOMER_RETURN_FLIGHT_DAYS_MIN = 1; + + public static final int CUSTOMER_RETURN_FLIGHT_DAYS_MAX = 14; + + // ---------------------------------------------------------------- + // RESERVATION CONSTANTS + // ---------------------------------------------------------------- + + public static final int RESERVATION_PRICE_MIN = 100; + public static final int RESERVATION_PRICE_MAX = 1000; + + public static final int MAX_OPEN_SEATS_PER_TXN = 100; + + // ---------------------------------------------------------------- + // PROBABILITIES + // ---------------------------------------------------------------- + + /** Probability that a customer books a non-roundtrip flight (0% - 100%) */ + public static final int PROB_SINGLE_FLIGHT_RESERVATION = 10; + + /** + * Probability that a customer will invoke DeleteReservation using the string version of their + * Customer Id (0% - 100%) + */ + public static final int PROB_DELETE_WITH_CUSTOMER_ID_STR = 20; + + /** + * Probability that a customer will invoke UpdateCustomer using the string version of their + * Customer Id (0% - 100%) + */ + public static final int PROB_UPDATE_WITH_CUSTOMER_ID_STR = 20; + + /** + * Probability that a customer will invoke DeleteReservation using the string version of their + * FrequentFlyer Id (0% - 100%) + */ + public static final int PROB_DELETE_WITH_FREQUENTFLYER_ID_STR = 20; + + /** Probability that is a seat is initially occupied (0% - 100%) */ + public static final int PROB_SEAT_OCCUPIED = 1; // 25; + + /** Probability that UpdateCustomer should update FrequentFlyer records */ + public static final int PROB_UPDATE_FREQUENT_FLYER = 25; + + /** Probability that a new Reservation will be added to the DeleteReservation queue */ + public static final int PROB_DELETE_RESERVATION = 50; + + /** Probability that a new Reservation will be added to the UpdateReservation queue */ + public static final int PROB_UPDATE_RESERVATION = 50; + + /** Probability that a deleted Reservation will be requeued for another NewReservation call */ + public static final int PROB_REQUEUE_DELETED_RESERVATION = 90; + + /** Probability that FindFlights will use the distance search */ + public static final int PROB_FIND_FLIGHTS_NEARBY_AIRPORT = 25; + + /** Probability that FindFlights will use two random airports as its input */ + public static final int PROB_FIND_FLIGHTS_RANDOM_AIRPORTS = 10; + + // ---------------------------------------------------------------- + // TIME CONSTANTS + // ---------------------------------------------------------------- + + /** Number of microseconds in a day */ + public static final long MILLISECONDS_PER_MINUTE = 60000L; // 60sec * 1,000 + + /** Number of microseconds in a day */ + public static final long MILLISECONDS_PER_DAY = 86400000L; // 60sec * 60min * 24hr * 1,000 + /** The format of the time codes used in HISTOGRAM_FLIGHTS_PER_DEPART_TIMES */ + public static final Pattern TIMECODE_PATTERN = Pattern.compile("([\\d]{2,2}):([\\d]{2,2})"); + + // ---------------------------------------------------------------- + // CACHE SIZES + // ---------------------------------------------------------------- + + /** The number of FlightIds we want to keep cached locally at a client */ + public static final int CACHE_LIMIT_FLIGHT_IDS = 10000; + + public static final int CACHE_LIMIT_PENDING_INSERTS = 10000; + public static final int CACHE_LIMIT_PENDING_UPDATES = 5000; + public static final int CACHE_LIMIT_PENDING_DELETES = 5000; + + // ---------------------------------------------------------------- + // DATA SET INFORMATION + // ---------------------------------------------------------------- + + /** Table Names */ + public static final String TABLENAME_COUNTRY = "country"; + + public static final String TABLENAME_AIRLINE = "airline"; + public static final String TABLENAME_CUSTOMER = "customer"; + public static final String TABLENAME_FREQUENT_FLYER = "frequent_flyer"; + public static final String TABLENAME_AIRPORT = "airport"; + public static final String TABLENAME_AIRPORT_DISTANCE = "airport_distance"; + public static final String TABLENAME_FLIGHT = "flight"; + public static final String TABLENAME_RESERVATION = "reservation"; + + public static final String TABLENAME_CONFIG_PROFILE = "config_profile"; + public static final String TABLENAME_CONFIG_HISTOGRAMS = "config_histograms"; + + /** Histogram Data Set Names */ + public static final String HISTOGRAM_FLIGHTS_PER_AIRPORT = "flights_per_airport"; + + public static final String HISTOGRAM_FLIGHTS_PER_DEPART_TIMES = "flights_per_time"; + + /** Tables that are loaded from data files */ + public static final String[] TABLES_DATAFILES = { + SEATSConstants.TABLENAME_COUNTRY, + SEATSConstants.TABLENAME_AIRPORT, + SEATSConstants.TABLENAME_AIRLINE, + }; + + /** Tables generated from random data IMPORTANT: FLIGHT must come before FREQUENT_FLYER */ + public static final String[] TABLES_SCALING = { + SEATSConstants.TABLENAME_CUSTOMER, + SEATSConstants.TABLENAME_AIRPORT_DISTANCE, + SEATSConstants.TABLENAME_FLIGHT, + SEATSConstants.TABLENAME_FREQUENT_FLYER, + SEATSConstants.TABLENAME_RESERVATION, + }; + + /** Configuration Tables */ + public static final String[] TABLES_CONFIG = { + SEATSConstants.TABLENAME_CONFIG_PROFILE, SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS, + }; + + /** Histograms generated from data files */ + public static final String[] HISTOGRAM_DATA_FILES = { + SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT, SEATSConstants.HISTOGRAM_FLIGHTS_PER_DEPART_TIMES, + }; + + /** + * Tuple Code to Tuple Id Mapping For some tables, we want to store a unique code that can be used + * to map to the id of a tuple. Any table that has a foreign key reference to this table will use + * the unique code in the input data tables instead of the id. Thus, we need to keep a table of + * how to map these codes to the ids when loading. + */ + public static final String AIRPORT_ID = "ap_id"; + + public static final String AIRLINE_ID = "al_id"; + public static final String COUNTRY_ID = "co_id"; + public static final String AIRLINE_IATA_CODE = "al_iata_code"; + public static final String AIRPORT_CODE = "ap_code"; + public static final String COUNTRY_CODE = "co_code_3"; + + public static final String[][] CODE_TO_ID_COLUMNS = { + {TABLENAME_COUNTRY, COUNTRY_CODE, COUNTRY_ID}, + {TABLENAME_AIRPORT, AIRPORT_CODE, AIRPORT_ID}, + {TABLENAME_AIRLINE, AIRLINE_IATA_CODE, AIRLINE_ID}, + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java index 31b5e7226..bf31f2cec 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSLoader.java @@ -27,9 +27,6 @@ import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; import com.oltpbenchmark.util.RandomDistribution.Gaussian; import com.oltpbenchmark.util.RandomDistribution.Zipf; -import org.apache.commons.collections4.map.ListOrderedMap; -import org.apache.commons.collections4.set.ListOrderedSet; - import java.sql.*; import java.util.*; import java.util.Map.Entry; @@ -38,1781 +35,1890 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; +import org.apache.commons.collections4.map.ListOrderedMap; +import org.apache.commons.collections4.set.ListOrderedSet; public final class SEATSLoader extends Loader { - // ----------------------------------------------------------------- - // INTERNAL DATA MEMBERS - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // INTERNAL DATA MEMBERS + // ----------------------------------------------------------------- - protected final SEATSProfile profile; + protected final SEATSProfile profile; - /** - * Mapping from Airports to their geolocation coordinates AirportCode -> - * - */ - private final ListOrderedMap> airport_locations = new ListOrderedMap<>(); + /** Mapping from Airports to their geolocation coordinates AirportCode -> */ + private final ListOrderedMap> airport_locations = + new ListOrderedMap<>(); - /** - * AirportCode -> Set Only store the records for - * those airports in HISTOGRAM_FLIGHTS_PER_AIRPORT - */ - private final Map> airport_distances = new HashMap<>(); + /** + * AirportCode -> Set Only store the records for those airports in + * HISTOGRAM_FLIGHTS_PER_AIRPORT + */ + private final Map> airport_distances = new HashMap<>(); - /** - * Store a list of FlightIds and the number of seats remaining for a - * particular flight. - */ - private final ListOrderedMap seats_remaining = new ListOrderedMap<>(); + /** Store a list of FlightIds and the number of seats remaining for a particular flight. */ + private final ListOrderedMap seats_remaining = new ListOrderedMap<>(); - /** - * Counter for the number of tables that we have finished loading - */ - private final AtomicInteger finished = new AtomicInteger(0); + /** Counter for the number of tables that we have finished loading */ + private final AtomicInteger finished = new AtomicInteger(0); - /** - * A histogram of the number of flights in the database per airline code - */ - private final Histogram flights_per_airline = new Histogram<>(true); + /** A histogram of the number of flights in the database per airline code */ + private final Histogram flights_per_airline = new Histogram<>(true); - private final RandomGenerator rng; // FIXME + private final RandomGenerator rng; // FIXME - // ----------------------------------------------------------------- - // INITIALIZATION - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // INITIALIZATION + // ----------------------------------------------------------------- - public SEATSLoader(SEATSBenchmark benchmark) { - super(benchmark); + public SEATSLoader(SEATSBenchmark benchmark) { + super(benchmark); - this.rng = benchmark.getRandomGenerator(); - // TODO: Sync with the base class rng - this.profile = new SEATSProfile(benchmark, this.rng); + this.rng = benchmark.getRandomGenerator(); + // TODO: Sync with the base class rng + this.profile = new SEATSProfile(benchmark, this.rng); - if (LOG.isDebugEnabled()) { - LOG.debug("CONSTRUCTOR: {}", SEATSLoader.class.getName()); - } + if (LOG.isDebugEnabled()) { + LOG.debug("CONSTRUCTOR: {}", SEATSLoader.class.getName()); } - - // ----------------------------------------------------------------- - // LOADING METHODS - // ----------------------------------------------------------------- - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - - // High level locking overview, where step N+1 depends on step N - // and latches are countDown()'d from top to bottom: - // - // 1. [histLatch] Histograms will be loaded on their own - // - // FIXED TABLES [fixedLatch] - // 2. - // [countryLatch] Country will be loaded on their own - // AIRPORT depends on COUNTRY - // AIRLINE depends on COUNTRY - // - // 3. [scalePrepLatch] - // We need to load fixed table data into histograms before we - // start to load scaling tables - // - // SCALING TABLES - // 4. - // [custLatch] CUSTOMER depends on AIRPORT - // [distanceLatch] AIRPORT_DISTANCE depends on AIRPORT - // [flightLatch] FLIGHT depends on AIRLINE, AIRPORT, AIRPORT_DISTANCE - // - // 5. [loadLatch] - // RESERVATIONS depends on FLIGHT, CUSTOMER - // FREQUENT_FLYER depends on FLIGHT, CUSTOMER, AIRLINE - // - // Important note: FLIGHT must come before FREQUENT_FLYER so that - // we can use the flights_per_airline histogram when - // selecting an airline to create a new FREQUENT_FLYER - // account for a CUSTOMER - // - // 6. Then we save the profile - - final CountDownLatch histLatch = new CountDownLatch(1); - - // 1. [histLatch] HISTOGRAMS - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - loadHistograms(); - } - - @Override - public void afterLoad() { - histLatch.countDown(); - } + } + + // ----------------------------------------------------------------- + // LOADING METHODS + // ----------------------------------------------------------------- + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + + // High level locking overview, where step N+1 depends on step N + // and latches are countDown()'d from top to bottom: + // + // 1. [histLatch] Histograms will be loaded on their own + // + // FIXED TABLES [fixedLatch] + // 2. + // [countryLatch] Country will be loaded on their own + // AIRPORT depends on COUNTRY + // AIRLINE depends on COUNTRY + // + // 3. [scalePrepLatch] + // We need to load fixed table data into histograms before we + // start to load scaling tables + // + // SCALING TABLES + // 4. + // [custLatch] CUSTOMER depends on AIRPORT + // [distanceLatch] AIRPORT_DISTANCE depends on AIRPORT + // [flightLatch] FLIGHT depends on AIRLINE, AIRPORT, AIRPORT_DISTANCE + // + // 5. [loadLatch] + // RESERVATIONS depends on FLIGHT, CUSTOMER + // FREQUENT_FLYER depends on FLIGHT, CUSTOMER, AIRLINE + // + // Important note: FLIGHT must come before FREQUENT_FLYER so that + // we can use the flights_per_airline histogram when + // selecting an airline to create a new FREQUENT_FLYER + // account for a CUSTOMER + // + // 6. Then we save the profile + + final CountDownLatch histLatch = new CountDownLatch(1); + + // 1. [histLatch] HISTOGRAMS + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + loadHistograms(); + } + + @Override + public void afterLoad() { + histLatch.countDown(); + } }); - final CountDownLatch fixedLatch = new CountDownLatch(3); - final CountDownLatch countryLatch = new CountDownLatch(1); + final CountDownLatch fixedLatch = new CountDownLatch(3); + final CountDownLatch countryLatch = new CountDownLatch(1); - // 2. [countryLatch] COUNTRY - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - loadFixedTable(conn, SEATSConstants.TABLENAME_COUNTRY); - } + // 2. [countryLatch] COUNTRY + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + loadFixedTable(conn, SEATSConstants.TABLENAME_COUNTRY); + } - @Override - public void beforeLoad() { - try { - histLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + histLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - fixedLatch.countDown(); - countryLatch.countDown(); - } + @Override + public void afterLoad() { + fixedLatch.countDown(); + countryLatch.countDown(); + } }); - // 2. AIRPORT depends on COUNTRY - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - loadFixedTable(conn, SEATSConstants.TABLENAME_AIRPORT); - } + // 2. AIRPORT depends on COUNTRY + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + loadFixedTable(conn, SEATSConstants.TABLENAME_AIRPORT); + } - @Override - public void beforeLoad() { - try { - countryLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + countryLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - fixedLatch.countDown(); - } + @Override + public void afterLoad() { + fixedLatch.countDown(); + } }); - // 2. AIRLINE depends on COUNTRY - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - loadFixedTable(conn, SEATSConstants.TABLENAME_AIRLINE); - } - - @Override - public void beforeLoad() { - try { - countryLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + // 2. AIRLINE depends on COUNTRY + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + loadFixedTable(conn, SEATSConstants.TABLENAME_AIRLINE); + } + @Override + public void beforeLoad() { + try { + countryLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - fixedLatch.countDown(); - } + @Override + public void afterLoad() { + fixedLatch.countDown(); + } }); - final CountDownLatch scalingPrepLatch = new CountDownLatch(1); + final CountDownLatch scalingPrepLatch = new CountDownLatch(1); - // 3. [scalingPrepLatch] guards all of the fixed tables and should - // be used from this point onwards instead of individual fixed locks - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - // Setup the # of flights per airline - flights_per_airline.putAll(SEATSLoader.this.profile.getAirlineCodes(), 0); - } + // 3. [scalingPrepLatch] guards all of the fixed tables and should + // be used from this point onwards instead of individual fixed locks + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + // Setup the # of flights per airline + flights_per_airline.putAll(SEATSLoader.this.profile.getAirlineCodes(), 0); + } - @Override - public void beforeLoad() { - try { - fixedLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + fixedLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - scalingPrepLatch.countDown(); - } + @Override + public void afterLoad() { + scalingPrepLatch.countDown(); + } }); - final CountDownLatch custLatch = new CountDownLatch(1); - final CountDownLatch distanceLatch = new CountDownLatch(1); - final CountDownLatch flightLatch = new CountDownLatch(1); - - // 4. [custLatch] CUSTOMER depends on AIRPORT - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { + final CountDownLatch custLatch = new CountDownLatch(1); + final CountDownLatch distanceLatch = new CountDownLatch(1); + final CountDownLatch flightLatch = new CountDownLatch(1); - loadScalingTable(conn, SEATSConstants.TABLENAME_CUSTOMER); - - } + // 4. [custLatch] CUSTOMER depends on AIRPORT + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { - @Override - public void beforeLoad() { - try { - scalingPrepLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + loadScalingTable(conn, SEATSConstants.TABLENAME_CUSTOMER); + } + @Override + public void beforeLoad() { + try { + scalingPrepLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - custLatch.countDown(); - } + @Override + public void afterLoad() { + custLatch.countDown(); + } }); - // 4. AIRPORT_DISTANCE depends on AIRPORT - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - + // 4. AIRPORT_DISTANCE depends on AIRPORT + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { - loadScalingTable(conn, SEATSConstants.TABLENAME_AIRPORT_DISTANCE); - - } + loadScalingTable(conn, SEATSConstants.TABLENAME_AIRPORT_DISTANCE); + } - @Override - public void beforeLoad() { - try { - scalingPrepLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + scalingPrepLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - distanceLatch.countDown(); - } + @Override + public void afterLoad() { + distanceLatch.countDown(); + } }); - // 4. [flightLatch] FLIGHT depends on AIRPORT_DISTANCE, AIRLINE, AIRPORT - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - + // 4. [flightLatch] FLIGHT depends on AIRPORT_DISTANCE, AIRLINE, AIRPORT + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { - loadScalingTable(conn, SEATSConstants.TABLENAME_FLIGHT); - - } + loadScalingTable(conn, SEATSConstants.TABLENAME_FLIGHT); + } - @Override - public void beforeLoad() { - try { - distanceLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + distanceLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - flightLatch.countDown(); - } + @Override + public void afterLoad() { + flightLatch.countDown(); + } }); - final CountDownLatch loadLatch = new CountDownLatch(2); - - // 5. RESERVATIONS depends on FLIGHT, CUSTOMER - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { + final CountDownLatch loadLatch = new CountDownLatch(2); + // 5. RESERVATIONS depends on FLIGHT, CUSTOMER + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { - loadScalingTable(conn, SEATSConstants.TABLENAME_RESERVATION); - - } + loadScalingTable(conn, SEATSConstants.TABLENAME_RESERVATION); + } - @Override - public void beforeLoad() { - try { - flightLatch.await(); - custLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + flightLatch.await(); + custLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - loadLatch.countDown(); - } + @Override + public void afterLoad() { + loadLatch.countDown(); + } }); - // 5. FREQUENT_FLYER depends on FLIGHT, CUSTOMER, AIRLINE - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - - loadScalingTable(conn, SEATSConstants.TABLENAME_FREQUENT_FLYER); - - } + // 5. FREQUENT_FLYER depends on FLIGHT, CUSTOMER, AIRLINE + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { - @Override - public void beforeLoad() { - try { - flightLatch.await(); - custLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + loadScalingTable(conn, SEATSConstants.TABLENAME_FREQUENT_FLYER); + } + @Override + public void beforeLoad() { + try { + flightLatch.await(); + custLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - loadLatch.countDown(); - } + @Override + public void afterLoad() { + loadLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - profile.saveProfile(conn); - } - - @Override - public void beforeLoad() { - try { - loadLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + profile.saveProfile(conn); + } + @Override + public void beforeLoad() { + try { + loadLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - + } }); - return threads; + return threads; + } + + /** Load all the histograms used in the benchmark */ + protected void loadHistograms() { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Loading in %d histograms from files stored in '%s'", + SEATSConstants.HISTOGRAM_DATA_FILES.length, this.profile.airline_data_dir)); } - /** - * Load all the histograms used in the benchmark - */ - protected void loadHistograms() { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loading in %d histograms from files stored in '%s'", SEATSConstants.HISTOGRAM_DATA_FILES.length, this.profile.airline_data_dir)); + // Now load in the histograms that we will need for generating the + // flight data + for (String histogramName : SEATSConstants.HISTOGRAM_DATA_FILES) { + if (this.profile.histograms.containsKey(histogramName)) { + LOG.warn("Already loaded histogram '{}'. Skipping...", histogramName); + continue; + } + if (LOG.isDebugEnabled()) { + LOG.debug("Loading in histogram data file for '{}'", histogramName); + } + Histogram hist = null; + + try { + // The Flights_Per_Airport histogram is actually a serialized + // map that has a histogram + // of the departing flights from each airport to all the others + if (histogramName.equals(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT)) { + Map> m = + SEATSHistogramUtil.loadAirportFlights(this.profile.airline_data_dir); + + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %d airport flight histograms", m.size())); + } + + // Store the airport codes information + this.profile.airport_histograms.putAll(m); + + // We then need to flatten all of the histograms in this map + // into a single histogram that just counts the number of + // departing flights per airport. We will use this + // to get the distribution of where Customers are located + hist = new Histogram<>(); + for (Entry> e : m.entrySet()) { + hist.put(e.getKey(), e.getValue().getSampleCount()); + } + + // All other histograms are just serialized and can be + // loaded directly + } else { + hist = + SEATSHistogramUtil.loadHistogram(histogramName, this.profile.airline_data_dir, true); } + } catch (Exception ex) { + throw new RuntimeException("Failed to load histogram '" + histogramName + "'", ex); + } + + this.profile.histograms.put(histogramName, hist); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Loaded histogram '%s' [sampleCount=%d, valueCount=%d]", + histogramName, hist.getSampleCount(), hist.getValueCount())); + } + } + } + + /** + * The fixed tables are those that are generated from the static data files The number of tuples + * in these tables will not change based on the scale factor. + * + * @param conn + * @param table_name + */ + protected void loadFixedTable(Connection conn, String table_name) { + LOG.debug(String.format("Loading table '%s' from fixed file", table_name)); + try { + Table catalog_tbl = this.benchmark.getCatalog().getTable(table_name); + try (FixedDataIterable iterable = this.getFixedIterable(catalog_tbl)) { + this.loadTable(conn, catalog_tbl, iterable, workConf.getBatchSize()); + } + + } catch (Throwable ex) { + throw new RuntimeException( + "Failed to load data files for fixed-sized table '" + table_name + "'", ex); + } + } + + /** + * The scaling tables are things that we will scale the number of tuples based on the given + * scaling factor at runtime + * + * @param conn + * @param table_name + */ + protected void loadScalingTable(Connection conn, String table_name) { + try { + Table catalog_tbl = this.benchmark.getCatalog().getTable(table_name); + Iterable iterable = this.getScalingIterable(catalog_tbl); + this.loadTable(conn, catalog_tbl, iterable, workConf.getBatchSize()); + } catch (Throwable ex) { + throw new RuntimeException( + "Failed to load data files for scaling-sized table '" + table_name + "'", ex); + } + } + + /** + * @param catalog_tbl + */ + public void loadTable( + Connection conn, Table catalog_tbl, Iterable iterable, int batch_size) { + // Special Case: Airport Locations + final boolean is_airport = + catalog_tbl.getName().equalsIgnoreCase(SEATSConstants.TABLENAME_AIRPORT); + + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Generating new records for table %s [batchSize=%d]", + catalog_tbl.getName().toLowerCase(), batch_size)); + } + final List columns = catalog_tbl.getColumns(); + + // Check whether we have any special mappings that we need to maintain + Map code_2_id = new HashMap<>(); + Map> mapping_columns = new HashMap<>(); + for (int col_code_idx = 0, cnt = columns.size(); col_code_idx < cnt; col_code_idx++) { + Column catalog_col = columns.get(col_code_idx); + String col_name = catalog_col.getName().toLowerCase(); + + // Code Column -> Id Column Mapping + // Check to see whether this table has columns that we need to map + // their + // code values to tuple ids + String col_id_name = this.profile.code_columns.get(col_name); + if (col_id_name != null) { + Column catalog_id_col = catalog_tbl.getColumnByName(col_id_name); + + int col_id_idx = catalog_tbl.getColumnIndex(catalog_id_col); + code_2_id.put(col_code_idx, col_id_idx); + } + + // Foreign Key Column to Code->Id Mapping + // If this columns references a foreign key that is used in the + // Code->Id mapping that we generating above, + // then we need to know when we should change the + // column value from a code to the id stored in our lookup table + if (this.profile.fkey_value_xref.containsKey(col_name)) { + String col_fkey_name = this.profile.fkey_value_xref.get(col_name); + mapping_columns.put(col_code_idx, this.profile.code_id_xref.get(col_fkey_name)); + } + } - // Now load in the histograms that we will need for generating the - // flight data - for (String histogramName : SEATSConstants.HISTOGRAM_DATA_FILES) { - if (this.profile.histograms.containsKey(histogramName)) { - LOG.warn("Already loaded histogram '{}'. Skipping...", histogramName); - continue; - } - if (LOG.isDebugEnabled()) { - LOG.debug("Loading in histogram data file for '{}'", histogramName); - } - Histogram hist = null; + int row_idx = 0; + int row_batch = 0; - try { - // The Flights_Per_Airport histogram is actually a serialized - // map that has a histogram - // of the departing flights from each airport to all the others - if (histogramName.equals(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT)) { - Map> m = SEATSHistogramUtil.loadAirportFlights(this.profile.airline_data_dir); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d airport flight histograms", m.size())); - } - - // Store the airport codes information - this.profile.airport_histograms.putAll(m); - - // We then need to flatten all of the histograms in this map - // into a single histogram that just counts the number of - // departing flights per airport. We will use this - // to get the distribution of where Customers are located - hist = new Histogram<>(); - for (Entry> e : m.entrySet()) { - hist.put(e.getKey(), e.getValue().getSampleCount()); - } - - // All other histograms are just serialized and can be - // loaded directly - } else { - hist = SEATSHistogramUtil.loadHistogram(histogramName, this.profile.airline_data_dir, true); - } - } catch (Exception ex) { - throw new RuntimeException("Failed to load histogram '" + histogramName + "'", ex); - } + String insert_sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement insert_stmt = conn.prepareStatement(insert_sql)) { + int[] sqlTypes = catalog_tbl.getColumnTypes(); - this.profile.histograms.put(histogramName, hist); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded histogram '%s' [sampleCount=%d, valueCount=%d]", histogramName, hist.getSampleCount(), hist.getValueCount())); - } + for (Object[] tuple : iterable) { + // AIRPORT + if (is_airport) { + // Skip any airport that does not have flights + int col_code_idx = catalog_tbl.getColumnByName("AP_CODE").getIndex(); + if (!this.profile.hasFlights((String) tuple[col_code_idx])) { + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Skipping AIRPORT '%s' because it does not have any flights", + tuple[col_code_idx])); + } + continue; + } + + // Update the row # so that it matches + // what we're actually loading + int col_id_idx = catalog_tbl.getColumnByName("AP_ID").getIndex(); + tuple[col_id_idx] = (long) (row_idx + 1); + + // Store Locations + int col_lat_idx = catalog_tbl.getColumnByName("AP_LATITUDE").getIndex(); + int col_lon_idx = catalog_tbl.getColumnByName("AP_LONGITUDE").getIndex(); + + // HACK: We need to cast floats to doubles for SQLite + Pair coords; + if (tuple[col_lat_idx] instanceof Float) { + coords = + Pair.of( + Double.valueOf(tuple[col_lat_idx].toString()), + Double.valueOf(tuple[col_lon_idx].toString())); + } else { + coords = Pair.of((Double) tuple[col_lat_idx], (Double) tuple[col_lon_idx]); + } + if (coords.first == null || coords.second == null) { + LOG.error(Arrays.toString(tuple)); + } + + this.airport_locations.put(tuple[col_code_idx].toString(), coords); + if (LOG.isTraceEnabled()) { + LOG.trace(String.format("Storing location for '%s': %s", tuple[col_code_idx], coords)); + } } - } + // Code Column -> Id Column + for (int col_code_idx : code_2_id.keySet()) { - /** - * The fixed tables are those that are generated from the static data files - * The number of tuples in these tables will not change based on the scale - * factor. - * - * @param conn - * @param table_name - */ - protected void loadFixedTable(Connection conn, String table_name) { - LOG.debug(String.format("Loading table '%s' from fixed file", table_name)); - try { - Table catalog_tbl = this.benchmark.getCatalog().getTable(table_name); - try (FixedDataIterable iterable = this.getFixedIterable(catalog_tbl)) { - this.loadTable(conn, catalog_tbl, iterable, workConf.getBatchSize()); - } + String code = tuple[col_code_idx].toString().trim(); + if (code.length() > 0) { + Column from_column = columns.get(col_code_idx); - } catch (Throwable ex) { - throw new RuntimeException("Failed to load data files for fixed-sized table '" + table_name + "'", ex); - } - } + Column to_column = columns.get(code_2_id.get(col_code_idx)); - /** - * The scaling tables are things that we will scale the number of tuples - * based on the given scaling factor at runtime - * - * @param conn - * @param table_name - */ - protected void loadScalingTable(Connection conn, String table_name) { - try { - Table catalog_tbl = this.benchmark.getCatalog().getTable(table_name); - Iterable iterable = this.getScalingIterable(catalog_tbl); - this.loadTable(conn, catalog_tbl, iterable, workConf.getBatchSize()); - } catch (Throwable ex) { - throw new RuntimeException("Failed to load data files for scaling-sized table '" + table_name + "'", ex); + long id = (Long) tuple[code_2_id.get(col_code_idx)]; + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Mapping %s '%s' -> %s '%d'", + from_column.getName().toLowerCase(), + code, + to_column.getName().toLowerCase(), + id)); + } + this.profile.code_id_xref.get(to_column.getName().toLowerCase()).put(code, id); + } } - } - /** - * @param catalog_tbl - */ - public void loadTable(Connection conn, Table catalog_tbl, Iterable iterable, int batch_size) { - // Special Case: Airport Locations - final boolean is_airport = catalog_tbl.getName().equalsIgnoreCase(SEATSConstants.TABLENAME_AIRPORT); - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Generating new records for table %s [batchSize=%d]", catalog_tbl.getName().toLowerCase(), batch_size)); + // Foreign Key Code -> Foreign Key Id + for (int col_code_idx : mapping_columns.keySet()) { + if (tuple[col_code_idx] != null) { + String code = tuple[col_code_idx].toString(); + tuple[col_code_idx] = mapping_columns.get(col_code_idx).get(code); + } } - final List columns = catalog_tbl.getColumns(); - - // Check whether we have any special mappings that we need to maintain - Map code_2_id = new HashMap<>(); - Map> mapping_columns = new HashMap<>(); - for (int col_code_idx = 0, cnt = columns.size(); col_code_idx < cnt; col_code_idx++) { - Column catalog_col = columns.get(col_code_idx); - String col_name = catalog_col.getName().toLowerCase(); - - // Code Column -> Id Column Mapping - // Check to see whether this table has columns that we need to map - // their - // code values to tuple ids - String col_id_name = this.profile.code_columns.get(col_name); - if (col_id_name != null) { - Column catalog_id_col = catalog_tbl.getColumnByName(col_id_name); - - int col_id_idx = catalog_tbl.getColumnIndex(catalog_id_col); - code_2_id.put(col_code_idx, col_id_idx); - } - // Foreign Key Column to Code->Id Mapping - // If this columns references a foreign key that is used in the - // Code->Id mapping that we generating above, - // then we need to know when we should change the - // column value from a code to the id stored in our lookup table - if (this.profile.fkey_value_xref.containsKey(col_name)) { - String col_fkey_name = this.profile.fkey_value_xref.get(col_name); - mapping_columns.put(col_code_idx, this.profile.code_id_xref.get(col_fkey_name)); - } + for (int i = 0; i < tuple.length; i++) { + try { + if (tuple[i] != null) { + insert_stmt.setObject(i + 1, tuple[i]); + } else { + insert_stmt.setNull(i + 1, sqlTypes[i]); + } + } catch (SQLDataException ex) { + LOG.error( + "INVALID {} TUPLE: {}", + catalog_tbl.getName().toLowerCase(), + Arrays.toString(tuple)); + throw new RuntimeException( + "Failed to set value for " + catalog_tbl.getColumn(i).getName().toLowerCase(), ex); + } } - - int row_idx = 0; - int row_batch = 0; - - String insert_sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement insert_stmt = conn.prepareStatement(insert_sql)) { - int[] sqlTypes = catalog_tbl.getColumnTypes(); - - for (Object[] tuple : iterable) { - // AIRPORT - if (is_airport) { - // Skip any airport that does not have flights - int col_code_idx = catalog_tbl.getColumnByName("AP_CODE").getIndex(); - if (!this.profile.hasFlights((String) tuple[col_code_idx])) { - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Skipping AIRPORT '%s' because it does not have any flights", tuple[col_code_idx])); - } - continue; - } - - // Update the row # so that it matches - // what we're actually loading - int col_id_idx = catalog_tbl.getColumnByName("AP_ID").getIndex(); - tuple[col_id_idx] = (long) (row_idx + 1); - - // Store Locations - int col_lat_idx = catalog_tbl.getColumnByName("AP_LATITUDE").getIndex(); - int col_lon_idx = catalog_tbl.getColumnByName("AP_LONGITUDE").getIndex(); - - // HACK: We need to cast floats to doubles for SQLite - Pair coords; - if (tuple[col_lat_idx] instanceof Float) { - coords = Pair.of(Double.valueOf(tuple[col_lat_idx].toString()), Double.valueOf(tuple[col_lon_idx].toString())); - } else { - coords = Pair.of((Double) tuple[col_lat_idx], (Double) tuple[col_lon_idx]); - } - if (coords.first == null || coords.second == null) { - LOG.error(Arrays.toString(tuple)); - } - - - this.airport_locations.put(tuple[col_code_idx].toString(), coords); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Storing location for '%s': %s", tuple[col_code_idx], coords)); - } - } - - // Code Column -> Id Column - for (int col_code_idx : code_2_id.keySet()) { - - String code = tuple[col_code_idx].toString().trim(); - if (code.length() > 0) { - Column from_column = columns.get(col_code_idx); - - Column to_column = columns.get(code_2_id.get(col_code_idx)); - - long id = (Long) tuple[code_2_id.get(col_code_idx)]; - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Mapping %s '%s' -> %s '%d'", from_column.getName().toLowerCase(), code, to_column.getName().toLowerCase(), id)); - } - this.profile.code_id_xref.get(to_column.getName().toLowerCase()).put(code, id); - } - } - - // Foreign Key Code -> Foreign Key Id - for (int col_code_idx : mapping_columns.keySet()) { - if (tuple[col_code_idx] != null) { - String code = tuple[col_code_idx].toString(); - tuple[col_code_idx] = mapping_columns.get(col_code_idx).get(code); - } - } - - for (int i = 0; i < tuple.length; i++) { - try { - if (tuple[i] != null) { - insert_stmt.setObject(i + 1, tuple[i]); - } else { - insert_stmt.setNull(i + 1, sqlTypes[i]); - } - } catch (SQLDataException ex) { - LOG.error("INVALID {} TUPLE: {}", catalog_tbl.getName().toLowerCase(), Arrays.toString(tuple)); - throw new RuntimeException("Failed to set value for " + catalog_tbl.getColumn(i).getName().toLowerCase(), ex); - } - } - insert_stmt.addBatch(); - row_idx++; - - if (++row_batch >= batch_size) { - LOG.trace(String.format("Loading %s batch [total=%d]", catalog_tbl.getName().toLowerCase(), row_idx)); - insert_stmt.executeBatch(); - insert_stmt.clearBatch(); - row_batch = 0; - } - - } - - if (row_batch > 0) { - insert_stmt.executeBatch(); - } - - } catch (Exception ex) { - throw new RuntimeException("Failed to load table " + catalog_tbl.getName().toLowerCase(), ex); + insert_stmt.addBatch(); + row_idx++; + + if (++row_batch >= batch_size) { + LOG.trace( + String.format( + "Loading %s batch [total=%d]", catalog_tbl.getName().toLowerCase(), row_idx)); + insert_stmt.executeBatch(); + insert_stmt.clearBatch(); + row_batch = 0; } + } - // Record the number of tuples that we loaded for this table in the - // profile - if (catalog_tbl.getName().equalsIgnoreCase(SEATSConstants.TABLENAME_RESERVATION)) { - this.profile.num_reservations = row_idx + 1; - } + if (row_batch > 0) { + insert_stmt.executeBatch(); + } - LOG.debug(String.format("Finished loading all %d tuples for %s", row_idx, catalog_tbl.getName().toLowerCase())); + } catch (Exception ex) { + throw new RuntimeException("Failed to load table " + catalog_tbl.getName().toLowerCase(), ex); } - // ---------------------------------------------------------------- - // FIXED-SIZE TABLE DATA GENERATION - // ---------------------------------------------------------------- - - /** - * @param catalog_tbl - * @return - * @throws Exception - */ - protected FixedDataIterable getFixedIterable(Table catalog_tbl) throws Exception { - String path = SEATSBenchmark.getTableDataFilePath(this.profile.airline_data_dir, catalog_tbl); - return new FixedDataIterable(catalog_tbl, path); + // Record the number of tuples that we loaded for this table in the + // profile + if (catalog_tbl.getName().equalsIgnoreCase(SEATSConstants.TABLENAME_RESERVATION)) { + this.profile.num_reservations = row_idx + 1; } - /** - * Wrapper around TableDataIterable that will populate additional random - * fields - */ - protected class FixedDataIterable extends TableDataIterable { - private final Set rnd_string = new HashSet<>(); - private final Map rnd_string_min = new HashMap<>(); - private final Map rnd_string_max = new HashMap<>(); - private final Set rnd_integer = new HashSet<>(); - - public FixedDataIterable(Table catalog_tbl, String filePath) throws Exception { - super(catalog_tbl, filePath, true, true); - - // Figure out which columns are random integers and strings - for (Column catalog_col : catalog_tbl.getColumns()) { - int col_idx = catalog_col.getIndex(); - if (catalog_col.getName().toUpperCase().contains("_SATTR")) { - this.rnd_string.add(col_idx); - this.rnd_string_min.put(col_idx, SEATSLoader.this.rng.nextInt(catalog_col.getSize() - 1)); - this.rnd_string_max.put(col_idx, catalog_col.getSize()); - } else if (catalog_col.getName().toUpperCase().contains("_IATTR")) { - this.rnd_integer.add(catalog_col.getIndex()); - } - } + LOG.debug( + String.format( + "Finished loading all %d tuples for %s", row_idx, catalog_tbl.getName().toLowerCase())); + } + + // ---------------------------------------------------------------- + // FIXED-SIZE TABLE DATA GENERATION + // ---------------------------------------------------------------- + + /** + * @param catalog_tbl + * @return + * @throws Exception + */ + protected FixedDataIterable getFixedIterable(Table catalog_tbl) throws Exception { + String path = SEATSBenchmark.getTableDataFilePath(this.profile.airline_data_dir, catalog_tbl); + return new FixedDataIterable(catalog_tbl, path); + } + + /** Wrapper around TableDataIterable that will populate additional random fields */ + protected class FixedDataIterable extends TableDataIterable { + private final Set rnd_string = new HashSet<>(); + private final Map rnd_string_min = new HashMap<>(); + private final Map rnd_string_max = new HashMap<>(); + private final Set rnd_integer = new HashSet<>(); + + public FixedDataIterable(Table catalog_tbl, String filePath) throws Exception { + super(catalog_tbl, filePath, true, true); + + // Figure out which columns are random integers and strings + for (Column catalog_col : catalog_tbl.getColumns()) { + int col_idx = catalog_col.getIndex(); + if (catalog_col.getName().toUpperCase().contains("_SATTR")) { + this.rnd_string.add(col_idx); + this.rnd_string_min.put(col_idx, SEATSLoader.this.rng.nextInt(catalog_col.getSize() - 1)); + this.rnd_string_max.put(col_idx, catalog_col.getSize()); + } else if (catalog_col.getName().toUpperCase().contains("_IATTR")) { + this.rnd_integer.add(catalog_col.getIndex()); } + } + } + + @Override + public Iterator iterator() { + // This is nasty old boy! + return (new TableDataIterable.TableIterator() { @Override - public Iterator iterator() { - // This is nasty old boy! - return (new TableDataIterable.TableIterator() { - - @Override - public Object[] next() { - Object[] tuple = super.next(); - - // Random String (*_SATTR##) - for (int col_idx : FixedDataIterable.this.rnd_string) { - int min_length = FixedDataIterable.this.rnd_string_min.get(col_idx); - int max_length = FixedDataIterable.this.rnd_string_max.get(col_idx); - tuple[col_idx] = SEATSLoader.this.rng.astring(min_length, max_length); - } - // Random Integer (*_IATTR##) - for (int col_idx : FixedDataIterable.this.rnd_integer) { - tuple[col_idx] = SEATSLoader.this.rng.nextLong(); - } - - return (tuple); - } - }); + public Object[] next() { + Object[] tuple = super.next(); + + // Random String (*_SATTR##) + for (int col_idx : FixedDataIterable.this.rnd_string) { + int min_length = FixedDataIterable.this.rnd_string_min.get(col_idx); + int max_length = FixedDataIterable.this.rnd_string_max.get(col_idx); + tuple[col_idx] = SEATSLoader.this.rng.astring(min_length, max_length); + } + // Random Integer (*_IATTR##) + for (int col_idx : FixedDataIterable.this.rnd_integer) { + tuple[col_idx] = SEATSLoader.this.rng.nextLong(); + } + + return (tuple); } + }); + } + } + + // ---------------------------------------------------------------- + // SCALING TABLE DATA GENERATION + // ---------------------------------------------------------------- + + /** + * Return an iterable that spits out tuples for scaling tables + * + * @param catalog_tbl the target table that we need an iterable for + */ + protected Iterable getScalingIterable(Table catalog_tbl) { + String name = catalog_tbl.getName().toLowerCase(); + ScalingDataIterable it = null; + double scaleFactor = this.workConf.getScaleFactor(); + long num_customers = Math.round(SEATSConstants.CUSTOMERS_COUNT * scaleFactor); + + // Customers + if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_CUSTOMER)) { + it = new CustomerIterable(catalog_tbl, num_customers); + } + // FrequentFlyer + else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_FREQUENT_FLYER)) { + it = new FrequentFlyerIterable(catalog_tbl, num_customers); + } + // Airport Distance + else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_AIRPORT_DISTANCE)) { + int max_distance = + Integer.MAX_VALUE; // SEATSConstants.DISTANCES[SEATSConstants.DISTANCES.length + // - 1]; + it = new AirportDistanceIterable(catalog_tbl, max_distance); + } + // Flights + else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_FLIGHT)) { + it = + new FlightIterable( + catalog_tbl, + (int) Math.round(SEATSConstants.FLIGHTS_DAYS_PAST * scaleFactor), + (int) Math.round(SEATSConstants.FLIGHTS_DAYS_FUTURE * scaleFactor)); + } + // Reservations + else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_RESERVATION)) { + long total = + Math.round( + (SEATSConstants.FLIGHTS_PER_DAY_MIN + SEATSConstants.FLIGHTS_PER_DAY_MAX) + / 2d + * scaleFactor); + it = new ReservationIterable(catalog_tbl, total); } - // ---------------------------------------------------------------- - // SCALING TABLE DATA GENERATION - // ---------------------------------------------------------------- + return (it); + } + + /** + * Base Iterable implementation for scaling tables Sub-classes implement the specialValue() method + * to generate values of a specific type instead of just using the random data generators + */ + protected abstract class ScalingDataIterable implements Iterable { + private final Table catalog_tbl; + private final boolean[] special; + private final Object[] data; + private final int[] types; + protected long total; + private long last_id = 0; /** - * Return an iterable that spits out tuples for scaling tables - * - * @param catalog_tbl the target table that we need an iterable for + * @param catalog_tbl + * @param total + * @param special_columns The offsets of the columns that we will invoke specialValue() to get + * their values + * @throws Exception */ - protected Iterable getScalingIterable(Table catalog_tbl) { - String name = catalog_tbl.getName().toLowerCase(); - ScalingDataIterable it = null; - double scaleFactor = this.workConf.getScaleFactor(); - long num_customers = Math.round(SEATSConstants.CUSTOMERS_COUNT * scaleFactor); - - // Customers - if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_CUSTOMER)) { - it = new CustomerIterable(catalog_tbl, num_customers); - } - // FrequentFlyer - else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_FREQUENT_FLYER)) { - it = new FrequentFlyerIterable(catalog_tbl, num_customers); - } - // Airport Distance - else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_AIRPORT_DISTANCE)) { - int max_distance = Integer.MAX_VALUE; // SEATSConstants.DISTANCES[SEATSConstants.DISTANCES.length - // - 1]; - it = new AirportDistanceIterable(catalog_tbl, max_distance); - } - // Flights - else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_FLIGHT)) { - it = new FlightIterable(catalog_tbl, (int) Math.round(SEATSConstants.FLIGHTS_DAYS_PAST * scaleFactor), (int) Math.round(SEATSConstants.FLIGHTS_DAYS_FUTURE * scaleFactor)); - } - // Reservations - else if (name.equalsIgnoreCase(SEATSConstants.TABLENAME_RESERVATION)) { - long total = Math.round((SEATSConstants.FLIGHTS_PER_DAY_MIN + SEATSConstants.FLIGHTS_PER_DAY_MAX) / 2d * scaleFactor); - it = new ReservationIterable(catalog_tbl, total); - } - - return (it); + public ScalingDataIterable(Table catalog_tbl, long total, int[] special_columns) { + this.catalog_tbl = catalog_tbl; + this.total = total; + this.data = new Object[this.catalog_tbl.getColumns().size()]; + this.special = new boolean[this.catalog_tbl.getColumns().size()]; + + for (int i = 0; i < this.special.length; i++) { + this.special[i] = false; + } + for (int idx : special_columns) { + this.special[idx] = true; + } + + // Cache the types + this.types = new int[catalog_tbl.getColumns().size()]; + for (Column catalog_col : catalog_tbl.getColumns()) { + this.types[catalog_col.getIndex()] = catalog_col.getType(); + } } /** - * Base Iterable implementation for scaling tables Sub-classes implement the - * specialValue() method to generate values of a specific type instead of - * just using the random data generators + * Generate a special value for this particular column index + * + * @param id + * @param column_idx + * @return */ - protected abstract class ScalingDataIterable implements Iterable { - private final Table catalog_tbl; - private final boolean[] special; - private final Object[] data; - private final int[] types; - protected long total; - private long last_id = 0; - - /** - * @param catalog_tbl - * @param total - * @param special_columns The offsets of the columns that we will invoke - * specialValue() to get their values - * @throws Exception - */ - public ScalingDataIterable(Table catalog_tbl, long total, int[] special_columns) { - this.catalog_tbl = catalog_tbl; - this.total = total; - this.data = new Object[this.catalog_tbl.getColumns().size()]; - this.special = new boolean[this.catalog_tbl.getColumns().size()]; - - for (int i = 0; i < this.special.length; i++) { - this.special[i] = false; - } - for (int idx : special_columns) { - this.special[idx] = true; - } - - // Cache the types - this.types = new int[catalog_tbl.getColumns().size()]; - for (Column catalog_col : catalog_tbl.getColumns()) { - this.types[catalog_col.getIndex()] = catalog_col.getType(); - } - } + protected abstract Object specialValue(long id, int column_idx); - /** - * Generate a special value for this particular column index - * - * @param id - * @param column_idx - * @return - */ - protected abstract Object specialValue(long id, int column_idx); - - /** - * Simple callback when the ScalingDataIterable is finished - */ - protected void callbackFinished() { - // Nothing... - } - - protected boolean hasNext() { - boolean has_next = (this.last_id < this.total); - if (!has_next) { - this.callbackFinished(); - } - return (has_next); - } - - /** - * Generate the iterator - */ - @Override - public Iterator iterator() { - return (new Iterator() { - @Override - public boolean hasNext() { - return (ScalingDataIterable.this.hasNext()); - } - - @Override - public Object[] next() { - // For every column for this table, generate the random data that - // we need to populate for the new tuple that we will return with next() - for (int i = 0; i < ScalingDataIterable.this.data.length; i++) { - Column catalog_col = ScalingDataIterable.this.catalog_tbl.getColumn(i); - - // Special Value Column - if (ScalingDataIterable.this.special[i]) { - ScalingDataIterable.this.data[i] = ScalingDataIterable.this.specialValue(ScalingDataIterable.this.last_id, i); - - // Id column (always first unless overridden in - // special) - } else if (i == 0) { - ScalingDataIterable.this.data[i] = ScalingDataIterable.this.last_id; - - // Strings - } else if (SQLUtil.isStringType(ScalingDataIterable.this.types[i])) { - // WARN: If you ever have problems with running out of memory because of this block - // of code here, check that the length of the column from the catalog matches the DDL. - // SQLite incorrectly reports that the size of the column was massive for the customer - // table, so then we would allocate 2GB strings. - int max_len = catalog_col.getSize(); - int min_len = SEATSLoader.this.rng.nextInt(max_len - 1); - ScalingDataIterable.this.data[i] = SEATSLoader.this.rng.astring(min_len, max_len); - - // Ints/Longs - } else { - ScalingDataIterable.this.data[i] = SEATSLoader.this.rng.number(0, 1 << 30); - } - } - ScalingDataIterable.this.last_id++; - return (ScalingDataIterable.this.data); - } - - @Override - public void remove() { - // Not Implemented - } - }); - } + /** Simple callback when the ScalingDataIterable is finished */ + protected void callbackFinished() { + // Nothing... } - // ---------------------------------------------------------------- - // CUSTOMERS - // ---------------------------------------------------------------- - protected class CustomerIterable extends ScalingDataIterable { - private final FlatHistogram rand; - private final RandomDistribution.Flat randBalance; - private String airport_code = null; - private CustomerId last_id = null; - - public CustomerIterable(Table catalog_tbl, long total) { - super(catalog_tbl, total, new int[]{0, 1, 2, 3}); - - // Use the flights per airport histogram to select where people are - // located - Histogram histogram = SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); - this.rand = new FlatHistogram<>(SEATSLoader.this.rng, histogram); - if (LOG.isDebugEnabled()) { - this.rand.enableHistory(); - } + protected boolean hasNext() { + boolean has_next = (this.last_id < this.total); + if (!has_next) { + this.callbackFinished(); + } + return (has_next); + } - this.randBalance = new RandomDistribution.Flat(SEATSLoader.this.rng, 1000, 10000); + /** Generate the iterator */ + @Override + public Iterator iterator() { + return (new Iterator() { + @Override + public boolean hasNext() { + return (ScalingDataIterable.this.hasNext()); } @Override - protected Object specialValue(long id, int columnIdx) { - Object value = null; - switch (columnIdx) { - // CUSTOMER ID - case (0): { - // HACK: The flights_per_airport histogram may not match up - // exactly with the airport - // data files, so we'll just spin until we get a good one - Long airport_id = null; - while (airport_id == null) { - this.airport_code = this.rand.nextValue(); - airport_id = SEATSLoader.this.profile.getAirportId(this.airport_code); - } - int next_customer_id = SEATSLoader.this.profile.incrementAirportCustomerCount(airport_id); - this.last_id = new CustomerId(next_customer_id, airport_id); - if (LOG.isTraceEnabled()) { - LOG.trace("NEW CUSTOMER: {} / {}", this.last_id.encode(), this.last_id); - } - value = this.last_id.encode(); - if (LOG.isTraceEnabled()) { - LOG.trace("{} => {} [{}]", value, this.airport_code, SEATSLoader.this.profile.getCustomerIdCount(airport_id)); - } - break; - } - // CUSTOMER ID STR - case (1): { - - value = this.last_id.encode(); - this.last_id = null; - break; - } - // LOCAL AIRPORT - case (2): { - - value = this.airport_code; - break; - } - // BALANCE - case (3): { - value = (double) this.randBalance.nextInt(); - break; - } - // BAD MOJO! - default: - - } - return (value); + public Object[] next() { + // For every column for this table, generate the random data that + // we need to populate for the new tuple that we will return with next() + for (int i = 0; i < ScalingDataIterable.this.data.length; i++) { + Column catalog_col = ScalingDataIterable.this.catalog_tbl.getColumn(i); + + // Special Value Column + if (ScalingDataIterable.this.special[i]) { + ScalingDataIterable.this.data[i] = + ScalingDataIterable.this.specialValue(ScalingDataIterable.this.last_id, i); + + // Id column (always first unless overridden in + // special) + } else if (i == 0) { + ScalingDataIterable.this.data[i] = ScalingDataIterable.this.last_id; + + // Strings + } else if (SQLUtil.isStringType(ScalingDataIterable.this.types[i])) { + // WARN: If you ever have problems with running out of memory because of this block + // of code here, check that the length of the column from the catalog matches the DDL. + // SQLite incorrectly reports that the size of the column was massive for the customer + // table, so then we would allocate 2GB strings. + int max_len = catalog_col.getSize(); + int min_len = SEATSLoader.this.rng.nextInt(max_len - 1); + ScalingDataIterable.this.data[i] = SEATSLoader.this.rng.astring(min_len, max_len); + + // Ints/Longs + } else { + ScalingDataIterable.this.data[i] = SEATSLoader.this.rng.number(0, 1 << 30); + } + } + ScalingDataIterable.this.last_id++; + return (ScalingDataIterable.this.data); } @Override - protected void callbackFinished() { - if (LOG.isTraceEnabled()) { - Histogram h = this.rand.getHistogramHistory(); - LOG.trace(String.format("Customer Local Airports Histogram [valueCount=%d, sampleCount=%d]\n%s", h.getValueCount(), h.getSampleCount(), h)); - } + public void remove() { + // Not Implemented } + }); + } + } + + // ---------------------------------------------------------------- + // CUSTOMERS + // ---------------------------------------------------------------- + protected class CustomerIterable extends ScalingDataIterable { + private final FlatHistogram rand; + private final RandomDistribution.Flat randBalance; + private String airport_code = null; + private CustomerId last_id = null; + + public CustomerIterable(Table catalog_tbl, long total) { + super(catalog_tbl, total, new int[] {0, 1, 2, 3}); + + // Use the flights per airport histogram to select where people are + // located + Histogram histogram = + SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); + this.rand = new FlatHistogram<>(SEATSLoader.this.rng, histogram); + if (LOG.isDebugEnabled()) { + this.rand.enableHistory(); + } + + this.randBalance = new RandomDistribution.Flat(SEATSLoader.this.rng, 1000, 10000); } - // ---------------------------------------------------------------- - // FREQUENT_FLYER - // ---------------------------------------------------------------- - protected class FrequentFlyerIterable extends ScalingDataIterable { - private final Iterator customer_id_iterator; - private final short[] ff_per_customer; - private final FlatHistogram airline_rand; - - private int customer_idx = 0; - private CustomerId last_customer_id = null; - private final Collection customer_airlines = new HashSet<>(); - - public FrequentFlyerIterable(Table catalog_tbl, long num_customers) { - super(catalog_tbl, num_customers, new int[]{0, 1, 2}); - - this.customer_id_iterator = new CustomerIdIterable(SEATSLoader.this.profile.airport_max_customer_id).iterator(); - this.last_customer_id = this.customer_id_iterator.next(); - - // A customer is more likely to have a FREQUENT_FLYER account with - // an airline that has more flights. - // IMPORTANT: Add one to all of the airlines so that we don't get - // trapped - // in an infinite loop - - SEATSLoader.this.flights_per_airline.putAll(); - this.airline_rand = new FlatHistogram<>(SEATSLoader.this.rng, SEATSLoader.this.flights_per_airline); + @Override + protected Object specialValue(long id, int columnIdx) { + Object value = null; + switch (columnIdx) { + // CUSTOMER ID + case (0): + { + // HACK: The flights_per_airport histogram may not match up + // exactly with the airport + // data files, so we'll just spin until we get a good one + Long airport_id = null; + while (airport_id == null) { + this.airport_code = this.rand.nextValue(); + airport_id = SEATSLoader.this.profile.getAirportId(this.airport_code); + } + int next_customer_id = + SEATSLoader.this.profile.incrementAirportCustomerCount(airport_id); + this.last_id = new CustomerId(next_customer_id, airport_id); if (LOG.isTraceEnabled()) { - this.airline_rand.enableHistory(); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Flights Per Airline:\n{}", SEATSLoader.this.flights_per_airline); - } - - // Loop through for the total customers and figure out how many - // entries we - // should have for each one. This will be our new total; - long max_per_customer = Math.min(Math.round(SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_MAX * Math.max(1, SEATSLoader.this.scaleFactor)), SEATSLoader.this.flights_per_airline.getValueCount()); - Zipf ff_zipf = new Zipf(SEATSLoader.this.rng, SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_MIN, max_per_customer, SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_SIGMA); - long new_total = 0; - long total = SEATSLoader.this.profile.getCustomerIdCount(); - if (LOG.isDebugEnabled()) { - LOG.debug("Num of Customers: {}", total); - } - this.ff_per_customer = new short[(int) total]; - for (int i = 0; i < total; i++) { - this.ff_per_customer[i] = (short) ff_zipf.nextInt(); - if (this.ff_per_customer[i] > max_per_customer) { - this.ff_per_customer[i] = (short) max_per_customer; - } - new_total += this.ff_per_customer[i]; + LOG.trace("NEW CUSTOMER: {} / {}", this.last_id.encode(), this.last_id); } - this.total = new_total; - if (LOG.isDebugEnabled()) { - LOG.debug("Constructing {} FrequentFlyer tuples...", this.total); - } - } - - @Override - protected Object specialValue(long id, int columnIdx) { - String value = null; - switch (columnIdx) { - // CUSTOMER ID - case (0): { - while (this.customer_idx < this.ff_per_customer.length && this.ff_per_customer[this.customer_idx] <= 0) { - this.customer_idx++; - this.customer_airlines.clear(); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("CUSTOMER IDX: %d / %d", this.customer_idx, SEATSLoader.this.profile.getCustomerIdCount())); - } - - this.last_customer_id = this.customer_id_iterator.next(); - } - this.ff_per_customer[this.customer_idx]--; - value = this.last_customer_id.encode(); - break; - } - // AIRLINE ID - case (1): { - - do { - value = this.airline_rand.nextValue(); - } - while (this.customer_airlines.contains(value)); - this.customer_airlines.add(value); - if (LOG.isTraceEnabled()) { - LOG.trace("{} => {}", this.last_customer_id, value); - } - break; - } - // CUSTOMER_ID_STR - case (2): { - value = this.last_customer_id.encode(); - break; - } - // BAD MOJO! - default: - - } - return (value); - } - - @Override - protected void callbackFinished() { + value = this.last_id.encode(); if (LOG.isTraceEnabled()) { - Histogram h = this.airline_rand.getHistogramHistory(); - LOG.trace(String.format("Airline Flights Histogram [valueCount=%d, sampleCount=%d]\n%s", h.getValueCount(), h.getSampleCount(), h)); - } - } + LOG.trace( + "{} => {} [{}]", + value, + this.airport_code, + SEATSLoader.this.profile.getCustomerIdCount(airport_id)); + } + break; + } + // CUSTOMER ID STR + case (1): + { + value = this.last_id.encode(); + this.last_id = null; + break; + } + // LOCAL AIRPORT + case (2): + { + value = this.airport_code; + break; + } + // BALANCE + case (3): + { + value = (double) this.randBalance.nextInt(); + break; + } + // BAD MOJO! + default: + } + return (value); } - // ---------------------------------------------------------------- - // AIRPORT_DISTANCE - // ---------------------------------------------------------------- - protected class AirportDistanceIterable extends ScalingDataIterable { - private final int max_distance; - private final int num_airports; - private final Collection record_airports; - - private int outer_ctr = 0; - private String outer_airport; - private Pair outer_location; - - private Integer last_inner_ctr = null; - private String inner_airport; - private Pair inner_location; - private double distance; - - /** - * Constructor - * - * @param catalog_tbl - * @param max_distance - */ - public AirportDistanceIterable(Table catalog_tbl, int max_distance) { - super(catalog_tbl, Long.MAX_VALUE, new int[]{0, 1, 2}); - // total work around ???? - this.max_distance = max_distance; - this.num_airports = SEATSLoader.this.airport_locations.size(); - this.record_airports = SEATSLoader.this.profile.getAirportCodes(); - } - - /** - * Find the next two airports that are within our max_distance limit. We - * keep track of where we were in the inner loop using last_inner_ctr - */ - @Override - protected boolean hasNext() { - for (; this.outer_ctr < (this.num_airports - 1); this.outer_ctr++) { - this.outer_airport = SEATSLoader.this.airport_locations.get(this.outer_ctr); - this.outer_location = SEATSLoader.this.airport_locations.getValue(this.outer_ctr); - if (!SEATSLoader.this.profile.hasFlights(this.outer_airport)) { - continue; - } - - int inner_ctr = (this.last_inner_ctr != null ? this.last_inner_ctr : this.outer_ctr + 1); - this.last_inner_ctr = null; - for (; inner_ctr < this.num_airports; inner_ctr++) { - - this.inner_airport = SEATSLoader.this.airport_locations.get(inner_ctr); - this.inner_location = SEATSLoader.this.airport_locations.getValue(inner_ctr); - if (!SEATSLoader.this.profile.hasFlights(this.inner_airport)) { - continue; - } - this.distance = DistanceUtil.distance(this.outer_location, this.inner_location); - - // Store the distance between the airports locally if either - // one is in our - // flights-per-airport data set - if (this.record_airports.contains(this.outer_airport) && this.record_airports.contains(this.inner_airport)) { - SEATSLoader.this.setDistance(this.outer_airport, this.inner_airport, this.distance); - } - - // Stop here if these two airports are within range - if (this.distance > 0 && this.distance <= this.max_distance) { - // System.err.println(this.outer_airport + "->" + - // this.inner_airport + ": " + distance); - this.last_inner_ctr = inner_ctr + 1; - return (true); - } - } - } - return (false); - } - - @Override - protected Object specialValue(long id, int columnIdx) { - Object value = null; - switch (columnIdx) { - // OUTER AIRPORT - case (0): - value = this.outer_airport; - break; - // INNER AIRPORT - case (1): - value = this.inner_airport; - break; - // DISTANCE - case (2): - value = this.distance; - break; - // BAD MOJO! - default: - - } - return (value); - } + @Override + protected void callbackFinished() { + if (LOG.isTraceEnabled()) { + Histogram h = this.rand.getHistogramHistory(); + LOG.trace( + String.format( + "Customer Local Airports Histogram [valueCount=%d, sampleCount=%d]\n%s", + h.getValueCount(), h.getSampleCount(), h)); + } } - - // ---------------------------------------------------------------- - // FLIGHTS - // ---------------------------------------------------------------- - protected class FlightIterable extends ScalingDataIterable { - private final FlatHistogram airlines; - private final FlatHistogram airports; - private final Map> flights_per_airport = new HashMap<>(); - private final FlatHistogram flight_times; - private final Flat prices; - - private final Set todays_flights = new HashSet<>(); - private final ListOrderedMap flights_per_day = new ListOrderedMap<>(); - - private int day_idx = 0; - private final Timestamp today; - private Timestamp start_date; - - private FlightId flight_id; - private String depart_airport; - private String arrive_airport; - private String airline_code; - private Long airline_id; - private Timestamp depart_time; - private Timestamp arrive_time; - private int status; - - public FlightIterable(Table catalog_tbl, int days_past, int days_future) { - super(catalog_tbl, Long.MAX_VALUE, new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); - - - this.prices = new Flat(SEATSLoader.this.rng, SEATSConstants.RESERVATION_PRICE_MIN, SEATSConstants.RESERVATION_PRICE_MAX); - - // Flights per Airline - Collection all_airlines = SEATSLoader.this.profile.getAirlineCodes(); - Histogram histogram = new Histogram<>(); - histogram.putAll(all_airlines); - - // Embed a Gaussian distribution - Gaussian gauss_rng = new Gaussian(SEATSLoader.this.rng, 0, all_airlines.size()); - this.airlines = new FlatHistogram<>(gauss_rng, histogram); - - // Flights Per Airport - histogram = SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); - this.airports = new FlatHistogram<>(SEATSLoader.this.rng, histogram); - for (String airport_code : histogram.values()) { - histogram = SEATSLoader.this.profile.getFightsPerAirportHistogram(airport_code); - - this.flights_per_airport.put(airport_code, new FlatHistogram<>(SEATSLoader.this.rng, histogram)); - } - - // Flights Per Departure Time - histogram = SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_DEPART_TIMES); - this.flight_times = new FlatHistogram<>(SEATSLoader.this.rng, histogram); - - // Figure out how many flights that we want for each day - this.today = new Timestamp(System.currentTimeMillis()); - - // Sometimes there are more flights per day, and sometimes there are - // fewer - Gaussian gaussian = new Gaussian(SEATSLoader.this.rng, SEATSConstants.FLIGHTS_PER_DAY_MIN, SEATSConstants.FLIGHTS_PER_DAY_MAX); - - this.total = 0; - boolean first = true; - for (long t = this.today.getTime() - (days_past * SEATSConstants.MILLISECONDS_PER_DAY); t < this.today.getTime(); t += SEATSConstants.MILLISECONDS_PER_DAY) { - Timestamp timestamp = new Timestamp(t); - if (first) { - this.start_date = timestamp; - first = false; - } - int num_flights = gaussian.nextInt(); - this.flights_per_day.put(timestamp, num_flights); - this.total += num_flights; - } - if (this.start_date == null) { - this.start_date = this.today; - } - SEATSLoader.this.profile.setFlightStartDate(this.start_date); - - // This is for upcoming flights that we want to be able to schedule - // new reservations for in the benchmark - SEATSLoader.this.profile.setFlightUpcomingDate(this.today); - for (long t = this.today.getTime(), last_date = this.today.getTime() + (days_future * SEATSConstants.MILLISECONDS_PER_DAY); t <= last_date; t += SEATSConstants.MILLISECONDS_PER_DAY) { - Timestamp timestamp = new Timestamp(t); - int num_flights = gaussian.nextInt(); - this.flights_per_day.put(timestamp, num_flights); - this.total += num_flights; - } - - // Update profile - SEATSLoader.this.profile.setFlightPastDays(days_past); - SEATSLoader.this.profile.setFlightFutureDays(days_future); + } + + // ---------------------------------------------------------------- + // FREQUENT_FLYER + // ---------------------------------------------------------------- + protected class FrequentFlyerIterable extends ScalingDataIterable { + private final Iterator customer_id_iterator; + private final short[] ff_per_customer; + private final FlatHistogram airline_rand; + + private int customer_idx = 0; + private CustomerId last_customer_id = null; + private final Collection customer_airlines = new HashSet<>(); + + public FrequentFlyerIterable(Table catalog_tbl, long num_customers) { + super(catalog_tbl, num_customers, new int[] {0, 1, 2}); + + this.customer_id_iterator = + new CustomerIdIterable(SEATSLoader.this.profile.airport_max_customer_id).iterator(); + this.last_customer_id = this.customer_id_iterator.next(); + + // A customer is more likely to have a FREQUENT_FLYER account with + // an airline that has more flights. + // IMPORTANT: Add one to all of the airlines so that we don't get + // trapped + // in an infinite loop + + SEATSLoader.this.flights_per_airline.putAll(); + this.airline_rand = + new FlatHistogram<>(SEATSLoader.this.rng, SEATSLoader.this.flights_per_airline); + if (LOG.isTraceEnabled()) { + this.airline_rand.enableHistory(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Flights Per Airline:\n{}", SEATSLoader.this.flights_per_airline); + } + + // Loop through for the total customers and figure out how many + // entries we + // should have for each one. This will be our new total; + long max_per_customer = + Math.min( + Math.round( + SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_MAX + * Math.max(1, SEATSLoader.this.scaleFactor)), + SEATSLoader.this.flights_per_airline.getValueCount()); + Zipf ff_zipf = + new Zipf( + SEATSLoader.this.rng, + SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_MIN, + max_per_customer, + SEATSConstants.CUSTOMER_NUM_FREQUENTFLYERS_SIGMA); + long new_total = 0; + long total = SEATSLoader.this.profile.getCustomerIdCount(); + if (LOG.isDebugEnabled()) { + LOG.debug("Num of Customers: {}", total); + } + this.ff_per_customer = new short[(int) total]; + for (int i = 0; i < total; i++) { + this.ff_per_customer[i] = (short) ff_zipf.nextInt(); + if (this.ff_per_customer[i] > max_per_customer) { + this.ff_per_customer[i] = (short) max_per_customer; } + new_total += this.ff_per_customer[i]; + } + this.total = new_total; + if (LOG.isDebugEnabled()) { + LOG.debug("Constructing {} FrequentFlyer tuples...", this.total); + } + } - /** - * Convert a time string "HH:MM" to a Timestamp object - * - * @param code - * @return - */ - private Timestamp convertTimeString(Timestamp base_date, String code) { - Matcher m = SEATSConstants.TIMECODE_PATTERN.matcher(code); - boolean result = m.find(); - assert result; - - int hour = -1; - try { - hour = Integer.valueOf(m.group(1)); - } catch (Throwable ex) { - throw new RuntimeException("Invalid HOUR in time code '" + code + "'", ex); - } - - - int minute = -1; - try { - minute = Integer.valueOf(m.group(2)); - } catch (Throwable ex) { - throw new RuntimeException("Invalid MINUTE in time code '" + code + "'", ex); - } - + @Override + protected Object specialValue(long id, int columnIdx) { + String value = null; + switch (columnIdx) { + // CUSTOMER ID + case (0): + { + while (this.customer_idx < this.ff_per_customer.length + && this.ff_per_customer[this.customer_idx] <= 0) { + this.customer_idx++; + this.customer_airlines.clear(); + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "CUSTOMER IDX: %d / %d", + this.customer_idx, SEATSLoader.this.profile.getCustomerIdCount())); + } + + this.last_customer_id = this.customer_id_iterator.next(); + } + this.ff_per_customer[this.customer_idx]--; + value = this.last_customer_id.encode(); + break; + } + // AIRLINE ID + case (1): + { + do { + value = this.airline_rand.nextValue(); + } while (this.customer_airlines.contains(value)); + this.customer_airlines.add(value); + if (LOG.isTraceEnabled()) { + LOG.trace("{} => {}", this.last_customer_id, value); + } + break; + } + // CUSTOMER_ID_STR + case (2): + { + value = this.last_customer_id.encode(); + break; + } + // BAD MOJO! + default: + } + return (value); + } - long offset = (hour * 60 * SEATSConstants.MILLISECONDS_PER_MINUTE) + (minute * SEATSConstants.MILLISECONDS_PER_MINUTE); - return (new Timestamp(base_date.getTime() + offset)); - } + @Override + protected void callbackFinished() { + if (LOG.isTraceEnabled()) { + Histogram h = this.airline_rand.getHistogramHistory(); + LOG.trace( + String.format( + "Airline Flights Histogram [valueCount=%d, sampleCount=%d]\n%s", + h.getValueCount(), h.getSampleCount(), h)); + } + } + } - /** - * Select all the data elements for the current tuple - * - * @param date - */ - private void populate(Timestamp date) { - // Depart/Arrive Airports - this.depart_airport = this.airports.nextValue(); - this.arrive_airport = this.flights_per_airport.get(this.depart_airport).nextValue(); + // ---------------------------------------------------------------- + // AIRPORT_DISTANCE + // ---------------------------------------------------------------- + protected class AirportDistanceIterable extends ScalingDataIterable { + private final int max_distance; + private final int num_airports; + private final Collection record_airports; - // Depart/Arrive Times - this.depart_time = this.convertTimeString(date, this.flight_times.nextValue()); - this.arrive_time = SEATSLoader.this.calculateArrivalTime(this.depart_airport, this.arrive_airport, this.depart_time); + private int outer_ctr = 0; + private String outer_airport; + private Pair outer_location; - // Airline - this.airline_code = this.airlines.nextValue(); - this.airline_id = SEATSLoader.this.profile.getAirlineId(this.airline_code); + private Integer last_inner_ctr = null; + private String inner_airport; + private Pair inner_location; + private double distance; - // Status - this.status = 0; // TODO + /** + * Constructor + * + * @param catalog_tbl + * @param max_distance + */ + public AirportDistanceIterable(Table catalog_tbl, int max_distance) { + super(catalog_tbl, Long.MAX_VALUE, new int[] {0, 1, 2}); + // total work around ???? + this.max_distance = max_distance; + this.num_airports = SEATSLoader.this.airport_locations.size(); + this.record_airports = SEATSLoader.this.profile.getAirportCodes(); + } - this.flights_per_day.put(date, this.flights_per_day.get(date) - 1); + /** + * Find the next two airports that are within our max_distance limit. We keep track of where we + * were in the inner loop using last_inner_ctr + */ + @Override + protected boolean hasNext() { + for (; this.outer_ctr < (this.num_airports - 1); this.outer_ctr++) { + this.outer_airport = SEATSLoader.this.airport_locations.get(this.outer_ctr); + this.outer_location = SEATSLoader.this.airport_locations.getValue(this.outer_ctr); + if (!SEATSLoader.this.profile.hasFlights(this.outer_airport)) { + continue; } - /** - * Returns true if this seat is occupied (which means we must generate a - * reservation) - */ - boolean seatIsOccupied() { - return (SEATSLoader.this.rng.nextInt(100) < SEATSConstants.PROB_SEAT_OCCUPIED); + int inner_ctr = (this.last_inner_ctr != null ? this.last_inner_ctr : this.outer_ctr + 1); + this.last_inner_ctr = null; + for (; inner_ctr < this.num_airports; inner_ctr++) { + + this.inner_airport = SEATSLoader.this.airport_locations.get(inner_ctr); + this.inner_location = SEATSLoader.this.airport_locations.getValue(inner_ctr); + if (!SEATSLoader.this.profile.hasFlights(this.inner_airport)) { + continue; + } + this.distance = DistanceUtil.distance(this.outer_location, this.inner_location); + + // Store the distance between the airports locally if either + // one is in our + // flights-per-airport data set + if (this.record_airports.contains(this.outer_airport) + && this.record_airports.contains(this.inner_airport)) { + SEATSLoader.this.setDistance(this.outer_airport, this.inner_airport, this.distance); + } + + // Stop here if these two airports are within range + if (this.distance > 0 && this.distance <= this.max_distance) { + // System.err.println(this.outer_airport + "->" + + // this.inner_airport + ": " + distance); + this.last_inner_ctr = inner_ctr + 1; + return (true); + } } + } + return (false); + } - @Override - protected Object specialValue(long id, int columnIdx) { - Object value = null; - switch (columnIdx) { - // FLIGHT ID - case (0): { - // Figure out what date we are currently on - Integer remaining = null; - Timestamp date; - do { - // Move to the next day. - // Make sure that we reset the set of FlightIds that - // we've used for today - if (remaining != null) { - this.todays_flights.clear(); - this.day_idx++; - } - date = this.flights_per_day.get(this.day_idx); - remaining = this.flights_per_day.getValue(this.day_idx); - } - while (remaining <= 0 && this.day_idx + 1 < this.flights_per_day.size()); - - - // Keep looping until we get a FlightId that we haven't seen - // yet for this date - while (true) { - this.populate(date); - - // Generate a composite FlightId - this.flight_id = new FlightId(this.airline_id, SEATSLoader.this.profile.getAirportId(this.depart_airport), SEATSLoader.this.profile.getAirportId(this.arrive_airport), this.start_date, this.depart_time); - if (!this.todays_flights.contains(this.flight_id)) { - break; - } - } - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("%s [remaining=%d, dayIdx=%d]", this.flight_id, remaining, this.day_idx)); - } - - - this.todays_flights.add(this.flight_id); - SEATSLoader.this.addFlightId(this.flight_id); - value = this.flight_id.encode(); - break; - } - // AIRLINE ID - case (1): { - value = this.airline_code; - SEATSLoader.this.flights_per_airline.put(this.airline_code); - break; - } - // DEPART AIRPORT - case (2): { - value = this.depart_airport; - break; - } - // DEPART TIME - case (3): { - value = this.depart_time; - break; - } - // ARRIVE AIRPORT - case (4): { - value = this.arrive_airport; - break; - } - // ARRIVE TIME - case (5): { - value = this.arrive_time; - break; - } - // FLIGHT STATUS - case (6): { - value = this.status; - break; - } - // BASE PRICE - case (7): { - value = (double) this.prices.nextInt(); - break; - } - // SEATS TOTAL - case (8): { - value = SEATSConstants.FLIGHTS_NUM_SEATS; - break; - } - // SEATS REMAINING - case (9): { - // We have to figure this out ahead of time since we need to - // populate the tuple now - for (int seatnum = 0; seatnum < SEATSConstants.FLIGHTS_NUM_SEATS; seatnum++) { - if (!this.seatIsOccupied()) { - continue; - } - SEATSLoader.this.decrementFlightSeat(this.flight_id); - } - value = (long) SEATSLoader.this.getFlightRemainingSeats(this.flight_id); - if (LOG.isTraceEnabled()) { - LOG.trace("{} SEATS REMAINING: {}", this.flight_id, value); - } - break; - } - // BAD MOJO! - default: - - } - return (value); + @Override + protected Object specialValue(long id, int columnIdx) { + Object value = null; + switch (columnIdx) { + // OUTER AIRPORT + case (0): + value = this.outer_airport; + break; + // INNER AIRPORT + case (1): + value = this.inner_airport; + break; + // DISTANCE + case (2): + value = this.distance; + break; + // BAD MOJO! + default: + } + return (value); + } + } + + // ---------------------------------------------------------------- + // FLIGHTS + // ---------------------------------------------------------------- + protected class FlightIterable extends ScalingDataIterable { + private final FlatHistogram airlines; + private final FlatHistogram airports; + private final Map> flights_per_airport = new HashMap<>(); + private final FlatHistogram flight_times; + private final Flat prices; + + private final Set todays_flights = new HashSet<>(); + private final ListOrderedMap flights_per_day = new ListOrderedMap<>(); + + private int day_idx = 0; + private final Timestamp today; + private Timestamp start_date; + + private FlightId flight_id; + private String depart_airport; + private String arrive_airport; + private String airline_code; + private Long airline_id; + private Timestamp depart_time; + private Timestamp arrive_time; + private int status; + + public FlightIterable(Table catalog_tbl, int days_past, int days_future) { + super(catalog_tbl, Long.MAX_VALUE, new int[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}); + + this.prices = + new Flat( + SEATSLoader.this.rng, + SEATSConstants.RESERVATION_PRICE_MIN, + SEATSConstants.RESERVATION_PRICE_MAX); + + // Flights per Airline + Collection all_airlines = SEATSLoader.this.profile.getAirlineCodes(); + Histogram histogram = new Histogram<>(); + histogram.putAll(all_airlines); + + // Embed a Gaussian distribution + Gaussian gauss_rng = new Gaussian(SEATSLoader.this.rng, 0, all_airlines.size()); + this.airlines = new FlatHistogram<>(gauss_rng, histogram); + + // Flights Per Airport + histogram = + SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); + this.airports = new FlatHistogram<>(SEATSLoader.this.rng, histogram); + for (String airport_code : histogram.values()) { + histogram = SEATSLoader.this.profile.getFightsPerAirportHistogram(airport_code); + + this.flights_per_airport.put( + airport_code, new FlatHistogram<>(SEATSLoader.this.rng, histogram)); + } + + // Flights Per Departure Time + histogram = + SEATSLoader.this.profile.getHistogram(SEATSConstants.HISTOGRAM_FLIGHTS_PER_DEPART_TIMES); + this.flight_times = new FlatHistogram<>(SEATSLoader.this.rng, histogram); + + // Figure out how many flights that we want for each day + this.today = new Timestamp(System.currentTimeMillis()); + + // Sometimes there are more flights per day, and sometimes there are + // fewer + Gaussian gaussian = + new Gaussian( + SEATSLoader.this.rng, + SEATSConstants.FLIGHTS_PER_DAY_MIN, + SEATSConstants.FLIGHTS_PER_DAY_MAX); + + this.total = 0; + boolean first = true; + for (long t = this.today.getTime() - (days_past * SEATSConstants.MILLISECONDS_PER_DAY); + t < this.today.getTime(); + t += SEATSConstants.MILLISECONDS_PER_DAY) { + Timestamp timestamp = new Timestamp(t); + if (first) { + this.start_date = timestamp; + first = false; } + int num_flights = gaussian.nextInt(); + this.flights_per_day.put(timestamp, num_flights); + this.total += num_flights; + } + if (this.start_date == null) { + this.start_date = this.today; + } + SEATSLoader.this.profile.setFlightStartDate(this.start_date); + + // This is for upcoming flights that we want to be able to schedule + // new reservations for in the benchmark + SEATSLoader.this.profile.setFlightUpcomingDate(this.today); + for (long t = this.today.getTime(), + last_date = + this.today.getTime() + (days_future * SEATSConstants.MILLISECONDS_PER_DAY); + t <= last_date; + t += SEATSConstants.MILLISECONDS_PER_DAY) { + Timestamp timestamp = new Timestamp(t); + int num_flights = gaussian.nextInt(); + this.flights_per_day.put(timestamp, num_flights); + this.total += num_flights; + } + + // Update profile + SEATSLoader.this.profile.setFlightPastDays(days_past); + SEATSLoader.this.profile.setFlightFutureDays(days_future); } - // ---------------------------------------------------------------- - // RESERVATIONS - // ---------------------------------------------------------------- - protected class ReservationIterable extends ScalingDataIterable { - private final RandomDistribution.Flat prices = new RandomDistribution.Flat(SEATSLoader.this.rng, SEATSConstants.RESERVATION_PRICE_MIN, SEATSConstants.RESERVATION_PRICE_MAX); - - /** - * For each airport id, store a list of ReturnFlight objects that - * represent customers that need return flights back to their home - * airport ArriveAirportId -> ReturnFlights - */ - private final Map> airport_returns = new HashMap<>(); - - /** - * When this flag is true, then the data generation thread is finished - */ - private boolean done = false; - - /** - * We use a Gaussian distribution for determining how long a customer - * will stay at their destination before needing to return to their - * original airport - */ - private final Gaussian rand_returns = new Gaussian(SEATSLoader.this.rng, SEATSConstants.CUSTOMER_RETURN_FLIGHT_DAYS_MIN, SEATSConstants.CUSTOMER_RETURN_FLIGHT_DAYS_MAX); - - private final LinkedBlockingDeque queue = new LinkedBlockingDeque<>(100); - private Object[] current = null; - private Throwable error = null; - - /** - * Constructor - * - * @param catalog_tbl - * @param total - */ - public ReservationIterable(Table catalog_tbl, long total) { - // Special Columns: R_C_ID, R_F_ID, R_F_AL_ID, R_SEAT, R_PRICE - super(catalog_tbl, total, new int[]{1, 2, 3, 4}); - - for (long airport_id : SEATSLoader.this.profile.getAirportIds()) { - // Return Flights per airport - this.airport_returns.put(airport_id, new TreeSet<>()); - } - - // Data Generation Thread - // Ok, hang on tight. We are going to fork off a separate thread to - // generate our tuples because it's easier than trying to pick up - // where we left off every time. That means that when hasNext() is - // called, it will block and poke this thread to start running. - // Once this thread has generate a new tuple, it will block - // itself and then poke the hasNext() thread. This is sort of - // like a hacky version of Python's yield - new Thread() { - @Override - public void run() { - try { - ReservationIterable.this.generateData(); - } catch (Throwable ex) { - // System.err.println("Airport Customers:\n" + - // getAirportCustomerHistogram()); - ReservationIterable.this.error = ex; - } finally { - if (LOG.isDebugEnabled()) { - LOG.debug("Reservation generation thread is finished"); - } - ReservationIterable.this.done = true; - } - } - }.start(); - } + /** + * Convert a time string "HH:MM" to a Timestamp object + * + * @param code + * @return + */ + private Timestamp convertTimeString(Timestamp base_date, String code) { + Matcher m = SEATSConstants.TIMECODE_PATTERN.matcher(code); + boolean result = m.find(); + assert result; + + int hour = -1; + try { + hour = Integer.valueOf(m.group(1)); + } catch (Throwable ex) { + throw new RuntimeException("Invalid HOUR in time code '" + code + "'", ex); + } + + int minute = -1; + try { + minute = Integer.valueOf(m.group(2)); + } catch (Throwable ex) { + throw new RuntimeException("Invalid MINUTE in time code '" + code + "'", ex); + } + + long offset = + (hour * 60 * SEATSConstants.MILLISECONDS_PER_MINUTE) + + (minute * SEATSConstants.MILLISECONDS_PER_MINUTE); + return (new Timestamp(base_date.getTime() + offset)); + } - private void generateData() throws Exception { - if (LOG.isDebugEnabled()) { - LOG.debug("Reservation data generation thread started"); - } + /** + * Select all the data elements for the current tuple + * + * @param date + */ + private void populate(Timestamp date) { + // Depart/Arrive Airports + this.depart_airport = this.airports.nextValue(); + this.arrive_airport = this.flights_per_airport.get(this.depart_airport).nextValue(); - Collection flight_customer_ids = new HashSet<>(); - Collection returning_customers = new ListOrderedSet<>(); - - // Loop through the flights and generate reservations - for (FlightId flight_id : SEATSLoader.this.getFlightIds()) { - long depart_airport_id = flight_id.getDepartAirportId(); - String depart_airport_code = SEATSLoader.this.profile.getAirportCode(depart_airport_id); - long arrive_airport_id = flight_id.getArriveAirportId(); - String arrive_airport_code = SEATSLoader.this.profile.getAirportCode(arrive_airport_id); - Timestamp depart_time = flight_id.getDepartDateAsTimestamp(SEATSLoader.this.profile.getFlightStartDate()); - Timestamp arrive_time = SEATSLoader.this.calculateArrivalTime(depart_airport_code, arrive_airport_code, depart_time); - flight_customer_ids.clear(); - - // For each flight figure out which customers are returning - this.getReturningCustomers(returning_customers, flight_id); - int booked_seats = SEATSConstants.FLIGHTS_NUM_SEATS - SEATSLoader.this.getFlightRemainingSeats(flight_id); - - if (LOG.isTraceEnabled()) { - Map m = new ListOrderedMap<>(); - m.put("Flight Id", flight_id + " / " + flight_id.encode()); - m.put("Departure", String.format("%s / %s", SEATSLoader.this.profile.getAirportCode(depart_airport_id), depart_time)); - m.put("Arrival", String.format("%s / %s", SEATSLoader.this.profile.getAirportCode(arrive_airport_id), arrive_time)); - m.put("Booked Seats", booked_seats); - m.put(String.format("Returning Customers[%d]", returning_customers.size()), StringUtil.join("\n", returning_customers)); - LOG.trace("Flight Information\n{}", StringUtil.formatMaps(m)); - } - - for (int seatnum = 0; seatnum < booked_seats; seatnum++) { - CustomerId customer_id = null; - Integer airport_customer_cnt = SEATSLoader.this.profile.getCustomerIdCount(depart_airport_id); - boolean local_customer = airport_customer_cnt != null && (flight_customer_ids.size() < airport_customer_cnt); - int tries = 2000; - ReturnFlight return_flight = null; - while (tries > 0) { - return_flight = null; - - // Always book returning customers first - if (!returning_customers.isEmpty()) { - return_flight = CollectionUtil.pop(returning_customers); - customer_id = return_flight.getCustomerId(); - } - // New Outbound Reservation - // Prefer to use a customer based out of the local - // airport - else if (local_customer) { - customer_id = SEATSLoader.this.profile.getRandomCustomerId(depart_airport_id); - } - // New Outbound Reservation - // We'll take anybody! - else { - customer_id = SEATSLoader.this.profile.getRandomCustomerId(); - } - if (!flight_customer_ids.contains(customer_id)) { - break; - } - tries--; - } - - - // If this is return flight, then there's nothing extra that - // we need to do - if (return_flight != null) { - if (LOG.isTraceEnabled()) { - LOG.trace("Booked return flight: {} [remaining={}]", return_flight, returning_customers.size()); - } - - // If it's a new outbound flight, then we will randomly - // decide when this customer will return (if at all) - } else { - if (SEATSLoader.this.rng.nextInt(100) < SEATSConstants.PROB_SINGLE_FLIGHT_RESERVATION) { - // Do nothing for now... - - // Create a ReturnFlight object to record that this - // customer needs a flight - // back to their original depart airport - } else { - int return_days = this.rand_returns.nextInt(); - return_flight = new ReturnFlight(customer_id, depart_airport_id, depart_time, return_days); - this.airport_returns.get(arrive_airport_id).add(return_flight); - } - } - - - flight_customer_ids.add(customer_id); - - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("New reservation ready. Adding to queue! [queueSize=%d]", this.queue.size())); - } - this.queue.put(new Object[]{customer_id, flight_id, seatnum}); - } - } - if (LOG.isDebugEnabled()) { - LOG.debug("Reservation data generation thread is finished"); - } - } + // Depart/Arrive Times + this.depart_time = this.convertTimeString(date, this.flight_times.nextValue()); + this.arrive_time = + SEATSLoader.this.calculateArrivalTime( + this.depart_airport, this.arrive_airport, this.depart_time); - /** - * Return a list of the customers that need to return to their original - * location on this particular flight. - * - * @param flight_id - * @return - */ - private void getReturningCustomers(Collection returning_customers, FlightId flight_id) { - Timestamp flight_date = flight_id.getDepartDateAsTimestamp(SEATSLoader.this.profile.getFlightStartDate()); - returning_customers.clear(); - Set returns = this.airport_returns.get(flight_id.getDepartAirportId()); - if (!returns.isEmpty()) { - for (ReturnFlight return_flight : returns) { - if (return_flight.getReturnDate().compareTo(flight_date) > 0) { - break; - } - if (return_flight.getReturnAirportId() == flight_id.getArriveAirportId()) { - returning_customers.add(return_flight); - } - } - if (!returning_customers.isEmpty()) { - returns.removeAll(returning_customers); - } - } - } + // Airline + this.airline_code = this.airlines.nextValue(); + this.airline_id = SEATSLoader.this.profile.getAirlineId(this.airline_code); - @Override - protected boolean hasNext() { - if (LOG.isTraceEnabled()) { - LOG.trace("hasNext() called"); - } - this.current = null; - while (!this.done || !this.queue.isEmpty()) { - if (this.error != null) { - throw new RuntimeException("Failed to generate Reservation records", this.error); - } - - try { - this.current = this.queue.poll(100, TimeUnit.MILLISECONDS); - } catch (InterruptedException ex) { - throw new RuntimeException("Unexpected interruption!", ex); - } - if (this.current != null) { - return (true); - } - if (LOG.isTraceEnabled()) { - LOG.trace("There were no new reservations. Let's try again!"); - } - } - return (false); - } + // Status + this.status = 0; // TODO - @Override - protected Object specialValue(long id, int columnIdx) { - - Object value = null; - switch (columnIdx) { - // CUSTOMER ID - case (1): { - value = ((CustomerId) this.current[0]).encode(); - break; - } - // FLIGHT ID - case (2): { - FlightId flight_id = (FlightId) this.current[1]; - value = flight_id.encode(); - if (SEATSLoader.this.profile.getReservationUpcomingOffset() == null && flight_id.isUpcoming(SEATSLoader.this.profile.getFlightStartDate(), SEATSLoader.this.profile.getFlightPastDays())) { - SEATSLoader.this.profile.setReservationUpcomingOffset(id); - } - break; - } - // SEAT - case (3): { - value = this.current[2]; - break; - } - // PRICE - case (4): { - value = (double) this.prices.nextInt(); - break; - } - // BAD MOJO! - default: + this.flights_per_day.put(date, this.flights_per_day.get(date) - 1); + } - } - return (value); - } + /** Returns true if this seat is occupied (which means we must generate a reservation) */ + boolean seatIsOccupied() { + return (SEATSLoader.this.rng.nextInt(100) < SEATSConstants.PROB_SEAT_OCCUPIED); } - // ----------------------------------------------------------------- - // FLIGHT IDS - // ----------------------------------------------------------------- - - public Iterable getFlightIds() { - return (new Iterable() { - @Override - public Iterator iterator() { - return (new Iterator() { - private int idx = 0; - private final int cnt = SEATSLoader.this.seats_remaining.size(); - - @Override - public boolean hasNext() { - return (this.idx < this.cnt); - } - - @Override - public FlightId next() { - return (SEATSLoader.this.seats_remaining.get(this.idx++)); - } - - @Override - public void remove() { - // Not implemented - } - }); + @Override + protected Object specialValue(long id, int columnIdx) { + Object value = null; + switch (columnIdx) { + // FLIGHT ID + case (0): + { + // Figure out what date we are currently on + Integer remaining = null; + Timestamp date; + do { + // Move to the next day. + // Make sure that we reset the set of FlightIds that + // we've used for today + if (remaining != null) { + this.todays_flights.clear(); + this.day_idx++; + } + date = this.flights_per_day.get(this.day_idx); + remaining = this.flights_per_day.getValue(this.day_idx); + } while (remaining <= 0 && this.day_idx + 1 < this.flights_per_day.size()); + + // Keep looping until we get a FlightId that we haven't seen + // yet for this date + while (true) { + this.populate(date); + + // Generate a composite FlightId + this.flight_id = + new FlightId( + this.airline_id, + SEATSLoader.this.profile.getAirportId(this.depart_airport), + SEATSLoader.this.profile.getAirportId(this.arrive_airport), + this.start_date, + this.depart_time); + if (!this.todays_flights.contains(this.flight_id)) { + break; + } } - }); + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "%s [remaining=%d, dayIdx=%d]", this.flight_id, remaining, this.day_idx)); + } + + this.todays_flights.add(this.flight_id); + SEATSLoader.this.addFlightId(this.flight_id); + value = this.flight_id.encode(); + break; + } + // AIRLINE ID + case (1): + { + value = this.airline_code; + SEATSLoader.this.flights_per_airline.put(this.airline_code); + break; + } + // DEPART AIRPORT + case (2): + { + value = this.depart_airport; + break; + } + // DEPART TIME + case (3): + { + value = this.depart_time; + break; + } + // ARRIVE AIRPORT + case (4): + { + value = this.arrive_airport; + break; + } + // ARRIVE TIME + case (5): + { + value = this.arrive_time; + break; + } + // FLIGHT STATUS + case (6): + { + value = this.status; + break; + } + // BASE PRICE + case (7): + { + value = (double) this.prices.nextInt(); + break; + } + // SEATS TOTAL + case (8): + { + value = SEATSConstants.FLIGHTS_NUM_SEATS; + break; + } + // SEATS REMAINING + case (9): + { + // We have to figure this out ahead of time since we need to + // populate the tuple now + for (int seatnum = 0; seatnum < SEATSConstants.FLIGHTS_NUM_SEATS; seatnum++) { + if (!this.seatIsOccupied()) { + continue; + } + SEATSLoader.this.decrementFlightSeat(this.flight_id); + } + value = (long) SEATSLoader.this.getFlightRemainingSeats(this.flight_id); + if (LOG.isTraceEnabled()) { + LOG.trace("{} SEATS REMAINING: {}", this.flight_id, value); + } + break; + } + // BAD MOJO! + default: + } + return (value); } + } + + // ---------------------------------------------------------------- + // RESERVATIONS + // ---------------------------------------------------------------- + protected class ReservationIterable extends ScalingDataIterable { + private final RandomDistribution.Flat prices = + new RandomDistribution.Flat( + SEATSLoader.this.rng, + SEATSConstants.RESERVATION_PRICE_MIN, + SEATSConstants.RESERVATION_PRICE_MAX); /** - * @param flight_id + * For each airport id, store a list of ReturnFlight objects that represent customers that need + * return flights back to their home airport ArriveAirportId -> ReturnFlights */ - public boolean addFlightId(FlightId flight_id) { + private final Map> airport_returns = new HashMap<>(); + /** When this flag is true, then the data generation thread is finished */ + private boolean done = false; - this.profile.addFlightId(flight_id); - this.seats_remaining.put(flight_id, (short) SEATSConstants.FLIGHTS_NUM_SEATS); + /** + * We use a Gaussian distribution for determining how long a customer will stay at their + * destination before needing to return to their original airport + */ + private final Gaussian rand_returns = + new Gaussian( + SEATSLoader.this.rng, + SEATSConstants.CUSTOMER_RETURN_FLIGHT_DAYS_MIN, + SEATSConstants.CUSTOMER_RETURN_FLIGHT_DAYS_MAX); - // XXX - if (this.profile.flight_upcoming_offset == null && this.profile.flight_upcoming_date.compareTo(flight_id.getDepartDateAsTimestamp(this.profile.flight_start_date)) < 0) { - this.profile.flight_upcoming_offset = (long) (this.seats_remaining.size() - 1); - } - return (true); - } + private final LinkedBlockingDeque queue = new LinkedBlockingDeque<>(100); + private Object[] current = null; + private Throwable error = null; /** - * Return the number of unique flight ids + * Constructor * - * @return + * @param catalog_tbl + * @param total */ - public long getFlightIdCount() { - return (this.seats_remaining.size()); + public ReservationIterable(Table catalog_tbl, long total) { + // Special Columns: R_C_ID, R_F_ID, R_F_AL_ID, R_SEAT, R_PRICE + super(catalog_tbl, total, new int[] {1, 2, 3, 4}); + + for (long airport_id : SEATSLoader.this.profile.getAirportIds()) { + // Return Flights per airport + this.airport_returns.put(airport_id, new TreeSet<>()); + } + + // Data Generation Thread + // Ok, hang on tight. We are going to fork off a separate thread to + // generate our tuples because it's easier than trying to pick up + // where we left off every time. That means that when hasNext() is + // called, it will block and poke this thread to start running. + // Once this thread has generate a new tuple, it will block + // itself and then poke the hasNext() thread. This is sort of + // like a hacky version of Python's yield + new Thread() { + @Override + public void run() { + try { + ReservationIterable.this.generateData(); + } catch (Throwable ex) { + // System.err.println("Airport Customers:\n" + + // getAirportCustomerHistogram()); + ReservationIterable.this.error = ex; + } finally { + if (LOG.isDebugEnabled()) { + LOG.debug("Reservation generation thread is finished"); + } + ReservationIterable.this.done = true; + } + } + }.start(); } - /** - * Return the index offset of when future flights - * - * @return - */ - public long getFlightIdStartingOffset() { - return (this.profile.flight_upcoming_offset); + private void generateData() throws Exception { + if (LOG.isDebugEnabled()) { + LOG.debug("Reservation data generation thread started"); + } + + Collection flight_customer_ids = new HashSet<>(); + Collection returning_customers = new ListOrderedSet<>(); + + // Loop through the flights and generate reservations + for (FlightId flight_id : SEATSLoader.this.getFlightIds()) { + long depart_airport_id = flight_id.getDepartAirportId(); + String depart_airport_code = SEATSLoader.this.profile.getAirportCode(depart_airport_id); + long arrive_airport_id = flight_id.getArriveAirportId(); + String arrive_airport_code = SEATSLoader.this.profile.getAirportCode(arrive_airport_id); + Timestamp depart_time = + flight_id.getDepartDateAsTimestamp(SEATSLoader.this.profile.getFlightStartDate()); + Timestamp arrive_time = + SEATSLoader.this.calculateArrivalTime( + depart_airport_code, arrive_airport_code, depart_time); + flight_customer_ids.clear(); + + // For each flight figure out which customers are returning + this.getReturningCustomers(returning_customers, flight_id); + int booked_seats = + SEATSConstants.FLIGHTS_NUM_SEATS - SEATSLoader.this.getFlightRemainingSeats(flight_id); + + if (LOG.isTraceEnabled()) { + Map m = new ListOrderedMap<>(); + m.put("Flight Id", flight_id + " / " + flight_id.encode()); + m.put( + "Departure", + String.format( + "%s / %s", + SEATSLoader.this.profile.getAirportCode(depart_airport_id), depart_time)); + m.put( + "Arrival", + String.format( + "%s / %s", + SEATSLoader.this.profile.getAirportCode(arrive_airport_id), arrive_time)); + m.put("Booked Seats", booked_seats); + m.put( + String.format("Returning Customers[%d]", returning_customers.size()), + StringUtil.join("\n", returning_customers)); + LOG.trace("Flight Information\n{}", StringUtil.formatMaps(m)); + } + + for (int seatnum = 0; seatnum < booked_seats; seatnum++) { + CustomerId customer_id = null; + Integer airport_customer_cnt = + SEATSLoader.this.profile.getCustomerIdCount(depart_airport_id); + boolean local_customer = + airport_customer_cnt != null && (flight_customer_ids.size() < airport_customer_cnt); + int tries = 2000; + ReturnFlight return_flight = null; + while (tries > 0) { + return_flight = null; + + // Always book returning customers first + if (!returning_customers.isEmpty()) { + return_flight = CollectionUtil.pop(returning_customers); + customer_id = return_flight.getCustomerId(); + } + // New Outbound Reservation + // Prefer to use a customer based out of the local + // airport + else if (local_customer) { + customer_id = SEATSLoader.this.profile.getRandomCustomerId(depart_airport_id); + } + // New Outbound Reservation + // We'll take anybody! + else { + customer_id = SEATSLoader.this.profile.getRandomCustomerId(); + } + if (!flight_customer_ids.contains(customer_id)) { + break; + } + tries--; + } + + // If this is return flight, then there's nothing extra that + // we need to do + if (return_flight != null) { + if (LOG.isTraceEnabled()) { + LOG.trace( + "Booked return flight: {} [remaining={}]", + return_flight, + returning_customers.size()); + } + + // If it's a new outbound flight, then we will randomly + // decide when this customer will return (if at all) + } else { + if (SEATSLoader.this.rng.nextInt(100) < SEATSConstants.PROB_SINGLE_FLIGHT_RESERVATION) { + // Do nothing for now... + + // Create a ReturnFlight object to record that this + // customer needs a flight + // back to their original depart airport + } else { + int return_days = this.rand_returns.nextInt(); + return_flight = + new ReturnFlight(customer_id, depart_airport_id, depart_time, return_days); + this.airport_returns.get(arrive_airport_id).add(return_flight); + } + } + + flight_customer_ids.add(customer_id); + + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "New reservation ready. Adding to queue! [queueSize=%d]", this.queue.size())); + } + this.queue.put(new Object[] {customer_id, flight_id, seatnum}); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("Reservation data generation thread is finished"); + } } /** - * Return the number of seats remaining for a flight + * Return a list of the customers that need to return to their original location on this + * particular flight. * * @param flight_id * @return */ - public int getFlightRemainingSeats(FlightId flight_id) { - return (this.seats_remaining.get(flight_id)); - } - - /** - * Decrement the number of available seats for a flight and return the total - * amount remaining - */ - public int decrementFlightSeat(FlightId flight_id) { - Short seats = this.seats_remaining.get(flight_id); - - - return (this.seats_remaining.put(flight_id, (short) (seats - 1))); + private void getReturningCustomers( + Collection returning_customers, FlightId flight_id) { + Timestamp flight_date = + flight_id.getDepartDateAsTimestamp(SEATSLoader.this.profile.getFlightStartDate()); + returning_customers.clear(); + Set returns = this.airport_returns.get(flight_id.getDepartAirportId()); + if (!returns.isEmpty()) { + for (ReturnFlight return_flight : returns) { + if (return_flight.getReturnDate().compareTo(flight_date) > 0) { + break; + } + if (return_flight.getReturnAirportId() == flight_id.getArriveAirportId()) { + returning_customers.add(return_flight); + } + } + if (!returning_customers.isEmpty()) { + returns.removeAll(returning_customers); + } + } } - // ---------------------------------------------------------------- - // DISTANCE METHODS - // ---------------------------------------------------------------- + @Override + protected boolean hasNext() { + if (LOG.isTraceEnabled()) { + LOG.trace("hasNext() called"); + } + this.current = null; + while (!this.done || !this.queue.isEmpty()) { + if (this.error != null) { + throw new RuntimeException("Failed to generate Reservation records", this.error); + } - public void setDistance(String airport0, String airport1, double distance) { - short short_distance = (short) Math.round(distance); - for (String[] a : new String[][]{{airport0, airport1}, {airport1, airport0}}) { - if (!this.airport_distances.containsKey(a[0])) { - this.airport_distances.put(a[0], new HashMap<>()); - } - this.airport_distances.get(a[0]).put(a[1], short_distance); + try { + this.current = this.queue.poll(100, TimeUnit.MILLISECONDS); + } catch (InterruptedException ex) { + throw new RuntimeException("Unexpected interruption!", ex); + } + if (this.current != null) { + return (true); + } + if (LOG.isTraceEnabled()) { + LOG.trace("There were no new reservations. Let's try again!"); } + } + return (false); } - public Integer getDistance(String airport0, String airport1) { - - - return ((int) this.airport_distances.get(airport0).get(airport1)); + @Override + protected Object specialValue(long id, int columnIdx) { + + Object value = null; + switch (columnIdx) { + // CUSTOMER ID + case (1): + { + value = ((CustomerId) this.current[0]).encode(); + break; + } + // FLIGHT ID + case (2): + { + FlightId flight_id = (FlightId) this.current[1]; + value = flight_id.encode(); + if (SEATSLoader.this.profile.getReservationUpcomingOffset() == null + && flight_id.isUpcoming( + SEATSLoader.this.profile.getFlightStartDate(), + SEATSLoader.this.profile.getFlightPastDays())) { + SEATSLoader.this.profile.setReservationUpcomingOffset(id); + } + break; + } + // SEAT + case (3): + { + value = this.current[2]; + break; + } + // PRICE + case (4): + { + value = (double) this.prices.nextInt(); + break; + } + // BAD MOJO! + default: + } + return (value); } - - /** - * For the current depart+arrive airport destinations, calculate the - * estimated flight time and then add the to the departure time in order to - * come up with the expected arrival time. - * - * @param depart_airport - * @param arrive_airport - * @param depart_time - * @return - */ - public Timestamp calculateArrivalTime(String depart_airport, String arrive_airport, Timestamp depart_time) { - Integer distance = this.getDistance(depart_airport, arrive_airport); - - long flight_time = Math.round(distance / SEATSConstants.FLIGHT_TRAVEL_RATE) * 3600000000L; - // 60 sec * 60 min * 1,000,000 - return (new Timestamp(depart_time.getTime() + flight_time)); + } + + // ----------------------------------------------------------------- + // FLIGHT IDS + // ----------------------------------------------------------------- + + public Iterable getFlightIds() { + return (new Iterable() { + @Override + public Iterator iterator() { + return (new Iterator() { + private int idx = 0; + private final int cnt = SEATSLoader.this.seats_remaining.size(); + + @Override + public boolean hasNext() { + return (this.idx < this.cnt); + } + + @Override + public FlightId next() { + return (SEATSLoader.this.seats_remaining.get(this.idx++)); + } + + @Override + public void remove() { + // Not implemented + } + }); + } + }); + } + + /** + * @param flight_id + */ + public boolean addFlightId(FlightId flight_id) { + + this.profile.addFlightId(flight_id); + this.seats_remaining.put(flight_id, (short) SEATSConstants.FLIGHTS_NUM_SEATS); + + // XXX + if (this.profile.flight_upcoming_offset == null + && this.profile.flight_upcoming_date.compareTo( + flight_id.getDepartDateAsTimestamp(this.profile.flight_start_date)) + < 0) { + this.profile.flight_upcoming_offset = (long) (this.seats_remaining.size() - 1); + } + return (true); + } + + /** + * Return the number of unique flight ids + * + * @return + */ + public long getFlightIdCount() { + return (this.seats_remaining.size()); + } + + /** + * Return the index offset of when future flights + * + * @return + */ + public long getFlightIdStartingOffset() { + return (this.profile.flight_upcoming_offset); + } + + /** + * Return the number of seats remaining for a flight + * + * @param flight_id + * @return + */ + public int getFlightRemainingSeats(FlightId flight_id) { + return (this.seats_remaining.get(flight_id)); + } + + /** Decrement the number of available seats for a flight and return the total amount remaining */ + public int decrementFlightSeat(FlightId flight_id) { + Short seats = this.seats_remaining.get(flight_id); + + return (this.seats_remaining.put(flight_id, (short) (seats - 1))); + } + + // ---------------------------------------------------------------- + // DISTANCE METHODS + // ---------------------------------------------------------------- + + public void setDistance(String airport0, String airport1, double distance) { + short short_distance = (short) Math.round(distance); + for (String[] a : new String[][] {{airport0, airport1}, {airport1, airport0}}) { + if (!this.airport_distances.containsKey(a[0])) { + this.airport_distances.put(a[0], new HashMap<>()); + } + this.airport_distances.get(a[0]).put(a[1], short_distance); } -} \ No newline at end of file + } + + public Integer getDistance(String airport0, String airport1) { + + return ((int) this.airport_distances.get(airport0).get(airport1)); + } + + /** + * For the current depart+arrive airport destinations, calculate the estimated flight time and + * then add the to the departure time in order to come up with the expected arrival time. + * + * @param depart_airport + * @param arrive_airport + * @param depart_time + * @return + */ + public Timestamp calculateArrivalTime( + String depart_airport, String arrive_airport, Timestamp depart_time) { + Integer distance = this.getDistance(depart_airport, arrive_airport); + + long flight_time = Math.round(distance / SEATSConstants.FLIGHT_TRAVEL_RATE) * 3600000000L; + // 60 sec * 60 min * 1,000,000 + return (new Timestamp(depart_time.getTime() + flight_time)); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java index b58946bee..f02315272 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSProfile.java @@ -25,735 +25,725 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.*; import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; -import org.apache.commons.collections4.map.ListOrderedMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.util.*; import java.util.Map.Entry; +import org.apache.commons.collections4.map.ListOrderedMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class SEATSProfile { - private static final Logger LOG = LoggerFactory.getLogger(SEATSProfile.class); - - // ---------------------------------------------------------------- - // PERSISTENT DATA MEMBERS - // ---------------------------------------------------------------- - - /** - * Data Scale Factor - */ - protected double scale_factor; - /** - * For each airport id, store the last id of the customer that uses this - * airport as their local airport. The customer ids will be stored as - * follows in the dbms: <16-bit AirportId><48-bit CustomerId> - */ - protected final Histogram airport_max_customer_id = new Histogram<>(); - /** - * The date when flights total data set begins - */ - protected final Timestamp flight_start_date = new Timestamp(0); - /** - * The date for when the flights are considered upcoming and are eligible - * for reservations - */ - protected Timestamp flight_upcoming_date; - /** - * The number of days in the past that our flight data set includes. - */ - protected long flight_past_days; - /** - * The number of days in the future (from the flight_upcoming_date) that our - * flight data set includes - */ - protected long flight_future_days; - /** - * The offset of when upcoming flights begin in the seats_remaining list - */ - protected Long flight_upcoming_offset = null; - /** - * The offset of when reservations for upcoming flights begin - */ - protected Long reservation_upcoming_offset = null; - /** - * The number of reservations initially created. - */ - protected long num_reservations = 0L; - - /** - * TODO - **/ - protected final Map> histograms = new HashMap<>(); - - /** - * Each AirportCode will have a histogram of the number of flights that - * depart from that airport to all the other airports - */ - protected final Map> airport_histograms = new HashMap<>(); - - protected final Map> code_id_xref = new HashMap<>(); - - // ---------------------------------------------------------------- - // TRANSIENT DATA MEMBERS - // ---------------------------------------------------------------- - - protected final SEATSBenchmark benchmark; - - /** - * We want to maintain a small cache of FlightIds so that the SEATSClient - * has something to work with. We obviously don't want to store the entire - * set here - */ - protected transient final LinkedList cached_flight_ids = new LinkedList<>(); - - /** - * Key -> Id Mappings - */ - protected transient final Map code_columns = new HashMap<>(); - - /** - * Foreign Key Mappings Column Name -> Xref Mapper - */ - protected transient final Map fkey_value_xref = new HashMap<>(); - - /** - * Data Directory - */ - protected transient final String airline_data_dir; - - /** - * Specialized random number generator - */ - protected transient final RandomGenerator rng; - - /** - * Depart Airport Code -> Arrive Airport Code Random number generators based - * on the flight distributions - */ - private final Map> airport_distributions = new HashMap<>(); - - // ---------------------------------------------------------------- - // CONSTRUCTOR - // ---------------------------------------------------------------- - - public SEATSProfile(SEATSBenchmark benchmark, RandomGenerator rng) { - this.benchmark = benchmark; - this.rng = rng; - this.airline_data_dir = benchmark.getDataDir(); - - // Tuple Code to Tuple Id Mapping - for (String[] xref : SEATSConstants.CODE_TO_ID_COLUMNS) { - - String tableName = xref[0]; - String codeCol = xref[1]; - String idCol = xref[2]; - - if (!this.code_columns.containsKey(codeCol)) { - this.code_columns.put(codeCol, idCol); - this.code_id_xref.put(idCol, new HashMap<>()); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Added %s mapping from Code Column '%s' to Id Column '%s'", tableName, codeCol, idCol)); - } - } - } + private static final Logger LOG = LoggerFactory.getLogger(SEATSProfile.class); + // ---------------------------------------------------------------- + // PERSISTENT DATA MEMBERS + // ---------------------------------------------------------------- - // In this data structure, the key will be the name of the dependent - // column and the value will be the name of the foreign key parent - // column. We then use this in conjunction with the Key->Id mapping - // to turn a code into a foreign key column id. For example, if the - // child table AIRPORT has a column with a foreign key reference to - // COUNTRY.CO_ID, then the data file for AIRPORT will have a value - // 'USA' in the AP_CO_ID column. We can use mapping to get the id number - // for 'USA'. Long winded and kind of screwy, but hey what else are - // you going to do? - for (Table catalog_tbl : benchmark.getCatalog().getTables()) { - for (Column catalog_col : catalog_tbl.getColumns()) { - Column catalog_fkey_col = catalog_col.getForeignKey(); - if (catalog_fkey_col != null && this.code_id_xref.containsKey(catalog_fkey_col.getName().toLowerCase())) { - this.fkey_value_xref.put(catalog_col.getName().toLowerCase(), catalog_fkey_col.getName().toLowerCase()); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Added ForeignKey mapping from %s to %s", catalog_col.getName().toLowerCase(), catalog_fkey_col.getName().toLowerCase())); - } - } - } - } + /** Data Scale Factor */ + protected double scale_factor; - } + /** + * For each airport id, store the last id of the customer that uses this airport as their local + * airport. The customer ids will be stored as follows in the dbms: <16-bit AirportId><48-bit + * CustomerId> + */ + protected final Histogram airport_max_customer_id = new Histogram<>(); - // ---------------------------------------------------------------- - // SAVE / LOAD PROFILE - // ---------------------------------------------------------------- - - /** - * Save the profile information into the database - */ - protected final void saveProfile(Connection conn) throws SQLException { - - // CONFIG_PROFILE - Table profileTable = benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_CONFIG_PROFILE); - String profileSql = SQLUtil.getInsertSQL(profileTable, this.benchmark.getWorkloadConfiguration().getDatabaseType()); - - try (PreparedStatement stmt = conn.prepareStatement(profileSql)) { - int param_idx = 1; - stmt.setObject(param_idx++, this.scale_factor); // CFP_SCALE_FACTOR - stmt.setObject(param_idx++, this.airport_max_customer_id.toJSONString()); // CFP_AIPORT_MAX_CUSTOMER - stmt.setObject(param_idx++, this.flight_start_date); // CFP_FLIGHT_START - stmt.setObject(param_idx++, this.flight_upcoming_date); // CFP_FLIGHT_UPCOMING - stmt.setObject(param_idx++, this.flight_past_days); // CFP_FLIGHT_PAST_DAYS - stmt.setObject(param_idx++, this.flight_future_days); // CFP_FLIGHT_FUTURE_DAYS - stmt.setObject(param_idx++, this.flight_upcoming_offset); // CFP_FLIGHT_OFFSET - stmt.setObject(param_idx++, this.reservation_upcoming_offset); // CFP_RESERVATION_OFFSET - stmt.setObject(param_idx++, this.num_reservations); // CFP_NUM_RESERVATIONS - stmt.setObject(param_idx, JSONUtil.toJSONString(this.code_id_xref)); // CFP_CODE_ID_XREF - stmt.executeUpdate(); - - if (LOG.isDebugEnabled()) { - LOG.debug("Saved profile information into {}", profileTable.getName()); - } - } + /** The date when flights total data set begins */ + protected final Timestamp flight_start_date = new Timestamp(0); - // CONFIG_HISTOGRAMS - Table histogramsTable = benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS); - String histogramSql = SQLUtil.getInsertSQL(histogramsTable, this.benchmark.getWorkloadConfiguration().getDatabaseType()); - try (PreparedStatement stmt = conn.prepareStatement(histogramSql)) { - for (Entry> e : this.airport_histograms.entrySet()) { - int param_idx = 1; - stmt.setObject(param_idx++, e.getKey()); // CFH_NAME - stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA - stmt.setObject(param_idx, 1); // CFH_IS_AIRPORT - stmt.executeUpdate(); - - } - if (LOG.isDebugEnabled()) { - LOG.debug("Saved airport histogram information into {}", histogramsTable.getName()); - } - - for (Entry> e : this.histograms.entrySet()) { - int param_idx = 1; - stmt.setObject(param_idx++, e.getKey()); // CFH_NAME - stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA - stmt.setObject(param_idx, 0); // CFH_IS_AIRPORT - stmt.executeUpdate(); - - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Saved benchmark histogram information into {}", histogramsTable.getName()); - } - } + /** The date for when the flights are considered upcoming and are eligible for reservations */ + protected Timestamp flight_upcoming_date; - } + /** The number of days in the past that our flight data set includes. */ + protected long flight_past_days; - protected static void clearCachedProfile() { - cachedProfile = null; - } + /** + * The number of days in the future (from the flight_upcoming_date) that our flight data set + * includes + */ + protected long flight_future_days; - private SEATSProfile copy(SEATSProfile other) { - this.scale_factor = other.scale_factor; - this.airport_max_customer_id.putHistogram(other.airport_max_customer_id); - this.flight_start_date.setTime(other.flight_start_date.getTime()); - this.flight_upcoming_date = other.flight_upcoming_date; - this.flight_past_days = other.flight_past_days; - this.flight_future_days = other.flight_future_days; - this.flight_upcoming_offset = other.flight_upcoming_offset; - this.reservation_upcoming_offset = other.reservation_upcoming_offset; - this.num_reservations = other.num_reservations; - this.code_id_xref.putAll(other.code_id_xref); - this.cached_flight_ids.addAll(other.cached_flight_ids); - this.airport_histograms.putAll(other.airport_histograms); - this.histograms.putAll(other.histograms); - return (this); - } + /** The offset of when upcoming flights begin in the seats_remaining list */ + protected Long flight_upcoming_offset = null; - /** - * Load the profile information stored in the database - */ - private static SEATSProfile cachedProfile; + /** The offset of when reservations for upcoming flights begin */ + protected Long reservation_upcoming_offset = null; - protected final void loadProfile(SEATSWorker worker) throws SQLException { - synchronized (SEATSProfile.class) { - // Check whether we have a cached Profile we can copy from - if (cachedProfile != null) { - if (LOG.isDebugEnabled()) { - LOG.debug("Using cached SEATSProfile"); - } - this.copy(cachedProfile); - return; - } + /** The number of reservations initially created. */ + protected long num_reservations = 0L; - if (LOG.isDebugEnabled()) { - LOG.debug("Loading SEATSProfile for the first time"); - } + /** TODO */ + protected final Map> histograms = new HashMap<>(); - // Otherwise we have to go fetch everything again - LoadConfig proc = worker.getProcedure(LoadConfig.class); + /** + * Each AirportCode will have a histogram of the number of flights that depart from that airport + * to all the other airports + */ + protected final Map> airport_histograms = new HashMap<>(); - Config results; - try (Connection conn = benchmark.makeConnection()) { - results = proc.run(conn); - } - // CONFIG_PROFILE - this.loadConfigProfile(results.getConfigProfile()); + protected final Map> code_id_xref = new HashMap<>(); - // CONFIG_HISTOGRAMS - this.loadConfigHistograms(results.getConfigHistogram()); + // ---------------------------------------------------------------- + // TRANSIENT DATA MEMBERS + // ---------------------------------------------------------------- + protected final SEATSBenchmark benchmark; - this.loadCodeXref(results.getCountryCodes(), SEATSConstants.COUNTRY_CODE, SEATSConstants.COUNTRY_ID); - this.loadCodeXref(results.getAirportCodes(), SEATSConstants.AIRPORT_CODE, SEATSConstants.AIRPORT_ID); - this.loadCodeXref(results.getAirlineCodes(), SEATSConstants.AIRLINE_IATA_CODE, SEATSConstants.AIRLINE_ID); + /** + * We want to maintain a small cache of FlightIds so that the SEATSClient has something to work + * with. We obviously don't want to store the entire set here + */ + protected final transient LinkedList cached_flight_ids = new LinkedList<>(); - // CACHED FLIGHT IDS - this.loadCachedFlights(results.getFlights()); + /** Key -> Id Mappings */ + protected final transient Map code_columns = new HashMap<>(); + /** Foreign Key Mappings Column Name -> Xref Mapper */ + protected final transient Map fkey_value_xref = new HashMap<>(); - if (LOG.isDebugEnabled()) { - LOG.debug("Loaded profile:\n{}", this); - } - if (LOG.isTraceEnabled()) { - LOG.trace("Airport Max Customer Id:\n{}", this.airport_max_customer_id); - } + /** Data Directory */ + protected final transient String airline_data_dir; - cachedProfile = new SEATSProfile(this.benchmark, this.rng).copy(this); - } - } + /** Specialized random number generator */ + protected final transient RandomGenerator rng; - private void loadConfigProfile(List vt) { - for (Object[] row : vt) { - this.scale_factor = SQLUtil.getDouble(row[0]); - JSONUtil.fromJSONString(this.airport_max_customer_id, SQLUtil.getString(row[1])); - this.flight_start_date.setTime(SQLUtil.getTimestamp(row[2]).getTime()); - this.flight_upcoming_date = SQLUtil.getTimestamp(row[3]); - this.flight_past_days = SQLUtil.getLong(row[4]); - this.flight_future_days = SQLUtil.getLong(row[5]); - this.flight_upcoming_offset = SQLUtil.getLong(row[6]); - this.reservation_upcoming_offset = SQLUtil.getLong(row[7]); - this.num_reservations = SQLUtil.getLong(row[8]); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %s data", SEATSConstants.TABLENAME_CONFIG_PROFILE)); - } - } + /** + * Depart Airport Code -> Arrive Airport Code Random number generators based on the flight + * distributions + */ + private final Map> airport_distributions = new HashMap<>(); - private void loadConfigHistograms(List vt) { - for (Object[] row : vt) { - String name = SQLUtil.getString(row[0]); - Histogram h = JSONUtil.fromJSONString(new Histogram<>(), SQLUtil.getString(row[1])); - boolean is_airline = (SQLUtil.getLong(row[2]) == 1); - - if (is_airline) { - this.airport_histograms.put(name, h); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Loaded %d records for %s airport histogram", h.getValueCount(), name)); - } - } else { - this.histograms.put(name, h); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Loaded %d records for %s histogram", h.getValueCount(), name)); - } - } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %s data", SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS)); - } - } + // ---------------------------------------------------------------- + // CONSTRUCTOR + // ---------------------------------------------------------------- - private void loadCodeXref(List vt, String codeCol, String idCol) { - Map m = this.code_id_xref.get(idCol); - for (Object[] row : vt) { - long id = SQLUtil.getLong(row[0]); - String code = SQLUtil.getString(row[1]); - m.put(code, id); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d xrefs for %s -> %s", m.size(), codeCol, idCol)); - } - } + public SEATSProfile(SEATSBenchmark benchmark, RandomGenerator rng) { + this.benchmark = benchmark; + this.rng = rng; + this.airline_data_dir = benchmark.getDataDir(); - private void loadCachedFlights(List vt) { - int limit = 1; - Iterator iterator = vt.iterator(); - while (iterator.hasNext() && limit++ < SEATSConstants.CACHE_LIMIT_FLIGHT_IDS) { - Object[] row = iterator.next(); - String f_id = SQLUtil.getString(row[0]); - FlightId flight_id = new FlightId(f_id); - this.cached_flight_ids.add(flight_id); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Loaded %d cached FlightIds", this.cached_flight_ids.size())); - } - } - - // ---------------------------------------------------------------- - // DATA ACCESS METHODS - // ---------------------------------------------------------------- - - private Map getCodeXref(String col_name) { - - - return (this.code_id_xref.get(col_name)); - } - - /** - * The offset of when upcoming reservation ids begin - * - * @return - */ - public Long getReservationUpcomingOffset() { - return (this.reservation_upcoming_offset); - } - - /** - * Set the number of upcoming reservation offset - * - * @param offset - */ - public void setReservationUpcomingOffset(long offset) { - this.reservation_upcoming_offset = offset; - } - - // ----------------------------------------------------------------- - // FLIGHTS - // ----------------------------------------------------------------- - - /** - * Add a new FlightId for this benchmark instance This method will decide - * whether to store the id or not in its cache - * - * @return True if the FlightId was added to the cache - */ - public boolean addFlightId(FlightId flight_id) { - boolean added = false; - synchronized (this.cached_flight_ids) { - // If we have room, shove it right in - // We'll throw it in the back because we know it hasn't been used - // yet - if (this.cached_flight_ids.size() < SEATSConstants.CACHE_LIMIT_FLIGHT_IDS) { - this.cached_flight_ids.addLast(flight_id); - added = true; - - // Otherwise, we can will randomly decide whether to pop one out - } else if (this.rng.nextBoolean()) { - this.cached_flight_ids.pop(); - this.cached_flight_ids.addLast(flight_id); - added = true; - } - } - return (added); - } - - public long getFlightIdCount() { - return (this.cached_flight_ids.size()); - } - - // ---------------------------------------------------------------- - // HISTOGRAM METHODS - // ---------------------------------------------------------------- + // Tuple Code to Tuple Id Mapping + for (String[] xref : SEATSConstants.CODE_TO_ID_COLUMNS) { - /** - * Return the histogram for the given name - * - * @param name - * @return - */ - public Histogram getHistogram(String name) { + String tableName = xref[0]; + String codeCol = xref[1]; + String idCol = xref[2]; - return (this.histograms.get(name)); - } - - /** - * @param airport_code - * @return - */ - public Histogram getFightsPerAirportHistogram(String airport_code) { - return (this.airport_histograms.get(airport_code)); - } - - /** - * Returns the number of histograms that we have loaded Does not include the - * airport_histograms - * - * @return - */ - public int getHistogramCount() { - return (this.histograms.size()); - } - - // ---------------------------------------------------------------- - // RANDOM GENERATION METHODS - // ---------------------------------------------------------------- - - /** - * Return a random airport id - * - * @return - */ - public long getRandomAirportId() { - return (this.rng.number(1, this.getAirportCount())); - } - - public long getRandomOtherAirport(long airport_id) { - String code = this.getAirportCode(airport_id); - FlatHistogram f = this.airport_distributions.get(code); - if (f == null) { - synchronized (this.airport_distributions) { - f = this.airport_distributions.get(code); - if (f == null) { - Histogram h = this.airport_histograms.get(code); - - f = new FlatHistogram<>(this.rng, h); - this.airport_distributions.put(code, f); - } - } + if (!this.code_columns.containsKey(codeCol)) { + this.code_columns.put(codeCol, idCol); + this.code_id_xref.put(idCol, new HashMap<>()); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Added %s mapping from Code Column '%s' to Id Column '%s'", + tableName, codeCol, idCol)); } - - String other = f.nextValue(); - return this.getAirportId(other); - } - - /** - * Return a random customer id based at the given airport_id - * - * @param airport_id - * @return - */ - public CustomerId getRandomCustomerId(Long airport_id) { - Integer cnt = this.getCustomerIdCount(airport_id); - if (cnt != null) { - int base_id = this.rng.nextInt(cnt); - return (new CustomerId(base_id, airport_id)); + } + } + + // In this data structure, the key will be the name of the dependent + // column and the value will be the name of the foreign key parent + // column. We then use this in conjunction with the Key->Id mapping + // to turn a code into a foreign key column id. For example, if the + // child table AIRPORT has a column with a foreign key reference to + // COUNTRY.CO_ID, then the data file for AIRPORT will have a value + // 'USA' in the AP_CO_ID column. We can use mapping to get the id number + // for 'USA'. Long winded and kind of screwy, but hey what else are + // you going to do? + for (Table catalog_tbl : benchmark.getCatalog().getTables()) { + for (Column catalog_col : catalog_tbl.getColumns()) { + Column catalog_fkey_col = catalog_col.getForeignKey(); + if (catalog_fkey_col != null + && this.code_id_xref.containsKey(catalog_fkey_col.getName().toLowerCase())) { + this.fkey_value_xref.put( + catalog_col.getName().toLowerCase(), catalog_fkey_col.getName().toLowerCase()); + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Added ForeignKey mapping from %s to %s", + catalog_col.getName().toLowerCase(), catalog_fkey_col.getName().toLowerCase())); + } } - return (null); - } - - /** - * Return a random customer id based out of any airport - * - * @return - */ - public CustomerId getRandomCustomerId() { - int num_airports = this.airport_max_customer_id.getValueCount(); - if (LOG.isTraceEnabled()) { - LOG.trace(String.format("Selecting a random airport with customers [numAirports=%d]", num_airports)); - } - CustomerId c_id = null; - while (c_id == null) { - Long airport_id = (long) this.rng.number(1, num_airports); - c_id = this.getRandomCustomerId(airport_id); + } + } + } + + // ---------------------------------------------------------------- + // SAVE / LOAD PROFILE + // ---------------------------------------------------------------- + + /** Save the profile information into the database */ + protected final void saveProfile(Connection conn) throws SQLException { + + // CONFIG_PROFILE + Table profileTable = benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_CONFIG_PROFILE); + String profileSql = + SQLUtil.getInsertSQL( + profileTable, this.benchmark.getWorkloadConfiguration().getDatabaseType()); + + try (PreparedStatement stmt = conn.prepareStatement(profileSql)) { + int param_idx = 1; + stmt.setObject(param_idx++, this.scale_factor); // CFP_SCALE_FACTOR + stmt.setObject( + param_idx++, this.airport_max_customer_id.toJSONString()); // CFP_AIPORT_MAX_CUSTOMER + stmt.setObject(param_idx++, this.flight_start_date); // CFP_FLIGHT_START + stmt.setObject(param_idx++, this.flight_upcoming_date); // CFP_FLIGHT_UPCOMING + stmt.setObject(param_idx++, this.flight_past_days); // CFP_FLIGHT_PAST_DAYS + stmt.setObject(param_idx++, this.flight_future_days); // CFP_FLIGHT_FUTURE_DAYS + stmt.setObject(param_idx++, this.flight_upcoming_offset); // CFP_FLIGHT_OFFSET + stmt.setObject(param_idx++, this.reservation_upcoming_offset); // CFP_RESERVATION_OFFSET + stmt.setObject(param_idx++, this.num_reservations); // CFP_NUM_RESERVATIONS + stmt.setObject(param_idx, JSONUtil.toJSONString(this.code_id_xref)); // CFP_CODE_ID_XREF + stmt.executeUpdate(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Saved profile information into {}", profileTable.getName()); + } + } + + // CONFIG_HISTOGRAMS + Table histogramsTable = + benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS); + String histogramSql = + SQLUtil.getInsertSQL( + histogramsTable, this.benchmark.getWorkloadConfiguration().getDatabaseType()); + try (PreparedStatement stmt = conn.prepareStatement(histogramSql)) { + for (Entry> e : this.airport_histograms.entrySet()) { + int param_idx = 1; + stmt.setObject(param_idx++, e.getKey()); // CFH_NAME + stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA + stmt.setObject(param_idx, 1); // CFH_IS_AIRPORT + stmt.executeUpdate(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Saved airport histogram information into {}", histogramsTable.getName()); + } + + for (Entry> e : this.histograms.entrySet()) { + int param_idx = 1; + stmt.setObject(param_idx++, e.getKey()); // CFH_NAME + stmt.setObject(param_idx++, e.getValue().toJSONString()); // CFH_DATA + stmt.setObject(param_idx, 0); // CFH_IS_AIRPORT + stmt.executeUpdate(); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Saved benchmark histogram information into {}", histogramsTable.getName()); + } + } + } + + protected static void clearCachedProfile() { + cachedProfile = null; + } + + private SEATSProfile copy(SEATSProfile other) { + this.scale_factor = other.scale_factor; + this.airport_max_customer_id.putHistogram(other.airport_max_customer_id); + this.flight_start_date.setTime(other.flight_start_date.getTime()); + this.flight_upcoming_date = other.flight_upcoming_date; + this.flight_past_days = other.flight_past_days; + this.flight_future_days = other.flight_future_days; + this.flight_upcoming_offset = other.flight_upcoming_offset; + this.reservation_upcoming_offset = other.reservation_upcoming_offset; + this.num_reservations = other.num_reservations; + this.code_id_xref.putAll(other.code_id_xref); + this.cached_flight_ids.addAll(other.cached_flight_ids); + this.airport_histograms.putAll(other.airport_histograms); + this.histograms.putAll(other.histograms); + return (this); + } + + /** Load the profile information stored in the database */ + private static SEATSProfile cachedProfile; + + protected final void loadProfile(SEATSWorker worker) throws SQLException { + synchronized (SEATSProfile.class) { + // Check whether we have a cached Profile we can copy from + if (cachedProfile != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Using cached SEATSProfile"); } - return (c_id); - } - - /** - * Return a random date in the future (after the start of upcoming flights) - * - * @return - */ - public Timestamp getRandomUpcomingDate() { - Timestamp upcoming_start_date = this.flight_upcoming_date; - int offset = this.rng.nextInt((int) this.getFlightFutureDays()); - return (new Timestamp(upcoming_start_date.getTime() + (offset * SEATSConstants.MILLISECONDS_PER_DAY))); - } - - /** - * Return a random FlightId from our set of cached ids - * - * @return - */ - public FlightId getRandomFlightId() { - + this.copy(cachedProfile); + return; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Loading SEATSProfile for the first time"); + } + + // Otherwise we have to go fetch everything again + LoadConfig proc = worker.getProcedure(LoadConfig.class); + + Config results; + try (Connection conn = benchmark.makeConnection()) { + results = proc.run(conn); + } + // CONFIG_PROFILE + this.loadConfigProfile(results.getConfigProfile()); + + // CONFIG_HISTOGRAMS + this.loadConfigHistograms(results.getConfigHistogram()); + + this.loadCodeXref( + results.getCountryCodes(), SEATSConstants.COUNTRY_CODE, SEATSConstants.COUNTRY_ID); + this.loadCodeXref( + results.getAirportCodes(), SEATSConstants.AIRPORT_CODE, SEATSConstants.AIRPORT_ID); + this.loadCodeXref( + results.getAirlineCodes(), SEATSConstants.AIRLINE_IATA_CODE, SEATSConstants.AIRLINE_ID); + + // CACHED FLIGHT IDS + this.loadCachedFlights(results.getFlights()); + + if (LOG.isDebugEnabled()) { + LOG.debug("Loaded profile:\n{}", this); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Airport Max Customer Id:\n{}", this.airport_max_customer_id); + } + + cachedProfile = new SEATSProfile(this.benchmark, this.rng).copy(this); + } + } + + private void loadConfigProfile(List vt) { + for (Object[] row : vt) { + this.scale_factor = SQLUtil.getDouble(row[0]); + JSONUtil.fromJSONString(this.airport_max_customer_id, SQLUtil.getString(row[1])); + this.flight_start_date.setTime(SQLUtil.getTimestamp(row[2]).getTime()); + this.flight_upcoming_date = SQLUtil.getTimestamp(row[3]); + this.flight_past_days = SQLUtil.getLong(row[4]); + this.flight_future_days = SQLUtil.getLong(row[5]); + this.flight_upcoming_offset = SQLUtil.getLong(row[6]); + this.reservation_upcoming_offset = SQLUtil.getLong(row[7]); + this.num_reservations = SQLUtil.getLong(row[8]); + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %s data", SEATSConstants.TABLENAME_CONFIG_PROFILE)); + } + } + + private void loadConfigHistograms(List vt) { + for (Object[] row : vt) { + String name = SQLUtil.getString(row[0]); + Histogram h = JSONUtil.fromJSONString(new Histogram<>(), SQLUtil.getString(row[1])); + boolean is_airline = (SQLUtil.getLong(row[2]) == 1); + + if (is_airline) { + this.airport_histograms.put(name, h); if (LOG.isTraceEnabled()) { - LOG.trace("Attempting to get a random FlightId"); + LOG.trace( + String.format("Loaded %d records for %s airport histogram", h.getValueCount(), name)); } - int idx = this.rng.nextInt(this.cached_flight_ids.size()); - FlightId flight_id = this.cached_flight_ids.get(idx); + } else { + this.histograms.put(name, h); if (LOG.isTraceEnabled()) { - LOG.trace("Got random {}", flight_id); - } - return (flight_id); - } - // ---------------------------------------------------------------- - // AIRLINE METHODS - // ---------------------------------------------------------------- - - public Collection getAirlineIds() { - Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); - return (m.values()); - } - - public Collection getAirlineCodes() { - Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); - return (m.keySet()); - } - - public Long getAirlineId(String airline_code) { - Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); - return (m.get(airline_code)); - } - - public int incrementAirportCustomerCount(long airport_id) { - int next_id = this.airport_max_customer_id.get(airport_id, 0); - this.airport_max_customer_id.put(airport_id); - return (next_id); - } - - public Integer getCustomerIdCount(Long airport_id) { - return (this.airport_max_customer_id.get(airport_id)); - } - - public long getCustomerIdCount() { - return (this.airport_max_customer_id.getSampleCount()); - } - - // ---------------------------------------------------------------- - // AIRPORT METHODS - // ---------------------------------------------------------------- - - /** - * Return all the airport ids that we know about - * - * @return - */ - public Collection getAirportIds() { - Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); - return (m.values()); - } - - public Long getAirportId(String airport_code) { - Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); - return (m.get(airport_code)); - } - - public String getAirportCode(long airport_id) { - Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); - for (Entry e : m.entrySet()) { - if (e.getValue() == airport_id) { - return (e.getKey()); - } - } - return (null); - } - - public Collection getAirportCodes() { - return (this.getCodeXref(SEATSConstants.AIRPORT_ID).keySet()); - } - - /** - * Return the number of airports that are part of this profile - * - * @return - */ - public int getAirportCount() { - return (this.getAirportCodes().size()); - } - - public Histogram getAirportCustomerHistogram() { - Histogram h = new Histogram<>(); - if (LOG.isDebugEnabled()) { - LOG.debug("Generating Airport-CustomerCount histogram [numAirports={}]", this.getAirportCount()); + LOG.trace(String.format("Loaded %d records for %s histogram", h.getValueCount(), name)); } - for (Long airport_id : this.airport_max_customer_id.values()) { - String airport_code = this.getAirportCode(airport_id); - int count = this.airport_max_customer_id.get(airport_id); - h.put(airport_code, count); - } - return (h); - } - - public Collection getAirportsWithFlights() { - return this.airport_histograms.keySet(); - } + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %s data", SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS)); + } + } + + private void loadCodeXref(List vt, String codeCol, String idCol) { + Map m = this.code_id_xref.get(idCol); + for (Object[] row : vt) { + long id = SQLUtil.getLong(row[0]); + String code = SQLUtil.getString(row[1]); + m.put(code, id); + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %d xrefs for %s -> %s", m.size(), codeCol, idCol)); + } + } + + private void loadCachedFlights(List vt) { + int limit = 1; + Iterator iterator = vt.iterator(); + while (iterator.hasNext() && limit++ < SEATSConstants.CACHE_LIMIT_FLIGHT_IDS) { + Object[] row = iterator.next(); + String f_id = SQLUtil.getString(row[0]); + FlightId flight_id = new FlightId(f_id); + this.cached_flight_ids.add(flight_id); + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Loaded %d cached FlightIds", this.cached_flight_ids.size())); + } + } + + // ---------------------------------------------------------------- + // DATA ACCESS METHODS + // ---------------------------------------------------------------- + + private Map getCodeXref(String col_name) { + + return (this.code_id_xref.get(col_name)); + } + + /** + * The offset of when upcoming reservation ids begin + * + * @return + */ + public Long getReservationUpcomingOffset() { + return (this.reservation_upcoming_offset); + } + + /** + * Set the number of upcoming reservation offset + * + * @param offset + */ + public void setReservationUpcomingOffset(long offset) { + this.reservation_upcoming_offset = offset; + } + + // ----------------------------------------------------------------- + // FLIGHTS + // ----------------------------------------------------------------- + + /** + * Add a new FlightId for this benchmark instance This method will decide whether to store the id + * or not in its cache + * + * @return True if the FlightId was added to the cache + */ + public boolean addFlightId(FlightId flight_id) { + boolean added = false; + synchronized (this.cached_flight_ids) { + // If we have room, shove it right in + // We'll throw it in the back because we know it hasn't been used + // yet + if (this.cached_flight_ids.size() < SEATSConstants.CACHE_LIMIT_FLIGHT_IDS) { + this.cached_flight_ids.addLast(flight_id); + added = true; + + // Otherwise, we can will randomly decide whether to pop one out + } else if (this.rng.nextBoolean()) { + this.cached_flight_ids.pop(); + this.cached_flight_ids.addLast(flight_id); + added = true; + } + } + return (added); + } + + public long getFlightIdCount() { + return (this.cached_flight_ids.size()); + } + + // ---------------------------------------------------------------- + // HISTOGRAM METHODS + // ---------------------------------------------------------------- + + /** + * Return the histogram for the given name + * + * @param name + * @return + */ + public Histogram getHistogram(String name) { + + return (this.histograms.get(name)); + } + + /** + * @param airport_code + * @return + */ + public Histogram getFightsPerAirportHistogram(String airport_code) { + return (this.airport_histograms.get(airport_code)); + } + + /** + * Returns the number of histograms that we have loaded Does not include the airport_histograms + * + * @return + */ + public int getHistogramCount() { + return (this.histograms.size()); + } + + // ---------------------------------------------------------------- + // RANDOM GENERATION METHODS + // ---------------------------------------------------------------- + + /** + * Return a random airport id + * + * @return + */ + public long getRandomAirportId() { + return (this.rng.number(1, this.getAirportCount())); + } + + public long getRandomOtherAirport(long airport_id) { + String code = this.getAirportCode(airport_id); + FlatHistogram f = this.airport_distributions.get(code); + if (f == null) { + synchronized (this.airport_distributions) { + f = this.airport_distributions.get(code); + if (f == null) { + Histogram h = this.airport_histograms.get(code); - public boolean hasFlights(String airport_code) { - Histogram h = this.getFightsPerAirportHistogram(airport_code); - if (h != null) { - return (h.getSampleCount() > 0); + f = new FlatHistogram<>(this.rng, h); + this.airport_distributions.put(code, f); } - return (false); - } - - // ----------------------------------------------------------------- - // FLIGHT DATES - // ----------------------------------------------------------------- - - /** - * The date in which the flight data set begins - * - * @return - */ - public Timestamp getFlightStartDate() { - return this.flight_start_date; - } - - /** - * @param start_date - */ - public void setFlightStartDate(Timestamp start_date) { - this.flight_start_date.setTime(start_date.getTime()); - } - - /** - * The date in which the flight data set begins - * - * @return - */ - public Timestamp getFlightUpcomingDate() { - return (this.flight_upcoming_date); - } - - public void setFlightUpcomingDate(Timestamp upcoming_date) { - this.flight_upcoming_date = upcoming_date; - } - - /** - * The date in which upcoming flights begin - * - * @return - */ - public long getFlightPastDays() { - return (this.flight_past_days); - } - - public void setFlightPastDays(long flight_past_days) { - this.flight_past_days = flight_past_days; - } - - /** - * The date in which upcoming flights begin - * - * @return - */ - public long getFlightFutureDays() { - return (this.flight_future_days); - } - - public void setFlightFutureDays(long flight_future_days) { - this.flight_future_days = flight_future_days; - } - - public long getNextReservationId(int id) { - // Offset it by the client id so that we can ensure it's unique - return (id | this.num_reservations++ << 48); - } - - @Override - public String toString() { - Map m = new ListOrderedMap<>(); - m.put("Scale Factor", this.scale_factor); - m.put("Data Directory", this.airline_data_dir); - m.put("# of Reservations", this.num_reservations); - m.put("Flight Start Date", this.flight_start_date); - m.put("Flight Upcoming Date", this.flight_upcoming_date); - m.put("Flight Past Days", this.flight_past_days); - m.put("Flight Future Days", this.flight_future_days); - m.put("Flight Upcoming Offset", this.flight_upcoming_offset); - m.put("Reservation Upcoming Offset", this.reservation_upcoming_offset); - return (StringUtil.formatMaps(m)); - } - + } + } + + String other = f.nextValue(); + return this.getAirportId(other); + } + + /** + * Return a random customer id based at the given airport_id + * + * @param airport_id + * @return + */ + public CustomerId getRandomCustomerId(Long airport_id) { + Integer cnt = this.getCustomerIdCount(airport_id); + if (cnt != null) { + int base_id = this.rng.nextInt(cnt); + return (new CustomerId(base_id, airport_id)); + } + return (null); + } + + /** + * Return a random customer id based out of any airport + * + * @return + */ + public CustomerId getRandomCustomerId() { + int num_airports = this.airport_max_customer_id.getValueCount(); + if (LOG.isTraceEnabled()) { + LOG.trace( + String.format( + "Selecting a random airport with customers [numAirports=%d]", num_airports)); + } + CustomerId c_id = null; + while (c_id == null) { + Long airport_id = (long) this.rng.number(1, num_airports); + c_id = this.getRandomCustomerId(airport_id); + } + return (c_id); + } + + /** + * Return a random date in the future (after the start of upcoming flights) + * + * @return + */ + public Timestamp getRandomUpcomingDate() { + Timestamp upcoming_start_date = this.flight_upcoming_date; + int offset = this.rng.nextInt((int) this.getFlightFutureDays()); + return (new Timestamp( + upcoming_start_date.getTime() + (offset * SEATSConstants.MILLISECONDS_PER_DAY))); + } + + /** + * Return a random FlightId from our set of cached ids + * + * @return + */ + public FlightId getRandomFlightId() { + + if (LOG.isTraceEnabled()) { + LOG.trace("Attempting to get a random FlightId"); + } + int idx = this.rng.nextInt(this.cached_flight_ids.size()); + FlightId flight_id = this.cached_flight_ids.get(idx); + if (LOG.isTraceEnabled()) { + LOG.trace("Got random {}", flight_id); + } + return (flight_id); + } + + // ---------------------------------------------------------------- + // AIRLINE METHODS + // ---------------------------------------------------------------- + + public Collection getAirlineIds() { + Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); + return (m.values()); + } + + public Collection getAirlineCodes() { + Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); + return (m.keySet()); + } + + public Long getAirlineId(String airline_code) { + Map m = this.getCodeXref(SEATSConstants.AIRLINE_ID); + return (m.get(airline_code)); + } + + public int incrementAirportCustomerCount(long airport_id) { + int next_id = this.airport_max_customer_id.get(airport_id, 0); + this.airport_max_customer_id.put(airport_id); + return (next_id); + } + + public Integer getCustomerIdCount(Long airport_id) { + return (this.airport_max_customer_id.get(airport_id)); + } + + public long getCustomerIdCount() { + return (this.airport_max_customer_id.getSampleCount()); + } + + // ---------------------------------------------------------------- + // AIRPORT METHODS + // ---------------------------------------------------------------- + + /** + * Return all the airport ids that we know about + * + * @return + */ + public Collection getAirportIds() { + Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); + return (m.values()); + } + + public Long getAirportId(String airport_code) { + Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); + return (m.get(airport_code)); + } + + public String getAirportCode(long airport_id) { + Map m = this.getCodeXref(SEATSConstants.AIRPORT_ID); + for (Entry e : m.entrySet()) { + if (e.getValue() == airport_id) { + return (e.getKey()); + } + } + return (null); + } + + public Collection getAirportCodes() { + return (this.getCodeXref(SEATSConstants.AIRPORT_ID).keySet()); + } + + /** + * Return the number of airports that are part of this profile + * + * @return + */ + public int getAirportCount() { + return (this.getAirportCodes().size()); + } + + public Histogram getAirportCustomerHistogram() { + Histogram h = new Histogram<>(); + if (LOG.isDebugEnabled()) { + LOG.debug( + "Generating Airport-CustomerCount histogram [numAirports={}]", this.getAirportCount()); + } + for (Long airport_id : this.airport_max_customer_id.values()) { + String airport_code = this.getAirportCode(airport_id); + int count = this.airport_max_customer_id.get(airport_id); + h.put(airport_code, count); + } + return (h); + } + + public Collection getAirportsWithFlights() { + return this.airport_histograms.keySet(); + } + + public boolean hasFlights(String airport_code) { + Histogram h = this.getFightsPerAirportHistogram(airport_code); + if (h != null) { + return (h.getSampleCount() > 0); + } + return (false); + } + + // ----------------------------------------------------------------- + // FLIGHT DATES + // ----------------------------------------------------------------- + + /** + * The date in which the flight data set begins + * + * @return + */ + public Timestamp getFlightStartDate() { + return this.flight_start_date; + } + + /** + * @param start_date + */ + public void setFlightStartDate(Timestamp start_date) { + this.flight_start_date.setTime(start_date.getTime()); + } + + /** + * The date in which the flight data set begins + * + * @return + */ + public Timestamp getFlightUpcomingDate() { + return (this.flight_upcoming_date); + } + + public void setFlightUpcomingDate(Timestamp upcoming_date) { + this.flight_upcoming_date = upcoming_date; + } + + /** + * The date in which upcoming flights begin + * + * @return + */ + public long getFlightPastDays() { + return (this.flight_past_days); + } + + public void setFlightPastDays(long flight_past_days) { + this.flight_past_days = flight_past_days; + } + + /** + * The date in which upcoming flights begin + * + * @return + */ + public long getFlightFutureDays() { + return (this.flight_future_days); + } + + public void setFlightFutureDays(long flight_future_days) { + this.flight_future_days = flight_future_days; + } + + public long getNextReservationId(int id) { + // Offset it by the client id so that we can ensure it's unique + return (id | this.num_reservations++ << 48); + } + + @Override + public String toString() { + Map m = new ListOrderedMap<>(); + m.put("Scale Factor", this.scale_factor); + m.put("Data Directory", this.airline_data_dir); + m.put("# of Reservations", this.num_reservations); + m.put("Flight Start Date", this.flight_start_date); + m.put("Flight Upcoming Date", this.flight_upcoming_date); + m.put("Flight Past Days", this.flight_past_days); + m.put("Flight Future Days", this.flight_future_days); + m.put("Flight Upcoming Offset", this.flight_upcoming_offset); + m.put("Reservation Upcoming Offset", this.reservation_upcoming_offset); + return (StringUtil.formatMaps(m)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java index afdced159..25b312dc8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/SEATSWorker.java @@ -50,671 +50,705 @@ import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.RandomGenerator; import com.oltpbenchmark.util.StringUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Timestamp; import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class SEATSWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(SEATSWorker.class); - - /** - * Airline Benchmark Transactions - */ - private enum Transaction { - DeleteReservation(DeleteReservation.class), FindFlights(FindFlights.class), FindOpenSeats(FindOpenSeats.class), NewReservation(NewReservation.class), UpdateCustomer(UpdateCustomer.class), UpdateReservation(UpdateReservation.class); - - Transaction(Class proc_class) { - this.proc_class = proc_class; - this.execName = proc_class.getSimpleName(); - this.displayName = StringUtil.title(this.name().replace("_", " ")); - } - - @SuppressWarnings("unused") // never read - public final Class proc_class; - - public final String displayName; - public final String execName; - - protected static final Map idx_lookup = new HashMap<>(); - protected static final Map name_lookup = new HashMap<>(); - - static { - for (Transaction vt : EnumSet.allOf(Transaction.class)) { - Transaction.idx_lookup.put(vt.ordinal(), vt); - Transaction.name_lookup.put(vt.name(), vt); - } - } - - public static Transaction get(String name) { - return (Transaction.name_lookup.get(name)); - } - - public String getDisplayName() { - return (this.displayName); - } - - public String getExecName() { - return (this.execName); - } + private static final Logger LOG = LoggerFactory.getLogger(SEATSWorker.class); + + /** Airline Benchmark Transactions */ + private enum Transaction { + DeleteReservation(DeleteReservation.class), + FindFlights(FindFlights.class), + FindOpenSeats(FindOpenSeats.class), + NewReservation(NewReservation.class), + UpdateCustomer(UpdateCustomer.class), + UpdateReservation(UpdateReservation.class); + + Transaction(Class proc_class) { + this.proc_class = proc_class; + this.execName = proc_class.getSimpleName(); + this.displayName = StringUtil.title(this.name().replace("_", " ")); } - // ----------------------------------------------------------------- - // RESERVED SEAT BITMAPS - // ----------------------------------------------------------------- + @SuppressWarnings("unused") // never read + public final Class proc_class; - public enum CacheType { - PENDING_INSERTS(SEATSConstants.CACHE_LIMIT_PENDING_INSERTS), PENDING_UPDATES(SEATSConstants.CACHE_LIMIT_PENDING_UPDATES), PENDING_DELETES(SEATSConstants.CACHE_LIMIT_PENDING_DELETES), - ; + public final String displayName; + public final String execName; - CacheType(int limit) { - this.limit = limit; - } + protected static final Map idx_lookup = new HashMap<>(); + protected static final Map name_lookup = new HashMap<>(); - private final int limit; + static { + for (Transaction vt : EnumSet.allOf(Transaction.class)) { + Transaction.idx_lookup.put(vt.ordinal(), vt); + Transaction.name_lookup.put(vt.name(), vt); + } } - protected final Map> CACHE_RESERVATIONS = new HashMap<>(); - - { - for (CacheType ctype : CacheType.values()) { - CACHE_RESERVATIONS.put(ctype, new LinkedList<>()); - } + public static Transaction get(String name) { + return (Transaction.name_lookup.get(name)); } - - protected final Map> CACHE_CUSTOMER_BOOKED_FLIGHTS = new HashMap<>(); - protected final Map CACHE_BOOKED_SEATS = new HashMap<>(); - - private static final BitSet FULL_FLIGHT_BITSET = new BitSet(SEATSConstants.FLIGHTS_NUM_SEATS); - - static { - for (int i = 0; i < SEATSConstants.FLIGHTS_NUM_SEATS; i++) { - FULL_FLIGHT_BITSET.set(i); - } + public String getDisplayName() { + return (this.displayName); } - protected BitSet getSeatsBitSet(FlightId flight_id) { - BitSet seats = CACHE_BOOKED_SEATS.get(flight_id); - if (seats == null) { -// synchronized (CACHE_BOOKED_SEATS) { - seats = CACHE_BOOKED_SEATS.get(flight_id); - if (seats == null) { - seats = new BitSet(SEATSConstants.FLIGHTS_NUM_SEATS); - CACHE_BOOKED_SEATS.put(flight_id, seats); - } -// } - } - return (seats); - } - - /** - * Returns true if the given BitSet for a Flight has all of its seats reserved - * - * @param seats - * @return - */ - protected boolean isFlightFull(BitSet seats) { - - return FULL_FLIGHT_BITSET.equals(seats); - } - - /** - * Returns true if the given Customer already has a reservation booked on the target Flight - * - * @param customer_id - * @param flight_id - * @return - */ - protected boolean isCustomerBookedOnFlight(CustomerId customer_id, FlightId flight_id) { - Set flights = CACHE_CUSTOMER_BOOKED_FLIGHTS.get(customer_id); - return (flights != null && flights.contains(flight_id)); - } - - // ----------------------------------------------------------------- - // ADDITIONAL DATA MEMBERS - // ----------------------------------------------------------------- - - private final SEATSProfile profile; - private final RandomGenerator rng; - private final List tmp_reservations = new ArrayList<>(); - - /** - * When a customer looks for an open seat, they will then attempt to book that seat in - * a new reservation. Some of them will want to change their seats. This data structure - * represents a customer that is queued to change their seat. - */ - protected static class Reservation { - public final long id; - public final FlightId flight_id; - public final CustomerId customer_id; - public final int seatnum; - - public Reservation(long id, FlightId flight_id, CustomerId customer_id, int seatnum) { - this.id = id; - this.flight_id = flight_id; - this.customer_id = customer_id; - this.seatnum = seatnum; - - - } - - @Override - public int hashCode() { - int prime = 7; - int result = 1; - result = prime * result + seatnum; - result = prime * result + flight_id.hashCode(); - result = prime * result + customer_id.hashCode(); - - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } + public String getExecName() { + return (this.execName); + } + } - if (!(obj instanceof SEATSWorker) || obj == null) { - return false; - } + // ----------------------------------------------------------------- + // RESERVED SEAT BITMAPS + // ----------------------------------------------------------------- - Reservation r = (Reservation) obj; - // Ignore id! - return (this.seatnum == r.seatnum && this.flight_id.equals(r.flight_id) && this.customer_id.equals(r.customer_id)); - } + public enum CacheType { + PENDING_INSERTS(SEATSConstants.CACHE_LIMIT_PENDING_INSERTS), + PENDING_UPDATES(SEATSConstants.CACHE_LIMIT_PENDING_UPDATES), + PENDING_DELETES(SEATSConstants.CACHE_LIMIT_PENDING_DELETES), + ; - @Override - public String toString() { - return String.format("{Id:%d / %s / %s / SeatNum:%d}", this.id, this.flight_id, this.customer_id, this.seatnum); - } + CacheType(int limit) { + this.limit = limit; } - // ----------------------------------------------------------------- - // REQUIRED METHODS - // ----------------------------------------------------------------- + private final int limit; + } - public SEATSWorker(SEATSBenchmark benchmark, int id) { - super(benchmark, id); + protected final Map> CACHE_RESERVATIONS = new HashMap<>(); - this.rng = benchmark.getRandomGenerator(); - this.profile = new SEATSProfile(benchmark, rng); + { + for (CacheType ctype : CacheType.values()) { + CACHE_RESERVATIONS.put(ctype, new LinkedList<>()); } + } - protected void initialize() { - try { - this.profile.loadProfile(this); - } catch (SQLException ex) { - throw new RuntimeException(ex); - } - if (LOG.isTraceEnabled()) { - LOG.trace("Airport Max Customer Id:\n{}", this.profile.airport_max_customer_id); - } + protected final Map> CACHE_CUSTOMER_BOOKED_FLIGHTS = new HashMap<>(); + protected final Map CACHE_BOOKED_SEATS = new HashMap<>(); - // Make sure we have the information we need in the BenchmarkProfile - String error_msg = null; - if (this.profile.getFlightIdCount() == 0) { - error_msg = "The benchmark profile does not have any flight ids."; - } else if (this.profile.getCustomerIdCount() == 0) { - error_msg = "The benchmark profile does not have any customer ids."; - } else if (this.profile.getFlightStartDate() == null) { - error_msg = "The benchmark profile does not have a valid flight start date."; - } - if (error_msg != null) { - throw new RuntimeException(error_msg); - } + private static final BitSet FULL_FLIGHT_BITSET = new BitSet(SEATSConstants.FLIGHTS_NUM_SEATS); - // Fire off a FindOpenSeats so that we can prime ourselves - FindOpenSeats proc = this.getProcedure(FindOpenSeats.class); - try (Connection conn = getBenchmark().makeConnection()) { - this.executeFindOpenSeats(conn, proc); - } catch (SQLException ex) { - throw new RuntimeException(ex); - } - - if (LOG.isDebugEnabled()) { - LOG.debug("Initialized SEATSWorker:\n{}", this); - } + static { + for (int i = 0; i < SEATSConstants.FLIGHTS_NUM_SEATS; i++) { + FULL_FLIGHT_BITSET.set(i); + } + } + + protected BitSet getSeatsBitSet(FlightId flight_id) { + BitSet seats = CACHE_BOOKED_SEATS.get(flight_id); + if (seats == null) { + // synchronized (CACHE_BOOKED_SEATS) { + seats = CACHE_BOOKED_SEATS.get(flight_id); + if (seats == null) { + seats = new BitSet(SEATSConstants.FLIGHTS_NUM_SEATS); + CACHE_BOOKED_SEATS.put(flight_id, seats); + } + // } + } + return (seats); + } + + /** + * Returns true if the given BitSet for a Flight has all of its seats reserved + * + * @param seats + * @return + */ + protected boolean isFlightFull(BitSet seats) { + + return FULL_FLIGHT_BITSET.equals(seats); + } + + /** + * Returns true if the given Customer already has a reservation booked on the target Flight + * + * @param customer_id + * @param flight_id + * @return + */ + protected boolean isCustomerBookedOnFlight(CustomerId customer_id, FlightId flight_id) { + Set flights = CACHE_CUSTOMER_BOOKED_FLIGHTS.get(customer_id); + return (flights != null && flights.contains(flight_id)); + } + + // ----------------------------------------------------------------- + // ADDITIONAL DATA MEMBERS + // ----------------------------------------------------------------- + + private final SEATSProfile profile; + private final RandomGenerator rng; + private final List tmp_reservations = new ArrayList<>(); + + /** + * When a customer looks for an open seat, they will then attempt to book that seat in a new + * reservation. Some of them will want to change their seats. This data structure represents a + * customer that is queued to change their seat. + */ + protected static class Reservation { + public final long id; + public final FlightId flight_id; + public final CustomerId customer_id; + public final int seatnum; + + public Reservation(long id, FlightId flight_id, CustomerId customer_id, int seatnum) { + this.id = id; + this.flight_id = flight_id; + this.customer_id = customer_id; + this.seatnum = seatnum; } @Override - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException { - Transaction txn = Transaction.get(txnType.getName()); - - - // Get the Procedure handle - Procedure proc = this.getProcedure(txnType); - if (LOG.isDebugEnabled()) { - LOG.debug("Attempting to execute {}", proc); - } - boolean ret = false; - try { - switch (txn) { - case DeleteReservation: { - ret = this.executeDeleteReservation(conn, (DeleteReservation) proc); - break; - } - case FindFlights: { - ret = this.executeFindFlights(conn, (FindFlights) proc); - break; - } - case FindOpenSeats: { - ret = this.executeFindOpenSeats(conn, (FindOpenSeats) proc); - break; - } - case NewReservation: { - ret = this.executeNewReservation(conn, (NewReservation) proc); - break; - } - case UpdateCustomer: { - ret = this.executeUpdateCustomer(conn, (UpdateCustomer) proc); - break; - } - case UpdateReservation: { - ret = this.executeUpdateReservation(conn, (UpdateReservation) proc); - break; - } - default: - - } - } catch (SQLException esql) { - LOG.error("caught SQLException in SEATSWorker for procedure {}:{}", txnType.getName(), esql, esql); - throw esql; - }/*catch(Exception e) { - LOG.error("caught Exception in SEATSWorker for procedure "+txnType.getName() +":" + e, e); - }*/ - if (!ret) { - if (LOG.isDebugEnabled()) { - LOG.debug("Unable to execute {} right now", proc); - } - return (TransactionStatus.RETRY_DIFFERENT); - } - - if (ret && LOG.isDebugEnabled()) { - LOG.debug("Executed a new invocation of {}", txn); - } - return (TransactionStatus.SUCCESS); - } - - /** - * Take an existing Reservation that we know is legit and randomly decide to - * either queue it for a later update or delete transaction - * - * @param r - */ - protected void requeueReservation(Reservation r) { - CacheType ctype = null; - - // Queue this motha trucka up for a deletin' - if (rng.nextBoolean()) { - ctype = CacheType.PENDING_DELETES; - } else { - ctype = CacheType.PENDING_UPDATES; - } - - - LinkedList cache = CACHE_RESERVATIONS.get(ctype); + public int hashCode() { + int prime = 7; + int result = 1; + result = prime * result + seatnum; + result = prime * result + flight_id.hashCode(); + result = prime * result + customer_id.hashCode(); + + return result; + } - cache.add(r); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Queued %s for %s [cache=%d]", r, ctype, cache.size())); - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (!(obj instanceof SEATSWorker) || obj == null) { + return false; + } + + Reservation r = (Reservation) obj; + // Ignore id! + return (this.seatnum == r.seatnum + && this.flight_id.equals(r.flight_id) + && this.customer_id.equals(r.customer_id)); + } - while (cache.size() > ctype.limit) { - cache.remove(); - } + @Override + public String toString() { + return String.format( + "{Id:%d / %s / %s / SeatNum:%d}", + this.id, this.flight_id, this.customer_id, this.seatnum); } + } - // ----------------------------------------------------------------- - // DeleteReservation - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- + // REQUIRED METHODS + // ----------------------------------------------------------------- - private boolean executeDeleteReservation(Connection conn, DeleteReservation proc) throws SQLException { - // Pull off the first cached reservation and drop it on the cluster... - final Reservation r = CACHE_RESERVATIONS.get(CacheType.PENDING_DELETES).poll(); - if (r == null) { - return (false); - } - int rand = rng.number(1, 100); - - // Parameters - String f_id = r.flight_id.encode(); - String c_id = null; - String c_id_str = null; - String ff_c_id_str = null; - Long ff_al_id = null; - - // Delete with the Customer's id as a string - if (rand <= SEATSConstants.PROB_DELETE_WITH_CUSTOMER_ID_STR) { - c_id_str = r.customer_id.encode(); - } - // Delete using their FrequentFlyer information - else if (rand <= SEATSConstants.PROB_DELETE_WITH_CUSTOMER_ID_STR + SEATSConstants.PROB_DELETE_WITH_FREQUENTFLYER_ID_STR) { - ff_c_id_str = r.customer_id.encode(); - ff_al_id = r.flight_id.getAirlineId(); - } - // Delete using their Customer id - else { - c_id = r.customer_id.encode(); - } + public SEATSWorker(SEATSBenchmark benchmark, int id) { + super(benchmark, id); - if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); - } + this.rng = benchmark.getRandomGenerator(); + this.profile = new SEATSProfile(benchmark, rng); + } + protected void initialize() { + try { + this.profile.loadProfile(this); + } catch (SQLException ex) { + throw new RuntimeException(ex); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Airport Max Customer Id:\n{}", this.profile.airport_max_customer_id); + } - proc.run(conn, f_id, c_id, c_id_str, ff_c_id_str, ff_al_id); + // Make sure we have the information we need in the BenchmarkProfile + String error_msg = null; + if (this.profile.getFlightIdCount() == 0) { + error_msg = "The benchmark profile does not have any flight ids."; + } else if (this.profile.getCustomerIdCount() == 0) { + error_msg = "The benchmark profile does not have any customer ids."; + } else if (this.profile.getFlightStartDate() == null) { + error_msg = "The benchmark profile does not have a valid flight start date."; + } + if (error_msg != null) { + throw new RuntimeException(error_msg); + } - // We can remove this from our set of full flights because know that there is now a free seat - BitSet seats = getSeatsBitSet(r.flight_id); - seats.set(r.seatnum, false); + // Fire off a FindOpenSeats so that we can prime ourselves + FindOpenSeats proc = this.getProcedure(FindOpenSeats.class); + try (Connection conn = getBenchmark().makeConnection()) { + this.executeFindOpenSeats(conn, proc); + } catch (SQLException ex) { + throw new RuntimeException(ex); + } - // And then put it up for a pending insert - if (rng.nextInt(100) < SEATSConstants.PROB_REQUEUE_DELETED_RESERVATION) { - CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS).add(r); - } + if (LOG.isDebugEnabled()) { + LOG.debug("Initialized SEATSWorker:\n{}", this); + } + } - return (true); - } - - // ---------------------------------------------------------------- - // FindFlights - // ---------------------------------------------------------------- - - /** - * Execute one of the FindFlight transactions - * - * @param conn - * @param proc - * @throws SQLException - */ - private boolean executeFindFlights(Connection conn, FindFlights proc) throws SQLException { - long depart_airport_id; - long arrive_airport_id; - Timestamp start_date; - Timestamp stop_date; - - // Select two random airport ids - if (rng.nextInt(100) < SEATSConstants.PROB_FIND_FLIGHTS_RANDOM_AIRPORTS) { - // Does it matter whether the one airport actually flies to the other one? - depart_airport_id = this.profile.getRandomAirportId(); - arrive_airport_id = this.profile.getRandomOtherAirport(depart_airport_id); - - // Select a random date from our upcoming dates - start_date = this.profile.getRandomUpcomingDate(); - stop_date = new Timestamp(start_date.getTime() + (SEATSConstants.MILLISECONDS_PER_DAY * 2)); - } + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException { + Transaction txn = Transaction.get(txnType.getName()); - // Use an existing flight so that we guaranteed to get back results - else { - FlightId flight_id = this.profile.getRandomFlightId(); - depart_airport_id = flight_id.getDepartAirportId(); - arrive_airport_id = flight_id.getArriveAirportId(); + // Get the Procedure handle + Procedure proc = this.getProcedure(txnType); + if (LOG.isDebugEnabled()) { + LOG.debug("Attempting to execute {}", proc); + } + boolean ret = false; + try { + switch (txn) { + case DeleteReservation: + { + ret = this.executeDeleteReservation(conn, (DeleteReservation) proc); + break; + } + case FindFlights: + { + ret = this.executeFindFlights(conn, (FindFlights) proc); + break; + } + case FindOpenSeats: + { + ret = this.executeFindOpenSeats(conn, (FindOpenSeats) proc); + break; + } + case NewReservation: + { + ret = this.executeNewReservation(conn, (NewReservation) proc); + break; + } + case UpdateCustomer: + { + ret = this.executeUpdateCustomer(conn, (UpdateCustomer) proc); + break; + } + case UpdateReservation: + { + ret = this.executeUpdateReservation(conn, (UpdateReservation) proc); + break; + } + default: + } + } catch (SQLException esql) { + LOG.error( + "caught SQLException in SEATSWorker for procedure {}:{}", txnType.getName(), esql, esql); + throw esql; + } /*catch(Exception e) { + LOG.error("caught Exception in SEATSWorker for procedure "+txnType.getName() +":" + e, e); + }*/ + if (!ret) { + if (LOG.isDebugEnabled()) { + LOG.debug("Unable to execute {} right now", proc); + } + return (TransactionStatus.RETRY_DIFFERENT); + } - Timestamp flightDate = flight_id.getDepartDateAsTimestamp(this.profile.getFlightStartDate()); - long range = Math.round(SEATSConstants.MILLISECONDS_PER_DAY * 0.5); - start_date = new Timestamp(flightDate.getTime() - range); - stop_date = new Timestamp(flightDate.getTime() + range); + if (ret && LOG.isDebugEnabled()) { + LOG.debug("Executed a new invocation of {}", txn); + } + return (TransactionStatus.SUCCESS); + } + + /** + * Take an existing Reservation that we know is legit and randomly decide to either queue it for a + * later update or delete transaction + * + * @param r + */ + protected void requeueReservation(Reservation r) { + CacheType ctype = null; + + // Queue this motha trucka up for a deletin' + if (rng.nextBoolean()) { + ctype = CacheType.PENDING_DELETES; + } else { + ctype = CacheType.PENDING_UPDATES; + } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Using %s as look up in %s: %s / %s", flight_id, proc, flight_id.encode(), flightDate)); - } - } + LinkedList cache = CACHE_RESERVATIONS.get(ctype); - // If distance is greater than zero, then we will also get flights from nearby airports - long distance = -1; - if (rng.nextInt(100) < SEATSConstants.PROB_FIND_FLIGHTS_NEARBY_AIRPORT) { - distance = SEATSConstants.DISTANCES[rng.nextInt(SEATSConstants.DISTANCES.length)]; - } + cache.add(r); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Queued %s for %s [cache=%d]", r, ctype, cache.size())); + } - if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); - } - List results = proc.run(conn, depart_airport_id, arrive_airport_id, start_date, stop_date, distance); - - if (results.size() > 1) { - // Convert the data into a FlightIds that other transactions can use - int ctr = 0; - for (Object[] row : results) { - FlightId flight_id = new FlightId((String) row[0]); - - boolean added = profile.addFlightId(flight_id); - if (added) { - ctr++; - } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Added %d out of %d FlightIds to local cache", ctr, results.size())); - } - } - return (true); + while (cache.size() > ctype.limit) { + cache.remove(); + } + } + + // ----------------------------------------------------------------- + // DeleteReservation + // ----------------------------------------------------------------- + + private boolean executeDeleteReservation(Connection conn, DeleteReservation proc) + throws SQLException { + // Pull off the first cached reservation and drop it on the cluster... + final Reservation r = CACHE_RESERVATIONS.get(CacheType.PENDING_DELETES).poll(); + if (r == null) { + return (false); + } + int rand = rng.number(1, 100); + + // Parameters + String f_id = r.flight_id.encode(); + String c_id = null; + String c_id_str = null; + String ff_c_id_str = null; + Long ff_al_id = null; + + // Delete with the Customer's id as a string + if (rand <= SEATSConstants.PROB_DELETE_WITH_CUSTOMER_ID_STR) { + c_id_str = r.customer_id.encode(); + } + // Delete using their FrequentFlyer information + else if (rand + <= SEATSConstants.PROB_DELETE_WITH_CUSTOMER_ID_STR + + SEATSConstants.PROB_DELETE_WITH_FREQUENTFLYER_ID_STR) { + ff_c_id_str = r.customer_id.encode(); + ff_al_id = r.flight_id.getAirlineId(); + } + // Delete using their Customer id + else { + c_id = r.customer_id.encode(); } - // ---------------------------------------------------------------- - // FindOpenSeats - // ---------------------------------------------------------------- + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); + } - /** - * Execute the FindOpenSeat procedure - * - * @throws SQLException - */ - private boolean executeFindOpenSeats(Connection conn, FindOpenSeats proc) throws SQLException { - final FlightId search_flight = this.profile.getRandomFlightId(); + proc.run(conn, f_id, c_id, c_id_str, ff_c_id_str, ff_al_id); - Long airport_depart_id = search_flight.getDepartAirportId(); + // We can remove this from our set of full flights because know that there is now a free seat + BitSet seats = getSeatsBitSet(r.flight_id); + seats.set(r.seatnum, false); - if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); - } - Object[][] results = proc.run(conn, search_flight.encode()); + // And then put it up for a pending insert + if (rng.nextInt(100) < SEATSConstants.PROB_REQUEUE_DELETED_RESERVATION) { + CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS).add(r); + } - int rowCount = results.length; - // there is some tiny probability of an empty flight .. maybe 1/(20**150) + return (true); + } + + // ---------------------------------------------------------------- + // FindFlights + // ---------------------------------------------------------------- + + /** + * Execute one of the FindFlight transactions + * + * @param conn + * @param proc + * @throws SQLException + */ + private boolean executeFindFlights(Connection conn, FindFlights proc) throws SQLException { + long depart_airport_id; + long arrive_airport_id; + Timestamp start_date; + Timestamp stop_date; + + // Select two random airport ids + if (rng.nextInt(100) < SEATSConstants.PROB_FIND_FLIGHTS_RANDOM_AIRPORTS) { + // Does it matter whether the one airport actually flies to the other one? + depart_airport_id = this.profile.getRandomAirportId(); + arrive_airport_id = this.profile.getRandomOtherAirport(depart_airport_id); + + // Select a random date from our upcoming dates + start_date = this.profile.getRandomUpcomingDate(); + stop_date = new Timestamp(start_date.getTime() + (SEATSConstants.MILLISECONDS_PER_DAY * 2)); + } - if (rowCount == 0) { - return (true); - } + // Use an existing flight so that we guaranteed to get back results + else { + FlightId flight_id = this.profile.getRandomFlightId(); + depart_airport_id = flight_id.getDepartAirportId(); + arrive_airport_id = flight_id.getArriveAirportId(); + + Timestamp flightDate = flight_id.getDepartDateAsTimestamp(this.profile.getFlightStartDate()); + long range = Math.round(SEATSConstants.MILLISECONDS_PER_DAY * 0.5); + start_date = new Timestamp(flightDate.getTime() - range); + stop_date = new Timestamp(flightDate.getTime() + range); + + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Using %s as look up in %s: %s / %s", + flight_id, proc, flight_id.encode(), flightDate)); + } + } - LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS); - - // Store pending reservations in our queue for a later transaction - BitSet seats = getSeatsBitSet(search_flight); - tmp_reservations.clear(); - - for (Object[] row : results) { - if (row == null) { - continue; // || rng.nextInt(100) < 75) continue; // HACK - } - Integer seatnum = (Integer) row[1]; - - // We first try to get a CustomerId based at this departure airport - if (LOG.isTraceEnabled()) { - LOG.trace("Looking for a random customer to fly on {}", search_flight); - } - CustomerId customer_id = profile.getRandomCustomerId(airport_depart_id); - - // We will go for a random one if: - // (1) The Customer is already booked on this Flight - // (2) We already made a new Reservation just now for this Customer - int tries = SEATSConstants.FLIGHTS_NUM_SEATS; - while (tries-- > 0 && (customer_id == null)) { // || isCustomerBookedOnFlight(customer_id, flight_id))) { - customer_id = profile.getRandomCustomerId(); - if (LOG.isTraceEnabled()) { - LOG.trace("RANDOM CUSTOMER: {}", customer_id); - } - } - Reservation r = new Reservation(profile.getNextReservationId(getId()), search_flight, customer_id, seatnum); - seats.set(seatnum); - tmp_reservations.add(r); - if (LOG.isTraceEnabled()) { - LOG.trace("QUEUED INSERT: {} / {} -> {}", search_flight, search_flight.encode(), customer_id); - } - } + // If distance is greater than zero, then we will also get flights from nearby airports + long distance = -1; + if (rng.nextInt(100) < SEATSConstants.PROB_FIND_FLIGHTS_NEARBY_AIRPORT) { + distance = SEATSConstants.DISTANCES[rng.nextInt(SEATSConstants.DISTANCES.length)]; + } - if (!tmp_reservations.isEmpty()) { - Collections.shuffle(tmp_reservations); - cache.addAll(tmp_reservations); - while (cache.size() > SEATSConstants.CACHE_LIMIT_PENDING_INSERTS) { - cache.remove(); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Stored %d pending inserts for %s [totalPendingInserts=%d]", tmp_reservations.size(), search_flight, cache.size())); - } - } - return (true); + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); } + List results = + proc.run(conn, depart_airport_id, arrive_airport_id, start_date, stop_date, distance); + + if (results.size() > 1) { + // Convert the data into a FlightIds that other transactions can use + int ctr = 0; + for (Object[] row : results) { + FlightId flight_id = new FlightId((String) row[0]); + + boolean added = profile.addFlightId(flight_id); + if (added) { + ctr++; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format("Added %d out of %d FlightIds to local cache", ctr, results.size())); + } + } + return (true); + } - // ---------------------------------------------------------------- - // NewReservation - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- + // FindOpenSeats + // ---------------------------------------------------------------- - private boolean executeNewReservation(Connection conn, NewReservation proc) throws SQLException { - Reservation reservation = null; - BitSet seats = null; - LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS); + /** + * Execute the FindOpenSeat procedure + * + * @throws SQLException + */ + private boolean executeFindOpenSeats(Connection conn, FindOpenSeats proc) throws SQLException { + final FlightId search_flight = this.profile.getRandomFlightId(); + Long airport_depart_id = search_flight.getDepartAirportId(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Attempting to get a new pending insert Reservation [totalPendingInserts=%d]", cache.size())); - } - while (reservation == null) { - Reservation r = cache.poll(); - if (r == null) { - LOG.warn("Unable to execute {} - No available reservations to insert", proc); - break; - } - - seats = getSeatsBitSet(r.flight_id); - - if (isFlightFull(seats)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s is full", r.flight_id)); - } - continue; - } - // PAVLO: Not sure why this is always coming back as reserved? -// else if (seats.get(r.seatnum)) { -// if (LOG.isDebugEnabled()) -// LOG.debug(String.format("Seat #%d on %s is already booked", r.seatnum, r.flight_id)); -// continue; -// } - else if (isCustomerBookedOnFlight(r.customer_id, r.flight_id)) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s is already booked on %s", r.customer_id, r.flight_id)); - } - continue; - } - reservation = r; - } - if (reservation == null) { - LOG.warn("Failed to find a valid pending insert Reservation\n{}", this); - return (false); - } + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); + } + Object[][] results = proc.run(conn, search_flight.encode()); - // Generate a random price for now - double price = 2.0 * rng.number(SEATSConstants.RESERVATION_PRICE_MIN, SEATSConstants.RESERVATION_PRICE_MAX); + int rowCount = results.length; + // there is some tiny probability of an empty flight .. maybe 1/(20**150) - // Generate random attributes - long[] attributes = new long[9]; - for (int i = 0; i < attributes.length; i++) { - attributes[i] = rng.nextLong(); - } + if (rowCount == 0) { + return (true); + } + LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS); + + // Store pending reservations in our queue for a later transaction + BitSet seats = getSeatsBitSet(search_flight); + tmp_reservations.clear(); + + for (Object[] row : results) { + if (row == null) { + continue; // || rng.nextInt(100) < 75) continue; // HACK + } + Integer seatnum = (Integer) row[1]; + + // We first try to get a CustomerId based at this departure airport + if (LOG.isTraceEnabled()) { + LOG.trace("Looking for a random customer to fly on {}", search_flight); + } + CustomerId customer_id = profile.getRandomCustomerId(airport_depart_id); + + // We will go for a random one if: + // (1) The Customer is already booked on this Flight + // (2) We already made a new Reservation just now for this Customer + int tries = SEATSConstants.FLIGHTS_NUM_SEATS; + while (tries-- > 0 + && (customer_id == null)) { // || isCustomerBookedOnFlight(customer_id, flight_id))) { + customer_id = profile.getRandomCustomerId(); if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); - } - - proc.run(conn, reservation.id, reservation.customer_id.encode(), reservation.flight_id.encode(), reservation.seatnum, price, attributes); - - // Mark this seat as successfully reserved - seats.set(reservation.seatnum); - - // Set it up so we can play with it later - this.requeueReservation(reservation); - - return (true); + LOG.trace("RANDOM CUSTOMER: {}", customer_id); + } + } + Reservation r = + new Reservation( + profile.getNextReservationId(getId()), search_flight, customer_id, seatnum); + seats.set(seatnum); + tmp_reservations.add(r); + if (LOG.isTraceEnabled()) { + LOG.trace( + "QUEUED INSERT: {} / {} -> {}", search_flight, search_flight.encode(), customer_id); + } } - // ---------------------------------------------------------------- - // UpdateCustomer - // ---------------------------------------------------------------- - - private boolean executeUpdateCustomer(Connection conn, UpdateCustomer proc) throws SQLException { - // Pick a random customer and then have at it! - CustomerId customer_id = this.profile.getRandomCustomerId(); - - String c_id = null; - String c_id_str = null; - long attr0 = this.rng.nextLong(); - long attr1 = this.rng.nextLong(); - long update_ff = (rng.number(1, 100) <= SEATSConstants.PROB_UPDATE_FREQUENT_FLYER ? 1 : 0); + if (!tmp_reservations.isEmpty()) { + Collections.shuffle(tmp_reservations); + cache.addAll(tmp_reservations); + while (cache.size() > SEATSConstants.CACHE_LIMIT_PENDING_INSERTS) { + cache.remove(); + } + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Stored %d pending inserts for %s [totalPendingInserts=%d]", + tmp_reservations.size(), search_flight, cache.size())); + } + } + return (true); + } + + // ---------------------------------------------------------------- + // NewReservation + // ---------------------------------------------------------------- + + private boolean executeNewReservation(Connection conn, NewReservation proc) throws SQLException { + Reservation reservation = null; + BitSet seats = null; + LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_INSERTS); + + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "Attempting to get a new pending insert Reservation [totalPendingInserts=%d]", + cache.size())); + } + while (reservation == null) { + Reservation r = cache.poll(); + if (r == null) { + LOG.warn("Unable to execute {} - No available reservations to insert", proc); + break; + } - // Update with the Customer's id as a string - if (rng.nextInt(100) < SEATSConstants.PROB_UPDATE_WITH_CUSTOMER_ID_STR) { - c_id_str = customer_id.encode(); - } - // Update using their Customer id - else { - c_id = customer_id.encode(); - } + seats = getSeatsBitSet(r.flight_id); - if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); + if (isFlightFull(seats)) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s is full", r.flight_id)); + } + continue; + } + // PAVLO: Not sure why this is always coming back as reserved? + // else if (seats.get(r.seatnum)) { + // if (LOG.isDebugEnabled()) + // LOG.debug(String.format("Seat #%d on %s is already booked", r.seatnum, + // r.flight_id)); + // continue; + // } + else if (isCustomerBookedOnFlight(r.customer_id, r.flight_id)) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s is already booked on %s", r.customer_id, r.flight_id)); } + continue; + } + reservation = r; + } + if (reservation == null) { + LOG.warn("Failed to find a valid pending insert Reservation\n{}", this); + return (false); + } + // Generate a random price for now + double price = + 2.0 + * rng.number( + SEATSConstants.RESERVATION_PRICE_MIN, SEATSConstants.RESERVATION_PRICE_MAX); - proc.run(conn, c_id, c_id_str, update_ff, attr0, attr1); + // Generate random attributes + long[] attributes = new long[9]; + for (int i = 0; i < attributes.length; i++) { + attributes[i] = rng.nextLong(); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); + } - return (true); + proc.run( + conn, + reservation.id, + reservation.customer_id.encode(), + reservation.flight_id.encode(), + reservation.seatnum, + price, + attributes); + + // Mark this seat as successfully reserved + seats.set(reservation.seatnum); + + // Set it up so we can play with it later + this.requeueReservation(reservation); + + return (true); + } + + // ---------------------------------------------------------------- + // UpdateCustomer + // ---------------------------------------------------------------- + + private boolean executeUpdateCustomer(Connection conn, UpdateCustomer proc) throws SQLException { + // Pick a random customer and then have at it! + CustomerId customer_id = this.profile.getRandomCustomerId(); + + String c_id = null; + String c_id_str = null; + long attr0 = this.rng.nextLong(); + long attr1 = this.rng.nextLong(); + long update_ff = (rng.number(1, 100) <= SEATSConstants.PROB_UPDATE_FREQUENT_FLYER ? 1 : 0); + + // Update with the Customer's id as a string + if (rng.nextInt(100) < SEATSConstants.PROB_UPDATE_WITH_CUSTOMER_ID_STR) { + c_id_str = customer_id.encode(); + } + // Update using their Customer id + else { + c_id = customer_id.encode(); } - // ---------------------------------------------------------------- - // UpdateReservation - // ---------------------------------------------------------------- + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); + } - private boolean executeUpdateReservation(Connection conn, UpdateReservation proc) throws SQLException { - LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_UPDATES); + proc.run(conn, c_id, c_id_str, update_ff, attr0, attr1); + return (true); + } - if (LOG.isTraceEnabled()) { - LOG.trace("Let's look for a Reservation that we can update"); - } + // ---------------------------------------------------------------- + // UpdateReservation + // ---------------------------------------------------------------- - // Pull off the first pending seat change and throw that ma at the server - Reservation r = null; - try { - r = cache.poll(); - } catch (Throwable ex) { - // Nothing - } - if (r == null) { - LOG.debug(String.format("Failed to find Reservation to update [cache=%d]", cache.size())); - return (false); - } - if (LOG.isTraceEnabled()) { - LOG.trace("Ok let's try to update {}", r); - } + private boolean executeUpdateReservation(Connection conn, UpdateReservation proc) + throws SQLException { + LinkedList cache = CACHE_RESERVATIONS.get(CacheType.PENDING_UPDATES); - long value = rng.number(1, 1 << 20); - long attribute_idx = rng.nextInt(UpdateReservation.NUM_UPDATES); - long seatnum = rng.number(0, SEATSConstants.FLIGHTS_NUM_SEATS - 1); + if (LOG.isTraceEnabled()) { + LOG.trace("Let's look for a Reservation that we can update"); + } - if (LOG.isTraceEnabled()) { - LOG.trace("Calling {}", proc); - } + // Pull off the first pending seat change and throw that ma at the server + Reservation r = null; + try { + r = cache.poll(); + } catch (Throwable ex) { + // Nothing + } + if (r == null) { + LOG.debug(String.format("Failed to find Reservation to update [cache=%d]", cache.size())); + return (false); + } + if (LOG.isTraceEnabled()) { + LOG.trace("Ok let's try to update {}", r); + } + long value = rng.number(1, 1 << 20); + long attribute_idx = rng.nextInt(UpdateReservation.NUM_UPDATES); + long seatnum = rng.number(0, SEATSConstants.FLIGHTS_NUM_SEATS - 1); - proc.run(conn, r.id, r.flight_id.encode(), r.customer_id.encode(), seatnum, attribute_idx, value); + if (LOG.isTraceEnabled()) { + LOG.trace("Calling {}", proc); + } - requeueReservation(r); + proc.run( + conn, r.id, r.flight_id.encode(), r.customer_id.encode(), seatnum, attribute_idx, value); - return (true); - } + requeueReservation(r); -} \ No newline at end of file + return (true); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/Config.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/Config.java index 2043f8eb3..ae9980279 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/Config.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/Config.java @@ -4,43 +4,49 @@ public class Config { - private final List configProfile; - private final List configHistogram; - private final List countryCodes; - private final List airportCodes; - private final List airlineCodes; - private final List flights; - - public Config(List configProfile, List configHistogram, List countryCodes, List airportCodes, List airlineCodes, List flights) { - this.configProfile = configProfile; - this.configHistogram = configHistogram; - this.countryCodes = countryCodes; - this.airportCodes = airportCodes; - this.airlineCodes = airlineCodes; - this.flights = flights; - } - - public List getConfigProfile() { - return configProfile; - } - - public List getConfigHistogram() { - return configHistogram; - } - - public List getCountryCodes() { - return countryCodes; - } - - public List getAirportCodes() { - return airportCodes; - } - - public List getAirlineCodes() { - return airlineCodes; - } - - public List getFlights() { - return flights; - } + private final List configProfile; + private final List configHistogram; + private final List countryCodes; + private final List airportCodes; + private final List airlineCodes; + private final List flights; + + public Config( + List configProfile, + List configHistogram, + List countryCodes, + List airportCodes, + List airlineCodes, + List flights) { + this.configProfile = configProfile; + this.configHistogram = configHistogram; + this.countryCodes = countryCodes; + this.airportCodes = airportCodes; + this.airlineCodes = airlineCodes; + this.flights = flights; + } + + public List getConfigProfile() { + return configProfile; + } + + public List getConfigHistogram() { + return configHistogram; + } + + public List getCountryCodes() { + return countryCodes; + } + + public List getAirportCodes() { + return airportCodes; + } + + public List getAirlineCodes() { + return airlineCodes; + } + + public List getFlights() { + return flights; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/DeleteReservation.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/DeleteReservation.java index 09ed2a227..1269ca422 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/DeleteReservation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/DeleteReservation.java @@ -15,162 +15,177 @@ * */ - package com.oltpbenchmark.benchmarks.seats.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DeleteReservation extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(DeleteReservation.class); - - public final SQLStmt GetCustomerByIdStr = new SQLStmt( - "SELECT C_ID " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + - " WHERE C_ID_STR = ?"); - - public final SQLStmt GetCustomerByFFNumber = new SQLStmt( - "SELECT C_ID, FF_AL_ID " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + ", " + - SEATSConstants.TABLENAME_FREQUENT_FLYER + - " WHERE FF_C_ID_STR = ? AND FF_C_ID = C_ID"); - - public final SQLStmt GetCustomerReservation = new SQLStmt( - "SELECT C_SATTR00, C_SATTR02, C_SATTR04, " + - " C_IATTR00, C_IATTR02, C_IATTR04, C_IATTR06, " + - " F_SEATS_LEFT, " + - " R_ID, R_SEAT, R_PRICE, R_IATTR00 " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + ", " + - SEATSConstants.TABLENAME_FLIGHT + ", " + - SEATSConstants.TABLENAME_RESERVATION + - " WHERE C_ID = ? AND C_ID = R_C_ID " + - " AND F_ID = ? AND F_ID = R_F_ID " - ); - - public final SQLStmt DeleteReservation = new SQLStmt( - "DELETE FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_ID = ? AND R_C_ID = ? AND R_F_ID = ?"); - - public final SQLStmt UpdateFlight = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_FLIGHT + - " SET F_SEATS_LEFT = F_SEATS_LEFT + 1 " + - " WHERE F_ID = ? "); - - public final SQLStmt UpdateCustomer = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_CUSTOMER + - " SET C_BALANCE = C_BALANCE + ?, " + - " C_IATTR00 = ?, " + - " C_IATTR10 = C_IATTR10 - 1, " + - " C_IATTR11 = C_IATTR10 - 1 " + - " WHERE C_ID = ? "); - - public final SQLStmt UpdateFrequentFlyer = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_FREQUENT_FLYER + - " SET FF_IATTR10 = FF_IATTR10 - 1 " + - " WHERE FF_C_ID = ? " + - " AND FF_AL_ID = ?"); - - public void run(Connection conn, String f_id, String c_id, String c_id_str, String ff_c_id_str, Long ff_al_id) throws SQLException { - - - // If we weren't given the customer id, then look it up - if (c_id == null) { - - - boolean has_al_id = false; - String parameter; - SQLStmt sqlStmt; - - // Use the customer's id as a string - if (c_id_str != null && c_id_str.length() > 0) { - sqlStmt = GetCustomerByIdStr; - parameter = c_id_str; - } - // Otherwise use their FrequentFlyer information - else { - sqlStmt = GetCustomerByFFNumber; - parameter = ff_c_id_str; - has_al_id = true; - } - - try (PreparedStatement stmt = this.getPreparedStatement(conn, sqlStmt, parameter)) { - - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - c_id = results.getString(1); - if (has_al_id) { - ff_al_id = results.getLong(2); - } - } else { - LOG.debug("No Customer record was found [c_id_str={}, ff_c_id_str={}, ff_al_id={}]", c_id_str, ff_c_id_str, ff_al_id); - return; - } - } - } - } - - // Now get the result of the information that we need - // If there is no valid customer record, then throw an abort - // This should happen 5% of the time - - long c_iattr00; - long seats_left; - long r_id; - double r_price; - try (PreparedStatement stmt = this.getPreparedStatement(conn, GetCustomerReservation)) { - stmt.setString(1, c_id); - stmt.setString(2, f_id); - try (ResultSet results = stmt.executeQuery()) { - if (!results.next()) { - LOG.debug("No Customer information record found for id '{}'", c_id); - return; - } - c_iattr00 = results.getLong(4) + 1; - seats_left = results.getLong(8); - r_id = results.getLong(9); - r_price = results.getDouble(11); + private static final Logger LOG = LoggerFactory.getLogger(DeleteReservation.class); + + public final SQLStmt GetCustomerByIdStr = + new SQLStmt( + "SELECT C_ID " + " FROM " + SEATSConstants.TABLENAME_CUSTOMER + " WHERE C_ID_STR = ?"); + + public final SQLStmt GetCustomerByFFNumber = + new SQLStmt( + "SELECT C_ID, FF_AL_ID " + + " FROM " + + SEATSConstants.TABLENAME_CUSTOMER + + ", " + + SEATSConstants.TABLENAME_FREQUENT_FLYER + + " WHERE FF_C_ID_STR = ? AND FF_C_ID = C_ID"); + + public final SQLStmt GetCustomerReservation = + new SQLStmt( + "SELECT C_SATTR00, C_SATTR02, C_SATTR04, " + + " C_IATTR00, C_IATTR02, C_IATTR04, C_IATTR06, " + + " F_SEATS_LEFT, " + + " R_ID, R_SEAT, R_PRICE, R_IATTR00 " + + " FROM " + + SEATSConstants.TABLENAME_CUSTOMER + + ", " + + SEATSConstants.TABLENAME_FLIGHT + + ", " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE C_ID = ? AND C_ID = R_C_ID " + + " AND F_ID = ? AND F_ID = R_F_ID "); + + public final SQLStmt DeleteReservation = + new SQLStmt( + "DELETE FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_ID = ? AND R_C_ID = ? AND R_F_ID = ?"); + + public final SQLStmt UpdateFlight = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_FLIGHT + + " SET F_SEATS_LEFT = F_SEATS_LEFT + 1 " + + " WHERE F_ID = ? "); + + public final SQLStmt UpdateCustomer = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_CUSTOMER + + " SET C_BALANCE = C_BALANCE + ?, " + + " C_IATTR00 = ?, " + + " C_IATTR10 = C_IATTR10 - 1, " + + " C_IATTR11 = C_IATTR10 - 1 " + + " WHERE C_ID = ? "); + + public final SQLStmt UpdateFrequentFlyer = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_FREQUENT_FLYER + + " SET FF_IATTR10 = FF_IATTR10 - 1 " + + " WHERE FF_C_ID = ? " + + " AND FF_AL_ID = ?"); + + public void run( + Connection conn, String f_id, String c_id, String c_id_str, String ff_c_id_str, Long ff_al_id) + throws SQLException { + + // If we weren't given the customer id, then look it up + if (c_id == null) { + + boolean has_al_id = false; + String parameter; + SQLStmt sqlStmt; + + // Use the customer's id as a string + if (c_id_str != null && c_id_str.length() > 0) { + sqlStmt = GetCustomerByIdStr; + parameter = c_id_str; + } + // Otherwise use their FrequentFlyer information + else { + sqlStmt = GetCustomerByFFNumber; + parameter = ff_c_id_str; + has_al_id = true; + } + + try (PreparedStatement stmt = this.getPreparedStatement(conn, sqlStmt, parameter)) { + + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + c_id = results.getString(1); + if (has_al_id) { + ff_al_id = results.getLong(2); } + } else { + LOG.debug( + "No Customer record was found [c_id_str={}, ff_c_id_str={}, ff_al_id={}]", + c_id_str, + ff_c_id_str, + ff_al_id); + return; + } } + } + } - - // Now delete all of the flights that they have on this flight - try (PreparedStatement stmt = this.getPreparedStatement(conn, DeleteReservation, r_id, c_id, f_id)) { - stmt.executeUpdate(); - } - - - // Update Available Seats on Flight - try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateFlight, f_id)) { - stmt.executeUpdate(); - } - - // Update Customer's Balance - try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateCustomer)) { - stmt.setBigDecimal(1, BigDecimal.valueOf(-1 * r_price)); - stmt.setLong(2, c_iattr00); - stmt.setString(3, c_id); - stmt.executeUpdate(); + // Now get the result of the information that we need + // If there is no valid customer record, then throw an abort + // This should happen 5% of the time + + long c_iattr00; + long seats_left; + long r_id; + double r_price; + try (PreparedStatement stmt = this.getPreparedStatement(conn, GetCustomerReservation)) { + stmt.setString(1, c_id); + stmt.setString(2, f_id); + try (ResultSet results = stmt.executeQuery()) { + if (!results.next()) { + LOG.debug("No Customer information record found for id '{}'", c_id); + return; } + c_iattr00 = results.getLong(4) + 1; + seats_left = results.getLong(8); + r_id = results.getLong(9); + r_price = results.getDouble(11); + } + } + // Now delete all of the flights that they have on this flight + try (PreparedStatement stmt = + this.getPreparedStatement(conn, DeleteReservation, r_id, c_id, f_id)) { + stmt.executeUpdate(); + } - // Update Customer's Frequent Flyer Information (Optional) - if (ff_al_id != null) { - try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateFrequentFlyer, c_id, ff_al_id)) { - stmt.executeUpdate(); - } - } + // Update Available Seats on Flight + try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateFlight, f_id)) { + stmt.executeUpdate(); + } - LOG.debug(String.format("Deleted reservation on flight %s for customer %s [seatsLeft=%d]", f_id, c_id, seats_left + 1)); + // Update Customer's Balance + try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateCustomer)) { + stmt.setBigDecimal(1, BigDecimal.valueOf(-1 * r_price)); + stmt.setLong(2, c_iattr00); + stmt.setString(3, c_id); + stmt.executeUpdate(); + } + // Update Customer's Frequent Flyer Information (Optional) + if (ff_al_id != null) { + try (PreparedStatement stmt = + this.getPreparedStatement(conn, UpdateFrequentFlyer, c_id, ff_al_id)) { + stmt.executeUpdate(); + } } + LOG.debug( + String.format( + "Deleted reservation on flight %s for customer %s [seatsLeft=%d]", + f_id, c_id, seats_left + 1)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindFlights.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindFlights.java index b4684465f..70efa5ddc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindFlights.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindFlights.java @@ -15,161 +15,166 @@ * */ - package com.oltpbenchmark.benchmarks.seats.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.*; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class FindFlights extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(FindFlights.class); - - - public final SQLStmt GetNearbyAirports = new SQLStmt( - "SELECT * " + - " FROM " + SEATSConstants.TABLENAME_AIRPORT_DISTANCE + - " WHERE D_AP_ID0 = ? " + - " AND D_DISTANCE <= ? " + - " ORDER BY D_DISTANCE ASC " - ); - - public final SQLStmt GetAirportInfo = new SQLStmt( - "SELECT AP_CODE, AP_NAME, AP_CITY, AP_LONGITUDE, AP_LATITUDE, " + - " CO_ID, CO_NAME, CO_CODE_2, CO_CODE_3 " + - " FROM " + SEATSConstants.TABLENAME_AIRPORT + ", " + - SEATSConstants.TABLENAME_COUNTRY + - " WHERE AP_ID = ? AND AP_CO_ID = CO_ID " - ); - - private final static String BaseGetFlights = - "SELECT F_ID, F_AL_ID, F_SEATS_LEFT, " + - " F_DEPART_AP_ID, F_DEPART_TIME, F_ARRIVE_AP_ID, F_ARRIVE_TIME, " + - " AL_NAME, AL_IATTR00, AL_IATTR01 " + - " FROM " + SEATSConstants.TABLENAME_FLIGHT + ", " + - SEATSConstants.TABLENAME_AIRLINE + - " WHERE F_DEPART_AP_ID = ? " + - " AND F_DEPART_TIME >= ? AND F_DEPART_TIME <= ? " + - " AND F_AL_ID = AL_ID " + - " AND F_ARRIVE_AP_ID IN (??)"; - - public final SQLStmt GetFlights1 = new SQLStmt(BaseGetFlights, 1); - public final SQLStmt GetFlights2 = new SQLStmt(BaseGetFlights, 2); - public final SQLStmt GetFlights3 = new SQLStmt(BaseGetFlights, 3); - - public List run(Connection conn, long depart_aid, long arrive_aid, Timestamp start_date, Timestamp end_date, long distance) throws SQLException { - try { - - - final List arrive_aids = new ArrayList<>(); - arrive_aids.add(arrive_aid); - - final List finalResults = new ArrayList<>(); - - if (distance > 0) { - // First get the nearby airports for the departure and arrival cities - try (PreparedStatement nearby_stmt = this.getPreparedStatement(conn, GetNearbyAirports, depart_aid, distance)) { - try (ResultSet nearby_results = nearby_stmt.executeQuery()) { - while (nearby_results.next()) { - long aid = nearby_results.getLong(1); - double aid_distance = nearby_results.getDouble(2); - - LOG.debug("DEPART NEARBY: {} distance={} miles", aid, aid_distance); - - arrive_aids.add(aid); - } - } - } + private static final Logger LOG = LoggerFactory.getLogger(FindFlights.class); + + public final SQLStmt GetNearbyAirports = + new SQLStmt( + "SELECT * " + + " FROM " + + SEATSConstants.TABLENAME_AIRPORT_DISTANCE + + " WHERE D_AP_ID0 = ? " + + " AND D_DISTANCE <= ? " + + " ORDER BY D_DISTANCE ASC "); + + public final SQLStmt GetAirportInfo = + new SQLStmt( + "SELECT AP_CODE, AP_NAME, AP_CITY, AP_LONGITUDE, AP_LATITUDE, " + + " CO_ID, CO_NAME, CO_CODE_2, CO_CODE_3 " + + " FROM " + + SEATSConstants.TABLENAME_AIRPORT + + ", " + + SEATSConstants.TABLENAME_COUNTRY + + " WHERE AP_ID = ? AND AP_CO_ID = CO_ID "); + + private static final String BaseGetFlights = + "SELECT F_ID, F_AL_ID, F_SEATS_LEFT, " + + " F_DEPART_AP_ID, F_DEPART_TIME, F_ARRIVE_AP_ID, F_ARRIVE_TIME, " + + " AL_NAME, AL_IATTR00, AL_IATTR01 " + + " FROM " + + SEATSConstants.TABLENAME_FLIGHT + + ", " + + SEATSConstants.TABLENAME_AIRLINE + + " WHERE F_DEPART_AP_ID = ? " + + " AND F_DEPART_TIME >= ? AND F_DEPART_TIME <= ? " + + " AND F_AL_ID = AL_ID " + + " AND F_ARRIVE_AP_ID IN (??)"; + + public final SQLStmt GetFlights1 = new SQLStmt(BaseGetFlights, 1); + public final SQLStmt GetFlights2 = new SQLStmt(BaseGetFlights, 2); + public final SQLStmt GetFlights3 = new SQLStmt(BaseGetFlights, 3); + + public List run( + Connection conn, + long depart_aid, + long arrive_aid, + Timestamp start_date, + Timestamp end_date, + long distance) + throws SQLException { + try { + + final List arrive_aids = new ArrayList<>(); + arrive_aids.add(arrive_aid); + + final List finalResults = new ArrayList<>(); + + if (distance > 0) { + // First get the nearby airports for the departure and arrival cities + try (PreparedStatement nearby_stmt = + this.getPreparedStatement(conn, GetNearbyAirports, depart_aid, distance)) { + try (ResultSet nearby_results = nearby_stmt.executeQuery()) { + while (nearby_results.next()) { + long aid = nearby_results.getLong(1); + double aid_distance = nearby_results.getDouble(2); + + LOG.debug("DEPART NEARBY: {} distance={} miles", aid, aid_distance); + + arrive_aids.add(aid); } + } + } + } + + // H-Store doesn't support IN clauses, so we'll only get nearby flights to nearby arrival + // cities + int num_nearby = arrive_aids.size(); + if (num_nearby > 0) { + SQLStmt sqlStmt; + if (num_nearby == 1) { + sqlStmt = GetFlights1; + } else if (num_nearby == 2) { + sqlStmt = GetFlights2; + } else { + sqlStmt = GetFlights3; + } - // H-Store doesn't support IN clauses, so we'll only get nearby flights to nearby arrival cities - int num_nearby = arrive_aids.size(); - if (num_nearby > 0) { - SQLStmt sqlStmt; - if (num_nearby == 1) { - sqlStmt = GetFlights1; - } else if (num_nearby == 2) { - sqlStmt = GetFlights2; - } else { - sqlStmt = GetFlights3; + try (PreparedStatement f_stmt = this.getPreparedStatement(conn, sqlStmt)) { + + // Set Parameters + f_stmt.setLong(1, depart_aid); + f_stmt.setTimestamp(2, start_date); + f_stmt.setTimestamp(3, end_date); + for (int i = 0, cnt = Math.min(3, num_nearby); i < cnt; i++) { + f_stmt.setLong(4 + i, arrive_aids.get(i)); + } + + // Process Result + try (ResultSet flightResults = f_stmt.executeQuery()) { + + try (PreparedStatement ai_stmt = this.getPreparedStatement(conn, GetAirportInfo)) { + while (flightResults.next()) { + long f_depart_airport = flightResults.getLong(4); + long f_arrive_airport = flightResults.getLong(6); + + Object[] row = new Object[13]; + int r = 0; + + row[r++] = flightResults.getString(1); // [00] F_ID + row[r++] = flightResults.getLong(3); // [01] SEATS_LEFT + row[r++] = flightResults.getString(8); // [02] AL_NAME + + // DEPARTURE AIRPORT + ai_stmt.setLong(1, f_depart_airport); + try (ResultSet ai_results = ai_stmt.executeQuery()) { + ai_results.next(); + + row[r++] = flightResults.getDate(5); // [03] DEPART_TIME + row[r++] = ai_results.getString(1); // [04] DEPART_AP_CODE + row[r++] = ai_results.getString(2); // [05] DEPART_AP_NAME + row[r++] = ai_results.getString(3); // [06] DEPART_AP_CITY + row[r++] = ai_results.getString(7); // [07] DEPART_AP_COUNTRY } + // ARRIVAL AIRPORT + ai_stmt.setLong(1, f_arrive_airport); + try (ResultSet ai_results = ai_stmt.executeQuery()) { + ai_results.next(); - try (PreparedStatement f_stmt = this.getPreparedStatement(conn, sqlStmt)) { - - // Set Parameters - f_stmt.setLong(1, depart_aid); - f_stmt.setTimestamp(2, start_date); - f_stmt.setTimestamp(3, end_date); - for (int i = 0, cnt = Math.min(3, num_nearby); i < cnt; i++) { - f_stmt.setLong(4 + i, arrive_aids.get(i)); - } - - - // Process Result - try (ResultSet flightResults = f_stmt.executeQuery()) { - - - try (PreparedStatement ai_stmt = this.getPreparedStatement(conn, GetAirportInfo)) { - while (flightResults.next()) { - long f_depart_airport = flightResults.getLong(4); - long f_arrive_airport = flightResults.getLong(6); - - Object[] row = new Object[13]; - int r = 0; - - row[r++] = flightResults.getString(1); // [00] F_ID - row[r++] = flightResults.getLong(3); // [01] SEATS_LEFT - row[r++] = flightResults.getString(8); // [02] AL_NAME - - // DEPARTURE AIRPORT - ai_stmt.setLong(1, f_depart_airport); - try (ResultSet ai_results = ai_stmt.executeQuery()) { - ai_results.next(); - - row[r++] = flightResults.getDate(5); // [03] DEPART_TIME - row[r++] = ai_results.getString(1); // [04] DEPART_AP_CODE - row[r++] = ai_results.getString(2); // [05] DEPART_AP_NAME - row[r++] = ai_results.getString(3); // [06] DEPART_AP_CITY - row[r++] = ai_results.getString(7); // [07] DEPART_AP_COUNTRY - } - - // ARRIVAL AIRPORT - ai_stmt.setLong(1, f_arrive_airport); - try (ResultSet ai_results = ai_stmt.executeQuery()) { - ai_results.next(); - - row[r++] = flightResults.getDate(7); // [08] ARRIVE_TIME - row[r++] = ai_results.getString(1); // [09] ARRIVE_AP_CODE - row[r++] = ai_results.getString(2); // [10] ARRIVE_AP_NAME - row[r++] = ai_results.getString(3); // [11] ARRIVE_AP_CITY - row[r] = ai_results.getString(7); // [12] ARRIVE_AP_COUNTRY - } - - finalResults.add(row); - - } - } - } + row[r++] = flightResults.getDate(7); // [08] ARRIVE_TIME + row[r++] = ai_results.getString(1); // [09] ARRIVE_AP_CODE + row[r++] = ai_results.getString(2); // [10] ARRIVE_AP_NAME + row[r++] = ai_results.getString(3); // [11] ARRIVE_AP_CITY + row[r] = ai_results.getString(7); // [12] ARRIVE_AP_COUNTRY } + finalResults.add(row); + } } + } + } + } - LOG.debug("Flight Information:\n{}", finalResults); + LOG.debug("Flight Information:\n{}", finalResults); - return (finalResults); - } catch (SQLException esql) { - LOG.error("caught SQLException in FindFlights:{}", esql, esql); - throw esql; - } catch (Exception e) { - LOG.error("caught Exception in FindFlights:{}", e, e); - } - return null; + return (finalResults); + } catch (SQLException esql) { + LOG.error("caught SQLException in FindFlights:{}", esql, esql); + throw esql; + } catch (Exception e) { + LOG.error("caught Exception in FindFlights:{}", e, e); } + return null; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindOpenSeats.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindOpenSeats.java index d7f31424d..ec49daa4a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindOpenSeats.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/FindOpenSeats.java @@ -43,112 +43,112 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class FindOpenSeats extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(FindOpenSeats.class); - - public final SQLStmt GetFlight = new SQLStmt( - "SELECT F_STATUS, F_BASE_PRICE, F_SEATS_TOTAL, F_SEATS_LEFT, " + - " (F_BASE_PRICE + (F_BASE_PRICE * (1 - (F_SEATS_LEFT / F_SEATS_TOTAL)))) AS F_PRICE " + - " FROM " + SEATSConstants.TABLENAME_FLIGHT + - " WHERE F_ID = ?" - ); - - public final SQLStmt GetSeats = new SQLStmt( - "SELECT R_ID, R_F_ID, R_SEAT " + - " FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_F_ID = ?" - ); - - public Object[][] run(Connection conn, String f_id) throws SQLException { - - // 150 seats - final long[] seatmap = new long[] - {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - - - double base_price = 0.0; - long seats_total = 0; - long seats_left = 0; - double seat_price = 0.0; - - // First calculate the seat price using the flight's base price - // and the number of seats that remaining - try (PreparedStatement f_stmt = this.getPreparedStatement(conn, GetFlight)) { - f_stmt.setString(1, f_id); - try (ResultSet f_results = f_stmt.executeQuery()) { - if (f_results.next()) { - - // long status = results[0].getLong(0); - base_price = f_results.getDouble(2); - seats_total = f_results.getLong(3); - seats_left = f_results.getLong(4); - seat_price = f_results.getDouble(5); - } else { - LOG.warn("flight {} had no seats; this may be a data problem or a code problem. previously this threw an unhandled exception.", f_id); - } - } + private static final Logger LOG = LoggerFactory.getLogger(FindOpenSeats.class); + + public final SQLStmt GetFlight = + new SQLStmt( + "SELECT F_STATUS, F_BASE_PRICE, F_SEATS_TOTAL, F_SEATS_LEFT, " + + " (F_BASE_PRICE + (F_BASE_PRICE * (1 - (F_SEATS_LEFT / F_SEATS_TOTAL)))) AS F_PRICE " + + " FROM " + + SEATSConstants.TABLENAME_FLIGHT + + " WHERE F_ID = ?"); + + public final SQLStmt GetSeats = + new SQLStmt( + "SELECT R_ID, R_F_ID, R_SEAT " + + " FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_F_ID = ?"); + + public Object[][] run(Connection conn, String f_id) throws SQLException { + + // 150 seats + final long[] seatmap = + new long[] { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + }; + + double base_price = 0.0; + long seats_total = 0; + long seats_left = 0; + double seat_price = 0.0; + + // First calculate the seat price using the flight's base price + // and the number of seats that remaining + try (PreparedStatement f_stmt = this.getPreparedStatement(conn, GetFlight)) { + f_stmt.setString(1, f_id); + try (ResultSet f_results = f_stmt.executeQuery()) { + if (f_results.next()) { + + // long status = results[0].getLong(0); + base_price = f_results.getDouble(2); + seats_total = f_results.getLong(3); + seats_left = f_results.getLong(4); + seat_price = f_results.getDouble(5); + } else { + LOG.warn( + "flight {} had no seats; this may be a data problem or a code problem. previously this threw an unhandled exception.", + f_id); } + } + } - // TODO: Figure out why this doesn't match the SQL - // Possible explanation: Floating point numbers are approximations; - // there is no exact representation of (for example) 0.01. - // Some databases (like PostgreSQL) will use exact types, - // such as numeric, for intermediate values. (This is - // more-or-less equivalent to java.math.BigDecimal.) - double _seat_price = base_price + (base_price * (1.0 - (seats_left / (double) seats_total))); - - LOG.debug(String.format("Flight %s - SQL[%.2f] <-> JAVA[%.2f] [basePrice=%f, total=%d, left=%d]", - f_id, seat_price, _seat_price, base_price, seats_total, seats_left)); - - - // Then build the seat map of the remaining seats - try (PreparedStatement s_stmt = this.getPreparedStatement(conn, GetSeats)) { - s_stmt.setString(1, f_id); - try (ResultSet s_results = s_stmt.executeQuery()) { - while (s_results.next()) { - long r_id = s_results.getLong(1); - int seatnum = s_results.getInt(3); - - LOG.debug(String.format("Reserved Seat: fid %s / rid %d / seat %d", f_id, r_id, seatnum)); - - - seatmap[seatnum] = 1; - } - } + // TODO: Figure out why this doesn't match the SQL + // Possible explanation: Floating point numbers are approximations; + // there is no exact representation of (for example) 0.01. + // Some databases (like PostgreSQL) will use exact types, + // such as numeric, for intermediate values. (This is + // more-or-less equivalent to java.math.BigDecimal.) + double _seat_price = base_price + (base_price * (1.0 - (seats_left / (double) seats_total))); + + LOG.debug( + String.format( + "Flight %s - SQL[%.2f] <-> JAVA[%.2f] [basePrice=%f, total=%d, left=%d]", + f_id, seat_price, _seat_price, base_price, seats_total, seats_left)); + + // Then build the seat map of the remaining seats + try (PreparedStatement s_stmt = this.getPreparedStatement(conn, GetSeats)) { + s_stmt.setString(1, f_id); + try (ResultSet s_results = s_stmt.executeQuery()) { + while (s_results.next()) { + long r_id = s_results.getLong(1); + int seatnum = s_results.getInt(3); + + LOG.debug(String.format("Reserved Seat: fid %s / rid %d / seat %d", f_id, r_id, seatnum)); + + seatmap[seatnum] = 1; } + } + } - int ctr = 0; - Object[][] returnResults = new Object[SEATSConstants.FLIGHTS_NUM_SEATS][]; - for (int i = 0; i < seatmap.length; ++i) { - if (seatmap[i] == -1) { - // Charge more for the first seats - double price = seat_price * (i < SEATSConstants.FLIGHTS_FIRST_CLASS_OFFSET ? 2.0 : 1.0); - Object[] row = new Object[]{f_id, i, price}; - returnResults[ctr++] = row; - if (ctr == returnResults.length) { - break; - } - } + int ctr = 0; + Object[][] returnResults = new Object[SEATSConstants.FLIGHTS_NUM_SEATS][]; + for (int i = 0; i < seatmap.length; ++i) { + if (seatmap[i] == -1) { + // Charge more for the first seats + double price = seat_price * (i < SEATSConstants.FLIGHTS_FIRST_CLASS_OFFSET ? 2.0 : 1.0); + Object[] row = new Object[] {f_id, i, price}; + returnResults[ctr++] = row; + if (ctr == returnResults.length) { + break; } - - return returnResults; + } } + return returnResults; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/LoadConfig.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/LoadConfig.java index 309285716..827d44ed0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/LoadConfig.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/LoadConfig.java @@ -22,7 +22,6 @@ import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -31,103 +30,105 @@ public class LoadConfig extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public final SQLStmt getConfigProfile = new SQLStmt( - "SELECT * FROM " + SEATSConstants.TABLENAME_CONFIG_PROFILE - ); - - public final SQLStmt getConfigHistogram = new SQLStmt( - "SELECT * FROM " + SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS - ); - - public final SQLStmt getCountryCodes = new SQLStmt( - "SELECT CO_ID, CO_CODE_3 FROM " + SEATSConstants.TABLENAME_COUNTRY - ); - - public final SQLStmt getAirportCodes = new SQLStmt( - "SELECT AP_ID, AP_CODE FROM " + SEATSConstants.TABLENAME_AIRPORT - ); - - public final SQLStmt getAirlineCodes = new SQLStmt( - "SELECT AL_ID, AL_IATA_CODE FROM " + SEATSConstants.TABLENAME_AIRLINE + - " WHERE AL_IATA_CODE != ''" - ); - - public final SQLStmt getFlights = new SQLStmt( - "SELECT f_id FROM " + SEATSConstants.TABLENAME_FLIGHT + - " ORDER BY F_DEPART_TIME DESC " + - " LIMIT " + SEATSConstants.CACHE_LIMIT_FLIGHT_IDS - ); - - public Config run(Connection conn) throws SQLException { - - List configProfile; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getConfigProfile)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - configProfile = SQLUtil.toList(resultSet); - // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). - // These CLOB needs to be converted to String while the connection is alive. - - // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be attempted - // by SQLUtil.getString(Object) after the connection closes, which will result in - // java.sql.SQLRecoverableException: Closed Connection. - if (getDbType() == DatabaseType.ORACLE) { - for (Object[] configProfileInstance: configProfile) { - configProfileInstance[1] = SQLUtil.clobToString(configProfileInstance[1]); - } - } - } - } - - List histogram; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getConfigHistogram)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - histogram = SQLUtil.toList(resultSet); - // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). - // These CLOB needs to be converted to String while the connection is alive. - - // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be attempted - // by SQLUtil.getString(Object) after the connection closes, which will result in - // java.sql.SQLRecoverableException: Closed Connection. - if (getDbType() == DatabaseType.ORACLE) { - for (Object[] histogramInstance: histogram) { - histogramInstance[1] = SQLUtil.clobToString(histogramInstance[1]); - } - } - } + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public final SQLStmt getConfigProfile = + new SQLStmt("SELECT * FROM " + SEATSConstants.TABLENAME_CONFIG_PROFILE); + + public final SQLStmt getConfigHistogram = + new SQLStmt("SELECT * FROM " + SEATSConstants.TABLENAME_CONFIG_HISTOGRAMS); + + public final SQLStmt getCountryCodes = + new SQLStmt("SELECT CO_ID, CO_CODE_3 FROM " + SEATSConstants.TABLENAME_COUNTRY); + + public final SQLStmt getAirportCodes = + new SQLStmt("SELECT AP_ID, AP_CODE FROM " + SEATSConstants.TABLENAME_AIRPORT); + + public final SQLStmt getAirlineCodes = + new SQLStmt( + "SELECT AL_ID, AL_IATA_CODE FROM " + + SEATSConstants.TABLENAME_AIRLINE + + " WHERE AL_IATA_CODE != ''"); + + public final SQLStmt getFlights = + new SQLStmt( + "SELECT f_id FROM " + + SEATSConstants.TABLENAME_FLIGHT + + " ORDER BY F_DEPART_TIME DESC " + + " LIMIT " + + SEATSConstants.CACHE_LIMIT_FLIGHT_IDS); + + public Config run(Connection conn) throws SQLException { + + List configProfile; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getConfigProfile)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + configProfile = SQLUtil.toList(resultSet); + // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). + // These CLOB needs to be converted to String while the connection is alive. + + // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be + // attempted + // by SQLUtil.getString(Object) after the connection closes, which will result in + // java.sql.SQLRecoverableException: Closed Connection. + if (getDbType() == DatabaseType.ORACLE) { + for (Object[] configProfileInstance : configProfile) { + configProfileInstance[1] = SQLUtil.clobToString(configProfileInstance[1]); + } } + } + } - List countryCodes; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getCountryCodes)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - countryCodes = SQLUtil.toList(resultSet); - } + List histogram; + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, getConfigHistogram)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + histogram = SQLUtil.toList(resultSet); + // Oracle DB DDL contains some CLOB fields (for LoadConfig procedures). + // These CLOB needs to be converted to String while the connection is alive. + + // This CLOB conversion for Oracle needs to be done here, otherwise the conversion will be + // attempted + // by SQLUtil.getString(Object) after the connection closes, which will result in + // java.sql.SQLRecoverableException: Closed Connection. + if (getDbType() == DatabaseType.ORACLE) { + for (Object[] histogramInstance : histogram) { + histogramInstance[1] = SQLUtil.clobToString(histogramInstance[1]); + } } + } + } - List airportCodes; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAirportCodes)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - airportCodes = SQLUtil.toList(resultSet); - } - } + List countryCodes; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getCountryCodes)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + countryCodes = SQLUtil.toList(resultSet); + } + } - List airlineCodes; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAirlineCodes)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - airlineCodes = SQLUtil.toList(resultSet); - } - } + List airportCodes; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAirportCodes)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + airportCodes = SQLUtil.toList(resultSet); + } + } - List flights; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getFlights)) { - try (ResultSet resultSet = preparedStatement.executeQuery()) { - flights = SQLUtil.toList(resultSet); - } - } + List airlineCodes; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getAirlineCodes)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + airlineCodes = SQLUtil.toList(resultSet); + } + } - return new Config(configProfile, histogram, countryCodes, airportCodes, airlineCodes, flights); + List flights; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, getFlights)) { + try (ResultSet resultSet = preparedStatement.executeQuery()) { + flights = SQLUtil.toList(resultSet); + } } + + return new Config(configProfile, histogram, countryCodes, airportCodes, airlineCodes, flights); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/NewReservation.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/NewReservation.java index 48add09a8..114e0d40a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/NewReservation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/NewReservation.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.seats.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,190 +22,256 @@ import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.benchmarks.seats.util.CustomerId; import com.oltpbenchmark.benchmarks.seats.util.ErrorType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NewReservation extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(NewReservation.class); - - public final SQLStmt GetFlight = new SQLStmt( - "SELECT F_AL_ID, F_SEATS_LEFT, " + - SEATSConstants.TABLENAME_AIRLINE + ".* " + - " FROM " + SEATSConstants.TABLENAME_FLIGHT + ", " + - SEATSConstants.TABLENAME_AIRLINE + - " WHERE F_ID = ? AND F_AL_ID = AL_ID"); - - public final SQLStmt GetCustomer = new SQLStmt( - "SELECT C_BASE_AP_ID, C_BALANCE, C_SATTR00 " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + - " WHERE C_ID = ? "); - - public final SQLStmt CheckSeat = new SQLStmt( - "SELECT R_ID " + - " FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_F_ID = ? and R_SEAT = ?"); - - public final SQLStmt CheckCustomer = new SQLStmt( - "SELECT R_ID " + - " FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_F_ID = ? AND R_C_ID = ?"); - - public final SQLStmt UpdateFlight = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_FLIGHT + - " SET F_SEATS_LEFT = F_SEATS_LEFT - 1 " + - " WHERE F_ID = ? "); - - public final SQLStmt UpdateCustomer = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_CUSTOMER + - " SET C_IATTR10 = C_IATTR10 + 1, " + - " C_IATTR11 = C_IATTR11 + 1, " + - " C_IATTR12 = ?, " + - " C_IATTR13 = ?, " + - " C_IATTR14 = ?, " + - " C_IATTR15 = ? " + - " WHERE C_ID = ? "); - - public final SQLStmt UpdateFrequentFlyer = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_FREQUENT_FLYER + - " SET FF_IATTR10 = FF_IATTR10 + 1, " + - " FF_IATTR11 = ?, " + - " FF_IATTR12 = ?, " + - " FF_IATTR13 = ?, " + - " FF_IATTR14 = ? " + - " WHERE FF_C_ID = ? " + - " AND FF_AL_ID = ?"); - - public final SQLStmt InsertReservation = new SQLStmt( - "INSERT INTO " + SEATSConstants.TABLENAME_RESERVATION + " (" + - " R_ID, " + - " R_C_ID, " + - " R_F_ID, " + - " R_SEAT, " + - " R_PRICE, " + - " R_IATTR00, " + - " R_IATTR01, " + - " R_IATTR02, " + - " R_IATTR03, " + - " R_IATTR04, " + - " R_IATTR05, " + - " R_IATTR06, " + - " R_IATTR07, " + - " R_IATTR08 " + - ") VALUES (" + - " ?, " + // R_ID - " ?, " + // R_C_ID - " ?, " + // R_F_ID - " ?, " + // R_SEAT - " ?, " + // R_PRICE - " ?, " + // R_ATTR00 - " ?, " + // R_ATTR01 - " ?, " + // R_ATTR02 - " ?, " + // R_ATTR03 - " ?, " + // R_ATTR04 - " ?, " + // R_ATTR05 - " ?, " + // R_ATTR06 - " ?, " + // R_ATTR07 - " ? " + // R_ATTR08 - ")"); - - public void run(Connection conn, long r_id, String c_id, String f_id, long seatnum, double price, long[] attrs) throws SQLException { - boolean found; - - long airline_id; - long seats_left; - - // Flight Information - try (PreparedStatement stmt = this.getPreparedStatement(conn, GetFlight, f_id)) { - try (ResultSet results = stmt.executeQuery()) { - found = results.next(); - if (!found) { - LOG.debug("Error Type [{}]: Invalid flight {}", ErrorType.INVALID_FLIGHT_ID, f_id); - return; - } - airline_id = results.getLong(1); - seats_left = results.getLong(2); - } - } - if (seats_left <= 0) { - LOG.debug("Error Type [{}]: No more seats available for flight {}", ErrorType.NO_MORE_SEATS, f_id); - return; - } - // Check if Seat is Available - try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckSeat, f_id, seatnum)) { - try (ResultSet results = stmt.executeQuery()) { - found = results.next(); - } - } - if (found) { - LOG.debug("Error Type [{}]: Seat {} is already reserved on flight {}", ErrorType.SEAT_ALREADY_RESERVED, seatnum, f_id); - return; - } - // Check if the Customer already has a seat on this flight - try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckCustomer, f_id, c_id)) { - try (ResultSet results = stmt.executeQuery()) { - found = results.next(); - } - } - if (found) { - LOG.debug("Error Type [{}]: Customer {} already owns on a reservations on flight {}", ErrorType.CUSTOMER_ALREADY_HAS_SEAT, c_id, f_id); - return; - } - // Get Customer Information - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetCustomer, c_id)) { - try (ResultSet results = preparedStatement.executeQuery()) { - found = results.next(); - } - } - if (!found) { - LOG.debug("Error Type [{}]: Invalid customer id: {} / {}", ErrorType.INVALID_CUSTOMER_ID, c_id, new CustomerId(c_id)); - return; - } + private static final Logger LOG = LoggerFactory.getLogger(NewReservation.class); - int updated; - - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, InsertReservation)) { - preparedStatement.setLong(1, r_id); - preparedStatement.setString(2, c_id); - preparedStatement.setString(3, f_id); - preparedStatement.setLong(4, seatnum); - preparedStatement.setDouble(5, price); - for (int i = 0; i < attrs.length; i++) { - preparedStatement.setLong(6 + i, attrs[i]); - } - updated = preparedStatement.executeUpdate(); - } - if (updated != 1) { - throw new UserAbortException(String.format("Error Type [%s]: Failed to add reservation for flight #%s - Inserted %d records for InsertReservation", ErrorType.VALIDITY_ERROR, f_id, updated)); - } + public final SQLStmt GetFlight = + new SQLStmt( + "SELECT F_AL_ID, F_SEATS_LEFT, " + + SEATSConstants.TABLENAME_AIRLINE + + ".* " + + " FROM " + + SEATSConstants.TABLENAME_FLIGHT + + ", " + + SEATSConstants.TABLENAME_AIRLINE + + " WHERE F_ID = ? AND F_AL_ID = AL_ID"); - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, UpdateFlight, f_id)) { - updated = preparedStatement.executeUpdate(); - } - if (updated != 1) { - throw new UserAbortException(String.format("Error Type [%s]: Failed to add reservation for flight #%s - Updated %d records for UpdateFlight", ErrorType.VALIDITY_ERROR, f_id, updated)); - } + public final SQLStmt GetCustomer = + new SQLStmt( + "SELECT C_BASE_AP_ID, C_BALANCE, C_SATTR00 " + + " FROM " + + SEATSConstants.TABLENAME_CUSTOMER + + " WHERE C_ID = ? "); - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, UpdateCustomer, attrs[0], attrs[1], attrs[2], attrs[3], c_id)) { - updated = preparedStatement.executeUpdate(); - } - if (updated != 1) { - throw new UserAbortException(String.format("Error Type [%s]: Failed to add reservation for flight #%s - Updated %d records for UpdateCustomer", ErrorType.VALIDITY_ERROR, f_id, updated)); - } + public final SQLStmt CheckSeat = + new SQLStmt( + "SELECT R_ID " + + " FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_F_ID = ? and R_SEAT = ?"); + + public final SQLStmt CheckCustomer = + new SQLStmt( + "SELECT R_ID " + + " FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_F_ID = ? AND R_C_ID = ?"); + + public final SQLStmt UpdateFlight = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_FLIGHT + + " SET F_SEATS_LEFT = F_SEATS_LEFT - 1 " + + " WHERE F_ID = ? "); - // We don't care if we updated FrequentFlyer - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, UpdateFrequentFlyer, attrs[4], attrs[5], attrs[6], attrs[7], c_id, airline_id)) { - updated = preparedStatement.executeUpdate(); + public final SQLStmt UpdateCustomer = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_CUSTOMER + + " SET C_IATTR10 = C_IATTR10 + 1, " + + " C_IATTR11 = C_IATTR11 + 1, " + + " C_IATTR12 = ?, " + + " C_IATTR13 = ?, " + + " C_IATTR14 = ?, " + + " C_IATTR15 = ? " + + " WHERE C_ID = ? "); + + public final SQLStmt UpdateFrequentFlyer = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_FREQUENT_FLYER + + " SET FF_IATTR10 = FF_IATTR10 + 1, " + + " FF_IATTR11 = ?, " + + " FF_IATTR12 = ?, " + + " FF_IATTR13 = ?, " + + " FF_IATTR14 = ? " + + " WHERE FF_C_ID = ? " + + " AND FF_AL_ID = ?"); + + public final SQLStmt InsertReservation = + new SQLStmt( + "INSERT INTO " + + SEATSConstants.TABLENAME_RESERVATION + + " (" + + " R_ID, " + + " R_C_ID, " + + " R_F_ID, " + + " R_SEAT, " + + " R_PRICE, " + + " R_IATTR00, " + + " R_IATTR01, " + + " R_IATTR02, " + + " R_IATTR03, " + + " R_IATTR04, " + + " R_IATTR05, " + + " R_IATTR06, " + + " R_IATTR07, " + + " R_IATTR08 " + + ") VALUES (" + + " ?, " + + // R_ID + " ?, " + + // R_C_ID + " ?, " + + // R_F_ID + " ?, " + + // R_SEAT + " ?, " + + // R_PRICE + " ?, " + + // R_ATTR00 + " ?, " + + // R_ATTR01 + " ?, " + + // R_ATTR02 + " ?, " + + // R_ATTR03 + " ?, " + + // R_ATTR04 + " ?, " + + // R_ATTR05 + " ?, " + + // R_ATTR06 + " ?, " + + // R_ATTR07 + " ? " + + // R_ATTR08 + ")"); + + public void run( + Connection conn, + long r_id, + String c_id, + String f_id, + long seatnum, + double price, + long[] attrs) + throws SQLException { + boolean found; + + long airline_id; + long seats_left; + + // Flight Information + try (PreparedStatement stmt = this.getPreparedStatement(conn, GetFlight, f_id)) { + try (ResultSet results = stmt.executeQuery()) { + found = results.next(); + if (!found) { + LOG.debug("Error Type [{}]: Invalid flight {}", ErrorType.INVALID_FLIGHT_ID, f_id); + return; } + airline_id = results.getLong(1); + seats_left = results.getLong(2); + } + } + if (seats_left <= 0) { + LOG.debug( + "Error Type [{}]: No more seats available for flight {}", ErrorType.NO_MORE_SEATS, f_id); + return; + } + // Check if Seat is Available + try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckSeat, f_id, seatnum)) { + try (ResultSet results = stmt.executeQuery()) { + found = results.next(); + } + } + if (found) { + LOG.debug( + "Error Type [{}]: Seat {} is already reserved on flight {}", + ErrorType.SEAT_ALREADY_RESERVED, + seatnum, + f_id); + return; + } + // Check if the Customer already has a seat on this flight + try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckCustomer, f_id, c_id)) { + try (ResultSet results = stmt.executeQuery()) { + found = results.next(); + } + } + if (found) { + LOG.debug( + "Error Type [{}]: Customer {} already owns on a reservations on flight {}", + ErrorType.CUSTOMER_ALREADY_HAS_SEAT, + c_id, + f_id); + return; + } + // Get Customer Information + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetCustomer, c_id)) { + try (ResultSet results = preparedStatement.executeQuery()) { + found = results.next(); + } + } + if (!found) { + LOG.debug( + "Error Type [{}]: Invalid customer id: {} / {}", + ErrorType.INVALID_CUSTOMER_ID, + c_id, + new CustomerId(c_id)); + return; + } + int updated; - LOG.debug(String.format("Reserved new seat on flight %s for customer %s [seatsLeft=%d]", - f_id, c_id, seats_left - 1)); + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, InsertReservation)) { + preparedStatement.setLong(1, r_id); + preparedStatement.setString(2, c_id); + preparedStatement.setString(3, f_id); + preparedStatement.setLong(4, seatnum); + preparedStatement.setDouble(5, price); + for (int i = 0; i < attrs.length; i++) { + preparedStatement.setLong(6 + i, attrs[i]); + } + updated = preparedStatement.executeUpdate(); + } + if (updated != 1) { + throw new UserAbortException( + String.format( + "Error Type [%s]: Failed to add reservation for flight #%s - Inserted %d records for InsertReservation", + ErrorType.VALIDITY_ERROR, f_id, updated)); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, UpdateFlight, f_id)) { + updated = preparedStatement.executeUpdate(); + } + if (updated != 1) { + throw new UserAbortException( + String.format( + "Error Type [%s]: Failed to add reservation for flight #%s - Updated %d records for UpdateFlight", + ErrorType.VALIDITY_ERROR, f_id, updated)); + } + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, UpdateCustomer, attrs[0], attrs[1], attrs[2], attrs[3], c_id)) { + updated = preparedStatement.executeUpdate(); + } + if (updated != 1) { + throw new UserAbortException( + String.format( + "Error Type [%s]: Failed to add reservation for flight #%s - Updated %d records for UpdateCustomer", + ErrorType.VALIDITY_ERROR, f_id, updated)); } + + // We don't care if we updated FrequentFlyer + try (PreparedStatement preparedStatement = + this.getPreparedStatement( + conn, UpdateFrequentFlyer, attrs[4], attrs[5], attrs[6], attrs[7], c_id, airline_id)) { + updated = preparedStatement.executeUpdate(); + } + + LOG.debug( + String.format( + "Reserved new seat on flight %s for customer %s [seatsLeft=%d]", + f_id, c_id, seats_left - 1)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateCustomer.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateCustomer.java index 47ff5fa5e..659b45c78 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateCustomer.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateCustomer.java @@ -15,124 +15,127 @@ * */ - package com.oltpbenchmark.benchmarks.seats.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.benchmarks.seats.util.ErrorType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class UpdateCustomer extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(UpdateCustomer.class); - - public final SQLStmt GetCustomerIdStr = new SQLStmt( - "SELECT C_ID " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + - " WHERE C_ID_STR = ? " - ); - - public final SQLStmt GetCustomer = new SQLStmt( - "SELECT * " + - " FROM " + SEATSConstants.TABLENAME_CUSTOMER + - " WHERE C_ID = ? " - ); - - public final SQLStmt GetBaseAirport = new SQLStmt( - "SELECT * " + - " FROM " + SEATSConstants.TABLENAME_AIRPORT + ", " + - SEATSConstants.TABLENAME_COUNTRY + - " WHERE AP_ID = ? AND AP_CO_ID = CO_ID " - ); - - public final SQLStmt UpdateCustomer = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_CUSTOMER + - " SET C_IATTR00 = ?, " + - " C_IATTR01 = ? " + - " WHERE C_ID = ?" - ); - - public final SQLStmt GetFrequentFlyers = new SQLStmt( - "SELECT * FROM " + SEATSConstants.TABLENAME_FREQUENT_FLYER + - " WHERE FF_C_ID = ?" - ); - - public final SQLStmt UpdatFrequentFlyers = new SQLStmt( - "UPDATE " + SEATSConstants.TABLENAME_FREQUENT_FLYER + - " SET FF_IATTR00 = ?, " + - " FF_IATTR01 = ? " + - " WHERE FF_C_ID = ? " + - " AND FF_AL_ID = ? " - ); - - public void run(Connection conn, String c_id, String c_id_str, Long update_ff, long attr0, long attr1) throws SQLException { - // Use C_ID_STR to get C_ID - if (c_id == null) { - - - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetCustomerIdStr, c_id_str)) { - try (ResultSet rs = preparedStatement.executeQuery()) { - if (rs.next()) { - c_id = rs.getString(1); - } else { - LOG.debug("No Customer information record found for string '{}'", c_id_str); - return; - } - } - } - } - - long base_airport; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetCustomer, c_id)) { - try (ResultSet rs = preparedStatement.executeQuery()) { - if (!rs.next()) { - LOG.debug("No Customer information record found for id '{}'", c_id); - return; - } - - base_airport = rs.getLong(3); - } + private static final Logger LOG = LoggerFactory.getLogger(UpdateCustomer.class); + + public final SQLStmt GetCustomerIdStr = + new SQLStmt( + "SELECT C_ID " + " FROM " + SEATSConstants.TABLENAME_CUSTOMER + " WHERE C_ID_STR = ? "); + + public final SQLStmt GetCustomer = + new SQLStmt("SELECT * " + " FROM " + SEATSConstants.TABLENAME_CUSTOMER + " WHERE C_ID = ? "); + + public final SQLStmt GetBaseAirport = + new SQLStmt( + "SELECT * " + + " FROM " + + SEATSConstants.TABLENAME_AIRPORT + + ", " + + SEATSConstants.TABLENAME_COUNTRY + + " WHERE AP_ID = ? AND AP_CO_ID = CO_ID "); + + public final SQLStmt UpdateCustomer = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_CUSTOMER + + " SET C_IATTR00 = ?, " + + " C_IATTR01 = ? " + + " WHERE C_ID = ?"); + + public final SQLStmt GetFrequentFlyers = + new SQLStmt( + "SELECT * FROM " + SEATSConstants.TABLENAME_FREQUENT_FLYER + " WHERE FF_C_ID = ?"); + + public final SQLStmt UpdatFrequentFlyers = + new SQLStmt( + "UPDATE " + + SEATSConstants.TABLENAME_FREQUENT_FLYER + + " SET FF_IATTR00 = ?, " + + " FF_IATTR01 = ? " + + " WHERE FF_C_ID = ? " + + " AND FF_AL_ID = ? "); + + public void run( + Connection conn, String c_id, String c_id_str, Long update_ff, long attr0, long attr1) + throws SQLException { + // Use C_ID_STR to get C_ID + if (c_id == null) { + + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, GetCustomerIdStr, c_id_str)) { + try (ResultSet rs = preparedStatement.executeQuery()) { + if (rs.next()) { + c_id = rs.getString(1); + } else { + LOG.debug("No Customer information record found for string '{}'", c_id_str); + return; + } } + } + } - // Get their airport information - // TODO: Do something interesting with this data - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetBaseAirport, base_airport)) { - try (ResultSet airport_results = preparedStatement.executeQuery()) { - airport_results.next(); - } + long base_airport; + try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetCustomer, c_id)) { + try (ResultSet rs = preparedStatement.executeQuery()) { + if (!rs.next()) { + LOG.debug("No Customer information record found for id '{}'", c_id); + return; } + base_airport = rs.getLong(3); + } + } - long ff_al_id; + // Get their airport information + // TODO: Do something interesting with this data + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, GetBaseAirport, base_airport)) { + try (ResultSet airport_results = preparedStatement.executeQuery()) { + airport_results.next(); + } + } - if (update_ff != null) { - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, GetFrequentFlyers, c_id)) { - try (ResultSet ff_results = preparedStatement.executeQuery()) { - while (ff_results.next()) { - ff_al_id = ff_results.getLong(2); - try (PreparedStatement updateStatement = this.getPreparedStatement(conn, UpdatFrequentFlyers, attr0, attr1, c_id, ff_al_id)) { - updateStatement.executeUpdate(); - } - } - } + long ff_al_id; + + if (update_ff != null) { + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, GetFrequentFlyers, c_id)) { + try (ResultSet ff_results = preparedStatement.executeQuery()) { + while (ff_results.next()) { + ff_al_id = ff_results.getLong(2); + try (PreparedStatement updateStatement = + this.getPreparedStatement( + conn, UpdatFrequentFlyers, attr0, attr1, c_id, ff_al_id)) { + updateStatement.executeUpdate(); } + } } + } + } - - int updated; - try (PreparedStatement preparedStatement = this.getPreparedStatement(conn, UpdateCustomer, attr0, attr1, c_id)) { - updated = preparedStatement.executeUpdate(); - } - if (updated != 1) { - throw new UserAbortException(String.format("Error Type [%s]: Failed to update customer #%s - Updated %d records", ErrorType.VALIDITY_ERROR, c_id, updated)); - } - + int updated; + try (PreparedStatement preparedStatement = + this.getPreparedStatement(conn, UpdateCustomer, attr0, attr1, c_id)) { + updated = preparedStatement.executeUpdate(); + } + if (updated != 1) { + throw new UserAbortException( + String.format( + "Error Type [%s]: Failed to update customer #%s - Updated %d records", + ErrorType.VALIDITY_ERROR, c_id, updated)); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateReservation.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateReservation.java index 7b96bba96..202563f0f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateReservation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/procedures/UpdateReservation.java @@ -44,84 +44,105 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.benchmarks.seats.util.ErrorType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class UpdateReservation extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(UpdateReservation.class); - - public final SQLStmt CheckSeat = new SQLStmt( - "SELECT R_ID " + - " FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_F_ID = ? and R_SEAT = ?"); - - public final SQLStmt CheckCustomer = new SQLStmt( - "SELECT R_ID " + - " FROM " + SEATSConstants.TABLENAME_RESERVATION + - " WHERE R_F_ID = ? AND R_C_ID = ?"); - - private static final String BASE_SQL = "UPDATE " + SEATSConstants.TABLENAME_RESERVATION + - " SET R_SEAT = ?, %s = ? " + - " WHERE R_ID = ? AND R_C_ID = ? AND R_F_ID = ?"; - - public final SQLStmt ReserveSeat0 = new SQLStmt(String.format(BASE_SQL, "R_IATTR00")); - public final SQLStmt ReserveSeat1 = new SQLStmt(String.format(BASE_SQL, "R_IATTR01")); - public final SQLStmt ReserveSeat2 = new SQLStmt(String.format(BASE_SQL, "R_IATTR02")); - public final SQLStmt ReserveSeat3 = new SQLStmt(String.format(BASE_SQL, "R_IATTR03")); - - public static final int NUM_UPDATES = 4; - public final SQLStmt[] ReserveSeats = { - ReserveSeat0, - ReserveSeat1, - ReserveSeat2, - ReserveSeat3, - }; - - public void run(Connection conn, long r_id, String f_id, String c_id, long seatnum, long attr_idx, long attr_val) throws SQLException { - - boolean found; - - // Check if Seat is Available - try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckSeat, f_id, seatnum)) { - try (ResultSet results = stmt.executeQuery()) { - found = results.next(); - } - } - - if (found) { - LOG.debug("Error Type [{}]: Seat {} is already reserved on flight {}", ErrorType.SEAT_ALREADY_RESERVED, seatnum, f_id); - return; - } - - // Check if the Customer already has a seat on this flight - try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckCustomer, f_id, c_id)) { - try (ResultSet results = stmt.executeQuery()) { - found = results.next(); - } - } - - if (!found) { - LOG.debug("Error Type [{}]: Customer {} does not have an existing reservation on flight {}", ErrorType.CUSTOMER_ALREADY_HAS_SEAT, c_id, f_id); - return; - } - - // Update the seat reservation for the customer - int updated; - try (PreparedStatement stmt = this.getPreparedStatement(conn, ReserveSeats[(int) attr_idx], seatnum, attr_val, r_id, c_id, f_id)) { - updated = stmt.executeUpdate(); - } - - if (updated != 1) { - throw new UserAbortException(String.format("Error Type [%s]: Failed to update reservation on flight %s for customer #%s - Updated %d records", ErrorType.VALIDITY_ERROR, f_id, c_id, updated)); - } - - - LOG.debug(String.format("Updated reservation on flight %s for customer %s", f_id, c_id)); + private static final Logger LOG = LoggerFactory.getLogger(UpdateReservation.class); + + public final SQLStmt CheckSeat = + new SQLStmt( + "SELECT R_ID " + + " FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_F_ID = ? and R_SEAT = ?"); + + public final SQLStmt CheckCustomer = + new SQLStmt( + "SELECT R_ID " + + " FROM " + + SEATSConstants.TABLENAME_RESERVATION + + " WHERE R_F_ID = ? AND R_C_ID = ?"); + + private static final String BASE_SQL = + "UPDATE " + + SEATSConstants.TABLENAME_RESERVATION + + " SET R_SEAT = ?, %s = ? " + + " WHERE R_ID = ? AND R_C_ID = ? AND R_F_ID = ?"; + + public final SQLStmt ReserveSeat0 = new SQLStmt(String.format(BASE_SQL, "R_IATTR00")); + public final SQLStmt ReserveSeat1 = new SQLStmt(String.format(BASE_SQL, "R_IATTR01")); + public final SQLStmt ReserveSeat2 = new SQLStmt(String.format(BASE_SQL, "R_IATTR02")); + public final SQLStmt ReserveSeat3 = new SQLStmt(String.format(BASE_SQL, "R_IATTR03")); + + public static final int NUM_UPDATES = 4; + public final SQLStmt[] ReserveSeats = { + ReserveSeat0, ReserveSeat1, ReserveSeat2, ReserveSeat3, + }; + + public void run( + Connection conn, + long r_id, + String f_id, + String c_id, + long seatnum, + long attr_idx, + long attr_val) + throws SQLException { + + boolean found; + + // Check if Seat is Available + try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckSeat, f_id, seatnum)) { + try (ResultSet results = stmt.executeQuery()) { + found = results.next(); + } + } + + if (found) { + LOG.debug( + "Error Type [{}]: Seat {} is already reserved on flight {}", + ErrorType.SEAT_ALREADY_RESERVED, + seatnum, + f_id); + return; + } + // Check if the Customer already has a seat on this flight + try (PreparedStatement stmt = this.getPreparedStatement(conn, CheckCustomer, f_id, c_id)) { + try (ResultSet results = stmt.executeQuery()) { + found = results.next(); + } } + + if (!found) { + LOG.debug( + "Error Type [{}]: Customer {} does not have an existing reservation on flight {}", + ErrorType.CUSTOMER_ALREADY_HAS_SEAT, + c_id, + f_id); + return; + } + + // Update the seat reservation for the customer + int updated; + try (PreparedStatement stmt = + this.getPreparedStatement( + conn, ReserveSeats[(int) attr_idx], seatnum, attr_val, r_id, c_id, f_id)) { + updated = stmt.executeUpdate(); + } + + if (updated != 1) { + throw new UserAbortException( + String.format( + "Error Type [%s]: Failed to update reservation on flight %s for customer #%s - Updated %d records", + ErrorType.VALIDITY_ERROR, f_id, c_id, updated)); + } + + LOG.debug(String.format("Updated reservation on flight %s for customer %s", f_id, c_id)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerId.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerId.java index 517737b0e..c714dbce5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerId.java @@ -15,90 +15,88 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.util.CompositeId; - import java.util.Comparator; import java.util.Objects; public final class CustomerId extends CompositeId implements Comparable { - private static final int[] COMPOSITE_BITS = { - INT_MAX_DIGITS, // ID - LONG_MAX_DIGITS // AIRPORT_ID - }; - - private int id; - private long depart_airport_id; - - public CustomerId(int id, long depart_airport_id) { - this.id = id; - this.depart_airport_id = depart_airport_id; - } - - public CustomerId(String composite_id) { - this.decode(composite_id); - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.id = Integer.parseInt(values[0]); - this.depart_airport_id = Long.parseLong(values[1]); - } - - @Override - public String[] toArray() { - return (new String[]{Integer.toString(this.id), Long.toString(this.depart_airport_id)}); + private static final int[] COMPOSITE_BITS = { + INT_MAX_DIGITS, // ID + LONG_MAX_DIGITS // AIRPORT_ID + }; + + private int id; + private long depart_airport_id; + + public CustomerId(int id, long depart_airport_id) { + this.id = id; + this.depart_airport_id = depart_airport_id; + } + + public CustomerId(String composite_id) { + this.decode(composite_id); + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.id = Integer.parseInt(values[0]); + this.depart_airport_id = Long.parseLong(values[1]); + } + + @Override + public String[] toArray() { + return (new String[] {Integer.toString(this.id), Long.toString(this.depart_airport_id)}); + } + + /** + * @return the id + */ + public int getId() { + return id; + } + + /** + * @return the depart_airport_id + */ + public long getDepartAirportId() { + return depart_airport_id; + } + + @Override + public String toString() { + return String.format("CustomerId{airport=%d,id=%d}", this.depart_airport_id, this.id); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * @return the id - */ - public int getId() { - return id; - } - - /** - * @return the depart_airport_id - */ - public long getDepartAirportId() { - return depart_airport_id; - } - - @Override - public String toString() { - return String.format("CustomerId{airport=%d,id=%d}", this.depart_airport_id, this.id); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CustomerId that = (CustomerId) o; - return id == that.id && depart_airport_id == that.depart_airport_id; - } - - @Override - public int hashCode() { - return Objects.hash(id, depart_airport_id); - } - - @Override - public int compareTo(CustomerId o) { - return Comparator.comparingInt(CustomerId::getId) - .thenComparingLong(CustomerId::getDepartAirportId) - .compare(this, o); + if (o == null || getClass() != o.getClass()) { + return false; } -} \ No newline at end of file + CustomerId that = (CustomerId) o; + return id == that.id && depart_airport_id == that.depart_airport_id; + } + + @Override + public int hashCode() { + return Objects.hash(id, depart_airport_id); + } + + @Override + public int compareTo(CustomerId o) { + return Comparator.comparingInt(CustomerId::getId) + .thenComparingLong(CustomerId::getDepartAirportId) + .compare(this, o); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerIdIterable.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerIdIterable.java index 8a48c52a9..f3e0870e1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerIdIterable.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/CustomerIdIterable.java @@ -15,52 +15,51 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.util.Histogram; -import org.apache.commons.collections4.set.ListOrderedSet; - import java.util.Iterator; +import org.apache.commons.collections4.set.ListOrderedSet; public class CustomerIdIterable implements Iterable { - private final Histogram airport_max_customer_id; - private final ListOrderedSet airport_ids = new ListOrderedSet<>(); - private Long last_airport_id = null; - private int last_id = -1; - private long last_max_id = -1; + private final Histogram airport_max_customer_id; + private final ListOrderedSet airport_ids = new ListOrderedSet<>(); + private Long last_airport_id = null; + private int last_id = -1; + private long last_max_id = -1; - public CustomerIdIterable(Histogram airport_max_customer_id) { - this.airport_max_customer_id = airport_max_customer_id; - this.airport_ids.addAll(airport_max_customer_id.values()); - } + public CustomerIdIterable(Histogram airport_max_customer_id) { + this.airport_max_customer_id = airport_max_customer_id; + this.airport_ids.addAll(airport_max_customer_id.values()); + } - @Override - public Iterator iterator() { - return new Iterator() { - @Override - public boolean hasNext() { - return (!CustomerIdIterable.this.airport_ids.isEmpty() || (last_id != -1 && last_id < last_max_id)); - } + @Override + public Iterator iterator() { + return new Iterator() { + @Override + public boolean hasNext() { + return (!CustomerIdIterable.this.airport_ids.isEmpty() + || (last_id != -1 && last_id < last_max_id)); + } - @Override - public CustomerId next() { - if (last_airport_id == null) { - last_airport_id = airport_ids.remove(0); - last_id = 0; - last_max_id = airport_max_customer_id.get(last_airport_id); - } - CustomerId next_id = new CustomerId(last_id, last_airport_id); - if (++last_id == last_max_id) { - last_airport_id = null; - } - return next_id; - } + @Override + public CustomerId next() { + if (last_airport_id == null) { + last_airport_id = airport_ids.remove(0); + last_id = 0; + last_max_id = airport_max_customer_id.get(last_airport_id); + } + CustomerId next_id = new CustomerId(last_id, last_airport_id); + if (++last_id == last_max_id) { + last_airport_id = null; + } + return next_id; + } - @Override - public void remove() { - // Not implemented - } - }; - } + @Override + public void remove() { + // Not implemented + } + }; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/DistanceUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/DistanceUtil.java index ce6fcfb16..53d8b5198 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/DistanceUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/DistanceUtil.java @@ -15,50 +15,48 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.util.Pair; -/** - * Based on code found here: - * http://www.zipcodeworld.com/samples/distance.java.html - */ +/** Based on code found here: http://www.zipcodeworld.com/samples/distance.java.html */ public abstract class DistanceUtil { - /** - * Calculate the distance between two points - * - * @param lat0 - * @param lon0 - * @param lat1 - * @param lon1 - * @return - */ - public static double distance(double lat0, double lon0, double lat1, double lon1) { - double theta = lon0 - lon1; - double dist = Math.sin(deg2rad(lat0)) * Math.sin(deg2rad(lat1)) + Math.cos(deg2rad(lat0)) * Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(theta)); - dist = Math.acos(dist); - dist = rad2deg(dist); - return (dist * 60 * 1.1515); - } - - /** - * Pair - * - * @param loc0 - * @param loc1 - * @return - */ - public static double distance(Pair loc0, Pair loc1) { - return (DistanceUtil.distance(loc0.first, loc0.second, loc1.first, loc1.second)); - } - - private static double deg2rad(double deg) { - return (deg * Math.PI / 180.0); - } - - private static double rad2deg(double rad) { - return (rad * 180.0 / Math.PI); - } + /** + * Calculate the distance between two points + * + * @param lat0 + * @param lon0 + * @param lat1 + * @param lon1 + * @return + */ + public static double distance(double lat0, double lon0, double lat1, double lon1) { + double theta = lon0 - lon1; + double dist = + Math.sin(deg2rad(lat0)) * Math.sin(deg2rad(lat1)) + + Math.cos(deg2rad(lat0)) * Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(theta)); + dist = Math.acos(dist); + dist = rad2deg(dist); + return (dist * 60 * 1.1515); + } + + /** + * Pair + * + * @param loc0 + * @param loc1 + * @return + */ + public static double distance(Pair loc0, Pair loc1) { + return (DistanceUtil.distance(loc0.first, loc0.second, loc1.first, loc1.second)); + } + + private static double deg2rad(double deg) { + return (deg * Math.PI / 180.0); + } + + private static double rad2deg(double rad) { + return (rad * 180.0 / Math.PI); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ErrorType.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ErrorType.java index 054a13ab2..c2b95707f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ErrorType.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ErrorType.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; /** @@ -24,22 +23,22 @@ * @author pavlo */ public enum ErrorType { - INVALID_FLIGHT_ID, - INVALID_CUSTOMER_ID, - NO_MORE_SEATS, - SEAT_ALREADY_RESERVED, - CUSTOMER_ALREADY_HAS_SEAT, - VALIDITY_ERROR, - UNKNOWN; + INVALID_FLIGHT_ID, + INVALID_CUSTOMER_ID, + NO_MORE_SEATS, + SEAT_ALREADY_RESERVED, + CUSTOMER_ALREADY_HAS_SEAT, + VALIDITY_ERROR, + UNKNOWN; - private final String errorCode; + private final String errorCode; - ErrorType() { - this.errorCode = String.format("E%04d", this.ordinal()); - } + ErrorType() { + this.errorCode = String.format("E%04d", this.ordinal()); + } - @Override - public String toString() { - return this.errorCode; - } -} \ No newline at end of file + @Override + public String toString() { + return this.errorCode; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/FlightId.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/FlightId.java index a749a7964..eaffcf94a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/FlightId.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/FlightId.java @@ -15,170 +15,175 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.util.CompositeId; - import java.sql.Timestamp; import java.util.Comparator; import java.util.Objects; public final class FlightId extends CompositeId implements Comparable { - private static final int[] COMPOSITE_BITS = { - LONG_MAX_DIGITS, // AIRLINE_ID - LONG_MAX_DIGITS, // DEPART AIRPORT_ID - LONG_MAX_DIGITS, // ARRIVE AIRPORT_ID - LONG_MAX_DIGITS // DEPART DATE - }; - - /** - * The airline for this flight - */ - private long airline_id; - /** - * The id of the departure airport - */ - private long depart_airport_id; - /** - * The id of the arrival airport - */ - private long arrive_airport_id; - /** - * This is the departure time of the flight in minutes since the benchmark start date - */ - private long depart_date; - - - /** - * Constructor - * - * @param airline_id - The airline for this flight - * @param depart_airport_id - the id of the departure airport - * @param arrive_airport_id - the id of the arrival airport - * @param benchmark_start - the base date of when the benchmark data starts (including past days) - * @param flight_date - when departure date of the flight - */ - public FlightId(long airline_id, long depart_airport_id, long arrive_airport_id, Timestamp benchmark_start, Timestamp flight_date) { - this.airline_id = airline_id; - this.depart_airport_id = depart_airport_id; - this.arrive_airport_id = arrive_airport_id; - this.depart_date = FlightId.calculateFlightDate(benchmark_start, flight_date); - - } - - /** - * Constructor. Converts a composite id generated by encode() into the full object - * - * @param composite_id - */ - public FlightId(String composite_id) { - this.set(composite_id); - } - - public void set(String composite_id) { - this.decode(composite_id); - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.airline_id = Long.parseLong(values[0]); - this.depart_airport_id = Long.parseLong(values[1]); - this.arrive_airport_id = Long.parseLong(values[2]); - this.depart_date = Long.parseLong(values[3]); - } - - @Override - public String[] toArray() { - return (new String[]{Long.toString(this.airline_id), - Long.toString(this.depart_airport_id), - Long.toString(this.arrive_airport_id), - Long.toString(this.depart_date)}); - } - - /** - * @param benchmark_start - * @param flight_date - * @return - */ - protected static long calculateFlightDate(Timestamp benchmark_start, Timestamp flight_date) { - return (flight_date.getTime() - benchmark_start.getTime()) / 3600000; // 60s * 60m * 1000 - } - - /** - * @return the id - */ - public long getAirlineId() { - return airline_id; - } - - /** - * @return the depart_airport_id - */ - public long getDepartAirportId() { - return depart_airport_id; - } - - /** - * @return the arrive_airport_id - */ - public long getArriveAirportId() { - return arrive_airport_id; - } - - public long getDepartDate() { - return depart_date; - } - - /** - * @return the flight departure date - */ - public Timestamp getDepartDateAsTimestamp(Timestamp benchmark_start) { - return (new Timestamp(benchmark_start.getTime() + (this.depart_date * SEATSConstants.MILLISECONDS_PER_MINUTE * 60))); - } - - public boolean isUpcoming(Timestamp benchmark_start, long past_days) { - Timestamp depart_date = this.getDepartDateAsTimestamp(benchmark_start); - return ((depart_date.getTime() - benchmark_start.getTime()) >= (past_days * SEATSConstants.MILLISECONDS_PER_DAY)); - } - - @Override - public String toString() { - return String.format("FlightId{airline=%d,depart=%d,arrive=%d,date=%s}", - this.airline_id, this.depart_airport_id, this.arrive_airport_id, this.depart_date); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FlightId flightId = (FlightId) o; - return airline_id == flightId.airline_id && depart_airport_id == flightId.depart_airport_id && arrive_airport_id == flightId.arrive_airport_id && depart_date == flightId.depart_date; - } - - @Override - public int hashCode() { - return Objects.hash(airline_id, depart_airport_id, arrive_airport_id, depart_date); - } - - @Override - public int compareTo(FlightId o) { - return Comparator.comparingLong(FlightId::getAirlineId) - .thenComparingLong(FlightId::getDepartAirportId) - .thenComparingLong(FlightId::getArriveAirportId) - .thenComparingLong(FlightId::getDepartDate) - .compare(this, o); - } + private static final int[] COMPOSITE_BITS = { + LONG_MAX_DIGITS, // AIRLINE_ID + LONG_MAX_DIGITS, // DEPART AIRPORT_ID + LONG_MAX_DIGITS, // ARRIVE AIRPORT_ID + LONG_MAX_DIGITS // DEPART DATE + }; + + /** The airline for this flight */ + private long airline_id; + + /** The id of the departure airport */ + private long depart_airport_id; + + /** The id of the arrival airport */ + private long arrive_airport_id; + + /** This is the departure time of the flight in minutes since the benchmark start date */ + private long depart_date; + + /** + * Constructor + * + * @param airline_id - The airline for this flight + * @param depart_airport_id - the id of the departure airport + * @param arrive_airport_id - the id of the arrival airport + * @param benchmark_start - the base date of when the benchmark data starts (including past days) + * @param flight_date - when departure date of the flight + */ + public FlightId( + long airline_id, + long depart_airport_id, + long arrive_airport_id, + Timestamp benchmark_start, + Timestamp flight_date) { + this.airline_id = airline_id; + this.depart_airport_id = depart_airport_id; + this.arrive_airport_id = arrive_airport_id; + this.depart_date = FlightId.calculateFlightDate(benchmark_start, flight_date); + } + + /** + * Constructor. Converts a composite id generated by encode() into the full object + * + * @param composite_id + */ + public FlightId(String composite_id) { + this.set(composite_id); + } + + public void set(String composite_id) { + this.decode(composite_id); + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.airline_id = Long.parseLong(values[0]); + this.depart_airport_id = Long.parseLong(values[1]); + this.arrive_airport_id = Long.parseLong(values[2]); + this.depart_date = Long.parseLong(values[3]); + } + + @Override + public String[] toArray() { + return (new String[] { + Long.toString(this.airline_id), + Long.toString(this.depart_airport_id), + Long.toString(this.arrive_airport_id), + Long.toString(this.depart_date) + }); + } + + /** + * @param benchmark_start + * @param flight_date + * @return + */ + protected static long calculateFlightDate(Timestamp benchmark_start, Timestamp flight_date) { + return (flight_date.getTime() - benchmark_start.getTime()) / 3600000; // 60s * 60m * 1000 + } + + /** + * @return the id + */ + public long getAirlineId() { + return airline_id; + } + + /** + * @return the depart_airport_id + */ + public long getDepartAirportId() { + return depart_airport_id; + } + + /** + * @return the arrive_airport_id + */ + public long getArriveAirportId() { + return arrive_airport_id; + } + + public long getDepartDate() { + return depart_date; + } + + /** + * @return the flight departure date + */ + public Timestamp getDepartDateAsTimestamp(Timestamp benchmark_start) { + return (new Timestamp( + benchmark_start.getTime() + + (this.depart_date * SEATSConstants.MILLISECONDS_PER_MINUTE * 60))); + } + + public boolean isUpcoming(Timestamp benchmark_start, long past_days) { + Timestamp depart_date = this.getDepartDateAsTimestamp(benchmark_start); + return ((depart_date.getTime() - benchmark_start.getTime()) + >= (past_days * SEATSConstants.MILLISECONDS_PER_DAY)); + } + + @Override + public String toString() { + return String.format( + "FlightId{airline=%d,depart=%d,arrive=%d,date=%s}", + this.airline_id, this.depart_airport_id, this.arrive_airport_id, this.depart_date); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + FlightId flightId = (FlightId) o; + return airline_id == flightId.airline_id + && depart_airport_id == flightId.depart_airport_id + && arrive_airport_id == flightId.arrive_airport_id + && depart_date == flightId.depart_date; + } + + @Override + public int hashCode() { + return Objects.hash(airline_id, depart_airport_id, arrive_airport_id, depart_date); + } + + @Override + public int compareTo(FlightId o) { + return Comparator.comparingLong(FlightId::getAirlineId) + .thenComparingLong(FlightId::getDepartAirportId) + .thenComparingLong(FlightId::getArriveAirportId) + .thenComparingLong(FlightId::getDepartDate) + .compare(this, o); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ReturnFlight.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ReturnFlight.java index 38af5978f..27657dd27 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ReturnFlight.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/ReturnFlight.java @@ -15,100 +15,102 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; - import java.sql.Timestamp; import java.util.Calendar; import java.util.Objects; public class ReturnFlight implements Comparable { - private final CustomerId customer_id; - private final long return_airport_id; - private final Timestamp return_date; - - public ReturnFlight(CustomerId customer_id, long return_airport_id, Timestamp flight_date, int return_days) { - this.customer_id = customer_id; - this.return_airport_id = return_airport_id; - this.return_date = ReturnFlight.calculateReturnDate(flight_date, return_days); + private final CustomerId customer_id; + private final long return_airport_id; + private final Timestamp return_date; + + public ReturnFlight( + CustomerId customer_id, long return_airport_id, Timestamp flight_date, int return_days) { + this.customer_id = customer_id; + this.return_airport_id = return_airport_id; + this.return_date = ReturnFlight.calculateReturnDate(flight_date, return_days); + } + + /** + * @param flight_date + * @param return_days + * @return + */ + protected static Timestamp calculateReturnDate(Timestamp flight_date, int return_days) { + + // Round this to the start of the day + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis( + flight_date.getTime() + (return_days * SEATSConstants.MILLISECONDS_PER_DAY)); + + int year = cal.get(Calendar.YEAR); + int month = cal.get(Calendar.MONTH); + int day = cal.get(Calendar.DAY_OF_MONTH); + + cal.clear(); + cal.set(year, month, day); + return (new Timestamp(cal.getTime().getTime())); + } + + /** + * @return the customer_id + */ + public CustomerId getCustomerId() { + return customer_id; + } + + /** + * @return the return_airport_id + */ + public long getReturnAirportId() { + return return_airport_id; + } + + /** + * @return the return_time + */ + public Timestamp getReturnDate() { + return return_date; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - /** - * @param flight_date - * @param return_days - * @return - */ - protected static Timestamp calculateReturnDate(Timestamp flight_date, int return_days) { - - // Round this to the start of the day - Calendar cal = Calendar.getInstance(); - cal.setTimeInMillis(flight_date.getTime() + (return_days * SEATSConstants.MILLISECONDS_PER_DAY)); - - int year = cal.get(Calendar.YEAR); - int month = cal.get(Calendar.MONTH); - int day = cal.get(Calendar.DAY_OF_MONTH); - - cal.clear(); - cal.set(year, month, day); - return (new Timestamp(cal.getTime().getTime())); + if (o == null || getClass() != o.getClass()) { + return false; } - - /** - * @return the customer_id - */ - public CustomerId getCustomerId() { - return customer_id; + ReturnFlight that = (ReturnFlight) o; + return return_airport_id == that.return_airport_id + && Objects.equals(customer_id, that.customer_id) + && Objects.equals(return_date, that.return_date); + } + + @Override + public int hashCode() { + return Objects.hash(customer_id, return_airport_id, return_date); + } + + @Override + public int compareTo(ReturnFlight o) { + if (this.customer_id.equals(o.customer_id) + && this.return_airport_id == o.return_airport_id + && this.return_date.equals(o.return_date)) { + return (0); } - - /** - * @return the return_airport_id - */ - public long getReturnAirportId() { - return return_airport_id; - } - - /** - * @return the return_time - */ - public Timestamp getReturnDate() { - return return_date; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ReturnFlight that = (ReturnFlight) o; - return return_airport_id == that.return_airport_id && Objects.equals(customer_id, that.customer_id) && Objects.equals(return_date, that.return_date); - } - - @Override - public int hashCode() { - return Objects.hash(customer_id, return_airport_id, return_date); - } - - @Override - public int compareTo(ReturnFlight o) { - if (this.customer_id.equals(o.customer_id) && - this.return_airport_id == o.return_airport_id && - this.return_date.equals(o.return_date)) { - return (0); - } - // Otherwise order by time - return (this.return_date.compareTo(o.return_date)); - } - - @Override - public String toString() { - return String.format("ReturnFlight{%s,airport=%s,date=%s}", - this.customer_id, this.return_airport_id, this.return_date); - } - + // Otherwise order by time + return (this.return_date.compareTo(o.return_date)); + } + + @Override + public String toString() { + return String.format( + "ReturnFlight{%s,airport=%s,date=%s}", + this.customer_id, this.return_airport_id, this.return_date); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/SEATSHistogramUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/SEATSHistogramUtil.java index 783ce577d..122eee27a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/seats/util/SEATSHistogramUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/seats/util/SEATSHistogramUtil.java @@ -15,86 +15,86 @@ * */ - package com.oltpbenchmark.benchmarks.seats.util; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; import com.oltpbenchmark.util.Histogram; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.regex.Pattern; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class SEATSHistogramUtil { - private static final Logger LOG = LoggerFactory.getLogger(SEATSHistogramUtil.class); + private static final Logger LOG = LoggerFactory.getLogger(SEATSHistogramUtil.class); - private static final Map> cached_Histograms = new HashMap<>(); + private static final Map> cached_Histograms = new HashMap<>(); - private static Map> cached_AirportFlights; + private static Map> cached_AirportFlights; - private static String getHistogramFilePath(String data_dir, String name) { - return data_dir + File.separator + "histogram." + name.toLowerCase(); - } - - /** - * Returns the Flights Per Airport Histogram - * - * @param data_path - * @return - * @throws Exception - */ - public static synchronized Map> loadAirportFlights(String data_path) throws Exception { - if (cached_AirportFlights != null) { - return (cached_AirportFlights); - } + private static String getHistogramFilePath(String data_dir, String name) { + return data_dir + File.separator + "histogram." + name.toLowerCase(); + } - String filePath = getHistogramFilePath(data_path, SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); - Histogram h = new Histogram<>(); - h.load(filePath); + /** + * Returns the Flights Per Airport Histogram + * + * @param data_path + * @return + * @throws Exception + */ + public static synchronized Map> loadAirportFlights(String data_path) + throws Exception { + if (cached_AirportFlights != null) { + return (cached_AirportFlights); + } - Map> m = new TreeMap<>(); - Pattern pattern = Pattern.compile("-"); - Collection values = h.values(); - for (String value : values) { - String[] split = pattern.split(value); - Histogram src_h = m.get(split[0]); - if (src_h == null) { - src_h = new Histogram<>(); - m.put(split[0], src_h); - } - src_h.put(split[1], h.get(value)); - } + String filePath = getHistogramFilePath(data_path, SEATSConstants.HISTOGRAM_FLIGHTS_PER_AIRPORT); + Histogram h = new Histogram<>(); + h.load(filePath); - cached_AirportFlights = m; - return (m); + Map> m = new TreeMap<>(); + Pattern pattern = Pattern.compile("-"); + Collection values = h.values(); + for (String value : values) { + String[] split = pattern.split(value); + Histogram src_h = m.get(split[0]); + if (src_h == null) { + src_h = new Histogram<>(); + m.put(split[0], src_h); + } + src_h.put(split[1], h.get(value)); } - /** - * Construct a histogram from an airline-benchmark data file - * - * @param name - * @param data_path - * @param has_header - * @return - * @throws Exception - */ - public static synchronized Histogram loadHistogram(String name, String data_path, boolean has_header) throws Exception { - String filePath = getHistogramFilePath(data_path, name); - Histogram histogram = cached_Histograms.get(filePath); - if (histogram == null) { - histogram = new Histogram<>(); - histogram.load(filePath); - cached_Histograms.put(filePath, histogram); - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Histogram %s\n%s", name, histogram)); - } + cached_AirportFlights = m; + return (m); + } - return (histogram); + /** + * Construct a histogram from an airline-benchmark data file + * + * @param name + * @param data_path + * @param has_header + * @return + * @throws Exception + */ + public static synchronized Histogram loadHistogram( + String name, String data_path, boolean has_header) throws Exception { + String filePath = getHistogramFilePath(data_path, name); + Histogram histogram = cached_Histograms.get(filePath); + if (histogram == null) { + histogram = new Histogram<>(); + histogram.load(filePath); + cached_Histograms.put(filePath, histogram); } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Histogram %s\n%s", name, histogram)); + } + + return (histogram); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIBenchmark.java index 65930f06f..67c22d371 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIBenchmark.java @@ -24,59 +24,57 @@ import com.oltpbenchmark.benchmarks.sibench.procedures.UpdateRecord; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class SIBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(SIBenchmark.class); + private static final Logger LOG = LoggerFactory.getLogger(SIBenchmark.class); - public SIBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } + public SIBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); - Table t = this.getCatalog().getTable("SITEST"); + Table t = this.getCatalog().getTable("SITEST"); - String recordCount = SQLUtil.getMaxColSQL(this.workConf.getDatabaseType(), t, "id"); + String recordCount = SQLUtil.getMaxColSQL(this.workConf.getDatabaseType(), t, "id"); - try (Connection metaConn = this.makeConnection(); - Statement stmt = metaConn.createStatement(); - ResultSet res = stmt.executeQuery(recordCount)) { + try (Connection metaConn = this.makeConnection(); + Statement stmt = metaConn.createStatement(); + ResultSet res = stmt.executeQuery(recordCount)) { - int init_record_count = 0; - while (res.next()) { - init_record_count = res.getInt(1); - } + int init_record_count = 0; + while (res.next()) { + init_record_count = res.getInt(1); + } - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new SIWorker(this, i, init_record_count)); - } + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new SIWorker(this, i, init_record_count)); + } - } catch (SQLException e) { - LOG.error(e.getMessage(), e); - } - return workers; + } catch (SQLException e) { + LOG.error(e.getMessage(), e); } - - @Override - protected Loader makeLoaderImpl() { - return new SILoader(this); - } - - @Override - protected Package getProcedurePackageImpl() { - return UpdateRecord.class.getPackage(); - } - + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new SILoader(this); + } + + @Override + protected Package getProcedurePackageImpl() { + return UpdateRecord.class.getPackage(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIConstants.java index f668cad0d..84620c9ee 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIConstants.java @@ -19,11 +19,9 @@ public abstract class SIConstants { - public static final String TABLE_NAME = "sitest"; - - public static final int NUM_FIELDS = 1; - - public static final int RECORD_COUNT = 10; + public static final String TABLE_NAME = "sitest"; + public static final int NUM_FIELDS = 1; + public static final int RECORD_COUNT = 10; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java index 22aa4bbfd..23a5a1813 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SILoader.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -30,61 +29,61 @@ import java.util.Random; public final class SILoader extends Loader { - private final int num_record; + private final int num_record; - public SILoader(SIBenchmark benchmark) { - super(benchmark); - this.num_record = (int) Math.round(SIConstants.RECORD_COUNT * this.scaleFactor); - if (LOG.isDebugEnabled()) { - LOG.debug("# of RECORDS: {}", this.num_record); - } + public SILoader(SIBenchmark benchmark) { + super(benchmark); + this.num_record = (int) Math.round(SIConstants.RECORD_COUNT * this.scaleFactor); + if (LOG.isDebugEnabled()) { + LOG.debug("# of RECORDS: {}", this.num_record); } + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - final int itemsPerThread = Math.max(this.num_record / numLoaders, 1); - final int numRecordThreads = (int) Math.ceil((double) this.num_record / itemsPerThread); + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + final int itemsPerThread = Math.max(this.num_record / numLoaders, 1); + final int numRecordThreads = (int) Math.ceil((double) this.num_record / itemsPerThread); - // SITEST - for (int i = 0; i < numRecordThreads; i++) { - final int lo = i * itemsPerThread + 1; - final int hi = Math.min(this.num_record, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadSITest(conn, lo, hi); - } - }); - } + // SITEST + for (int i = 0; i < numRecordThreads; i++) { + final int lo = i * itemsPerThread + 1; + final int hi = Math.min(this.num_record, (i + 1) * itemsPerThread); - return threads; + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadSITest(conn, lo, hi); + } + }); } - private void loadSITest(Connection conn, int lo, int hi) throws SQLException { - Random rand = this.benchmark.rng(); - Table catalog_tbl = this.benchmark.getCatalog().getTable("SITEST"); + return threads; + } + private void loadSITest(Connection conn, int lo, int hi) throws SQLException { + Random rand = this.benchmark.rng(); + Table catalog_tbl = this.benchmark.getCatalog().getTable("SITEST"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - int batch = 0; - for (int i = lo; i <= hi; i++) { - stmt.setInt(1, i); - stmt.setInt(2, rand.nextInt(Integer.MAX_VALUE)); - stmt.addBatch(); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int batch = 0; + for (int i = lo; i <= hi; i++) { + stmt.setInt(1, i); + stmt.setInt(2, rand.nextInt(Integer.MAX_VALUE)); + stmt.addBatch(); - if (++batch >= workConf.getBatchSize()) { - stmt.executeBatch(); + if (++batch >= workConf.getBatchSize()) { + stmt.executeBatch(); - batch = 0; - } - } - if (batch > 0) { - stmt.executeBatch(); - } + batch = 0; } + } + if (batch > 0) { + stmt.executeBatch(); + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java index e38144f8c..6a65190b4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/SIWorker.java @@ -24,49 +24,49 @@ import com.oltpbenchmark.benchmarks.sibench.procedures.MinRecord; import com.oltpbenchmark.benchmarks.sibench.procedures.UpdateRecord; import com.oltpbenchmark.types.TransactionStatus; - import java.sql.Connection; import java.sql.SQLException; import java.util.Random; public final class SIWorker extends Worker { - private static Random updateRecordIdGenerator = null; - private final int recordCount; + private static Random updateRecordIdGenerator = null; + private final int recordCount; - public SIWorker(SIBenchmark benchmarkModule, int id, int init_record_count) { - super(benchmarkModule, id); - synchronized (SIWorker.class) { - // We must know where to start inserting - if (updateRecordIdGenerator == null) { - updateRecordIdGenerator = benchmarkModule.rng(); - } - } - this.recordCount = init_record_count; + public SIWorker(SIBenchmark benchmarkModule, int id, int init_record_count) { + super(benchmarkModule, id); + synchronized (SIWorker.class) { + // We must know where to start inserting + if (updateRecordIdGenerator == null) { + updateRecordIdGenerator = benchmarkModule.rng(); + } } + this.recordCount = init_record_count; + } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - Class procClass = nextTrans.getProcedureClass(); + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + Class procClass = nextTrans.getProcedureClass(); - if (procClass.equals(MinRecord.class)) { - minRecord(conn); - } else if (procClass.equals(UpdateRecord.class)) { - updateRecord(conn); - } - return (TransactionStatus.SUCCESS); + if (procClass.equals(MinRecord.class)) { + minRecord(conn); + } else if (procClass.equals(UpdateRecord.class)) { + updateRecord(conn); } + return (TransactionStatus.SUCCESS); + } - private void minRecord(Connection conn) throws SQLException { - MinRecord proc = this.getProcedure(MinRecord.class); + private void minRecord(Connection conn) throws SQLException { + MinRecord proc = this.getProcedure(MinRecord.class); - proc.run(conn); - } + proc.run(conn); + } - private void updateRecord(Connection conn) throws SQLException { - UpdateRecord proc = this.getProcedure(UpdateRecord.class); + private void updateRecord(Connection conn) throws SQLException { + UpdateRecord proc = this.getProcedure(UpdateRecord.class); - int id = updateRecordIdGenerator.nextInt(this.recordCount); - proc.run(conn, id); - } + int id = updateRecordIdGenerator.nextInt(this.recordCount); + proc.run(conn, id); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/MinRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/MinRecord.java index 1bc63cbf6..62fdc5ff0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/MinRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/MinRecord.java @@ -17,26 +17,27 @@ package com.oltpbenchmark.benchmarks.sibench.procedures; +import static com.oltpbenchmark.benchmarks.sibench.SIConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.sibench.SIConstants.TABLE_NAME; - public class MinRecord extends Procedure { - public final SQLStmt minStmt = new SQLStmt("SELECT id FROM " + TABLE_NAME + " ORDER BY value ASC LIMIT 1"); + public final SQLStmt minStmt = + new SQLStmt("SELECT id FROM " + TABLE_NAME + " ORDER BY value ASC LIMIT 1"); - public int run(Connection conn) throws SQLException { - int minId = 0; - try (PreparedStatement stmt = this.getPreparedStatement(conn, minStmt); ResultSet r = stmt.executeQuery()) { - while (r.next()) { - minId = r.getInt(1); - } - } - return minId; + public int run(Connection conn) throws SQLException { + int minId = 0; + try (PreparedStatement stmt = this.getPreparedStatement(conn, minStmt); + ResultSet r = stmt.executeQuery()) { + while (r.next()) { + minId = r.getInt(1); + } } + return minId; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/UpdateRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/UpdateRecord.java index e489a9ac1..0280b3f5f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/UpdateRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/sibench/procedures/UpdateRecord.java @@ -17,25 +17,22 @@ package com.oltpbenchmark.benchmarks.sibench.procedures; +import static com.oltpbenchmark.benchmarks.sibench.SIConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.sibench.SIConstants.TABLE_NAME; - public class UpdateRecord extends Procedure { - public final SQLStmt updateStmt = new SQLStmt( - "UPDATE " + TABLE_NAME + " SET value = value + 1 WHERE id = ?" - ); + public final SQLStmt updateStmt = + new SQLStmt("UPDATE " + TABLE_NAME + " SET value = value + 1 WHERE id = ?"); - public void run(Connection conn, int id) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateStmt)) { - stmt.setInt(1, id); - stmt.executeUpdate(); - } + public void run(Connection conn, int id) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateStmt)) { + stmt.setInt(1, id); + stmt.executeUpdate(); } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankBenchmark.java index 998731a0e..62c68bc9c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankBenchmark.java @@ -25,55 +25,53 @@ import com.oltpbenchmark.catalog.Column; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.util.ArrayList; import java.util.List; public final class SmallBankBenchmark extends BenchmarkModule { - protected final long numAccounts; - - public SmallBankBenchmark(WorkloadConfiguration workConf) { - super(workConf); - this.numAccounts = (int) Math.round(SmallBankConstants.NUM_ACCOUNTS * workConf.getScaleFactor()); - } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new SmallBankWorker(this, i)); - } - return workers; - } + protected final long numAccounts; - @Override - protected Loader makeLoaderImpl() { - return new SmallBankLoader(this); - } + public SmallBankBenchmark(WorkloadConfiguration workConf) { + super(workConf); + this.numAccounts = + (int) Math.round(SmallBankConstants.NUM_ACCOUNTS * workConf.getScaleFactor()); + } - @Override - protected Package getProcedurePackageImpl() { - return Amalgamate.class.getPackage(); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new SmallBankWorker(this, i)); } + return workers; + } + @Override + protected Loader makeLoaderImpl() { + return new SmallBankLoader(this); + } - /** - * For the given table, return the length of the first VARCHAR attribute - * - * @param acctsTbl - * @return - */ - public static int getCustomerNameLength(Table acctsTbl) { - int acctNameLength = -1; - for (Column col : acctsTbl.getColumns()) { - if (SQLUtil.isStringType(col.getType())) { - acctNameLength = col.getSize(); - break; - } - } + @Override + protected Package getProcedurePackageImpl() { + return Amalgamate.class.getPackage(); + } - return (acctNameLength); + /** + * For the given table, return the length of the first VARCHAR attribute + * + * @param acctsTbl + * @return + */ + public static int getCustomerNameLength(Table acctsTbl) { + int acctNameLength = -1; + for (Column col : acctsTbl.getColumns()) { + if (SQLUtil.isStringType(col.getType())) { + acctNameLength = col.getSize(); + break; + } } + return (acctNameLength); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankConstants.java index 355bf4176..d8bc1513a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankConstants.java @@ -28,41 +28,39 @@ public abstract class SmallBankConstants { - // ---------------------------------------------------------------- - // TABLE NAMES - // ---------------------------------------------------------------- - public static final String TABLENAME_ACCOUNTS = "accounts"; - public static final String TABLENAME_SAVINGS = "savings"; - public static final String TABLENAME_CHECKING = "checking"; + // ---------------------------------------------------------------- + // TABLE NAMES + // ---------------------------------------------------------------- + public static final String TABLENAME_ACCOUNTS = "accounts"; + public static final String TABLENAME_SAVINGS = "savings"; + public static final String TABLENAME_CHECKING = "checking"; - // ---------------------------------------------------------------- - // ACCOUNT INFORMATION - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- + // ACCOUNT INFORMATION + // ---------------------------------------------------------------- - // Default number of customers in bank - public static final int NUM_ACCOUNTS = 1000000; + // Default number of customers in bank + public static final int NUM_ACCOUNTS = 1000000; - public static final boolean HOTSPOT_USE_FIXED_SIZE = false; - public static final double HOTSPOT_PERCENTAGE = 25; // [0% - 100%] - public static final int HOTSPOT_FIXED_SIZE = 100; // fixed number of tuples + public static final boolean HOTSPOT_USE_FIXED_SIZE = false; + public static final double HOTSPOT_PERCENTAGE = 25; // [0% - 100%] + public static final int HOTSPOT_FIXED_SIZE = 100; // fixed number of tuples - // ---------------------------------------------------------------- - // ADDITIONAL CONFIGURATION SETTINGS - // ---------------------------------------------------------------- - - // Initial balance amount - // We'll just make it really big so that they never run out of money - public static final int MIN_BALANCE = 10000; - public static final int MAX_BALANCE = 50000; - - // ---------------------------------------------------------------- - // PROCEDURE PARAMETERS - // These amounts are from the original code - // ---------------------------------------------------------------- - public static final double PARAM_SEND_PAYMENT_AMOUNT = 5.0d; - public static final double PARAM_DEPOSIT_CHECKING_AMOUNT = 1.3d; - public static final double PARAM_TRANSACT_SAVINGS_AMOUNT = 20.20d; - public static final double PARAM_WRITE_CHECK_AMOUNT = 5.0d; + // ---------------------------------------------------------------- + // ADDITIONAL CONFIGURATION SETTINGS + // ---------------------------------------------------------------- + // Initial balance amount + // We'll just make it really big so that they never run out of money + public static final int MIN_BALANCE = 10000; + public static final int MAX_BALANCE = 50000; + // ---------------------------------------------------------------- + // PROCEDURE PARAMETERS + // These amounts are from the original code + // ---------------------------------------------------------------- + public static final double PARAM_SEND_PAYMENT_AMOUNT = 5.0d; + public static final double PARAM_DEPOSIT_CHECKING_AMOUNT = 1.3d; + public static final double PARAM_TRANSACT_SAVINGS_AMOUNT = 20.20d; + public static final double PARAM_WRITE_CHECK_AMOUNT = 5.0d; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankLoader.java index 33026f87b..c94d285dc 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankLoader.java @@ -23,7 +23,6 @@ import com.oltpbenchmark.util.RandomDistribution.DiscreteRNG; import com.oltpbenchmark.util.RandomDistribution.Gaussian; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -36,112 +35,110 @@ * @author pavlo */ public final class SmallBankLoader extends Loader { - private final Table catalogAccts; - private final Table catalogSavings; - private final Table catalogChecking; - - private final String sqlAccts; - private final String sqlSavings; - private final String sqlChecking; - - private final long numAccounts; - private final int custNameLength; - - public SmallBankLoader(SmallBankBenchmark benchmark) { - super(benchmark); - - this.catalogAccts = this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_ACCOUNTS); - this.catalogSavings = this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_SAVINGS); - this.catalogChecking = this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_CHECKING); - - this.sqlAccts = SQLUtil.getInsertSQL(this.catalogAccts, this.getDatabaseType()); - this.sqlSavings = SQLUtil.getInsertSQL(this.catalogSavings, this.getDatabaseType()); - this.sqlChecking = SQLUtil.getInsertSQL(this.catalogChecking, this.getDatabaseType()); - - this.numAccounts = benchmark.numAccounts; - this.custNameLength = SmallBankBenchmark.getCustomerNameLength(this.catalogAccts); + private final Table catalogAccts; + private final Table catalogSavings; + private final Table catalogChecking; + + private final String sqlAccts; + private final String sqlSavings; + private final String sqlChecking; + + private final long numAccounts; + private final int custNameLength; + + public SmallBankLoader(SmallBankBenchmark benchmark) { + super(benchmark); + + this.catalogAccts = this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_ACCOUNTS); + this.catalogSavings = + this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_SAVINGS); + this.catalogChecking = + this.benchmark.getCatalog().getTable(SmallBankConstants.TABLENAME_CHECKING); + + this.sqlAccts = SQLUtil.getInsertSQL(this.catalogAccts, this.getDatabaseType()); + this.sqlSavings = SQLUtil.getInsertSQL(this.catalogSavings, this.getDatabaseType()); + this.sqlChecking = SQLUtil.getInsertSQL(this.catalogChecking, this.getDatabaseType()); + + this.numAccounts = benchmark.numAccounts; + this.custNameLength = SmallBankBenchmark.getCustomerNameLength(this.catalogAccts); + } + + @Override + public List createLoaderThreads() throws SQLException { + List threads = new ArrayList<>(); + int batchSize = 100000; + long start = 0; + while (start < this.numAccounts) { + long stop = Math.min(start + batchSize, this.numAccounts); + threads.add(new Generator(start, stop)); + start = stop; } - - @Override - public List createLoaderThreads() throws SQLException { - List threads = new ArrayList<>(); - int batchSize = 100000; - long start = 0; - while (start < this.numAccounts) { - long stop = Math.min(start + batchSize, this.numAccounts); - threads.add(new Generator(start, stop)); - start = stop; - } - return (threads); + return (threads); + } + + /** Thread that can generate a range of accounts */ + private class Generator extends LoaderThread { + private final long start; + private final long stop; + private final DiscreteRNG randBalance; + + PreparedStatement stmtAccts; + PreparedStatement stmtSavings; + PreparedStatement stmtChecking; + + public Generator(long start, long stop) { + super(benchmark); + this.start = start; + this.stop = stop; + this.randBalance = + new Gaussian( + benchmark.rng(), SmallBankConstants.MIN_BALANCE, SmallBankConstants.MAX_BALANCE); } - /** - * Thread that can generate a range of accounts - */ - private class Generator extends LoaderThread { - private final long start; - private final long stop; - private final DiscreteRNG randBalance; - - PreparedStatement stmtAccts; - PreparedStatement stmtSavings; - PreparedStatement stmtChecking; - - public Generator(long start, long stop) { - super(benchmark); - this.start = start; - this.stop = stop; - this.randBalance = new Gaussian(benchmark.rng(), - SmallBankConstants.MIN_BALANCE, - SmallBankConstants.MAX_BALANCE); - } - - @Override - public void load(Connection conn) { - try { - this.stmtAccts = conn.prepareStatement(SmallBankLoader.this.sqlAccts); - this.stmtSavings = conn.prepareStatement(SmallBankLoader.this.sqlSavings); - this.stmtChecking = conn.prepareStatement(SmallBankLoader.this.sqlChecking); - - final String acctNameFormat = "%0" + custNameLength + "d"; - int batchSize = 0; - for (long acctId = this.start; acctId < this.stop; acctId++) { - // ACCOUNT - String acctName = String.format(acctNameFormat, acctId); - stmtAccts.setLong(1, acctId); - stmtAccts.setString(2, acctName); - stmtAccts.addBatch(); - - // CHECKINGS - stmtChecking.setLong(1, acctId); - stmtChecking.setInt(2, this.randBalance.nextInt()); - stmtChecking.addBatch(); - - // SAVINGS - stmtSavings.setLong(1, acctId); - stmtSavings.setInt(2, this.randBalance.nextInt()); - stmtSavings.addBatch(); - - if (++batchSize >= workConf.getBatchSize()) { - this.loadTables(conn); - batchSize = 0; - } - } - if (batchSize > 0) { - this.loadTables(conn); - } - } catch (SQLException ex) { - LOG.error("Failed to load data", ex); - throw new RuntimeException(ex); - } + @Override + public void load(Connection conn) { + try { + this.stmtAccts = conn.prepareStatement(SmallBankLoader.this.sqlAccts); + this.stmtSavings = conn.prepareStatement(SmallBankLoader.this.sqlSavings); + this.stmtChecking = conn.prepareStatement(SmallBankLoader.this.sqlChecking); + + final String acctNameFormat = "%0" + custNameLength + "d"; + int batchSize = 0; + for (long acctId = this.start; acctId < this.stop; acctId++) { + // ACCOUNT + String acctName = String.format(acctNameFormat, acctId); + stmtAccts.setLong(1, acctId); + stmtAccts.setString(2, acctName); + stmtAccts.addBatch(); + + // CHECKINGS + stmtChecking.setLong(1, acctId); + stmtChecking.setInt(2, this.randBalance.nextInt()); + stmtChecking.addBatch(); + + // SAVINGS + stmtSavings.setLong(1, acctId); + stmtSavings.setInt(2, this.randBalance.nextInt()); + stmtSavings.addBatch(); + + if (++batchSize >= workConf.getBatchSize()) { + this.loadTables(conn); + batchSize = 0; + } } - - private void loadTables(Connection conn) throws SQLException { - this.stmtAccts.executeBatch(); - this.stmtSavings.executeBatch(); - this.stmtChecking.executeBatch(); - + if (batchSize > 0) { + this.loadTables(conn); } + } catch (SQLException ex) { + LOG.error("Failed to load data", ex); + throw new RuntimeException(ex); + } } + private void loadTables(Connection conn) throws SQLException { + this.stmtAccts.executeBatch(); + this.stmtSavings.executeBatch(); + this.stmtChecking.executeBatch(); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankWorker.java index 407f6ef4c..6d7a9a82c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/SmallBankWorker.java @@ -25,121 +25,124 @@ import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.RandomDistribution.DiscreteRNG; import com.oltpbenchmark.util.RandomDistribution.Flat; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * SmallBank Benchmark Work Driver - * Fuck yo couch. + * SmallBank Benchmark Work Driver Fuck yo couch. * * @author pavlo */ public final class SmallBankWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(SmallBankWorker.class); - - private final Amalgamate procAmalgamate; - private final Balance procBalance; - private final DepositChecking procDepositChecking; - private final SendPayment procSendPayment; - private final TransactSavings procTransactSavings; - private final WriteCheck procWriteCheck; - - private final DiscreteRNG rng; - private final long numAccounts; - private final int custNameLength; - private final String custNameFormat; - private final long[] custIdsBuffer = {-1L, -1L}; - - public SmallBankWorker(SmallBankBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - - // This is a minor speed-up to avoid having to invoke the hashmap look-up - // everytime we want to execute a txn. This is important to do on - // a client machine with not a lot of cores - this.procAmalgamate = this.getProcedure(Amalgamate.class); - this.procBalance = this.getProcedure(Balance.class); - this.procDepositChecking = this.getProcedure(DepositChecking.class); - this.procSendPayment = this.getProcedure(SendPayment.class); - this.procTransactSavings = this.getProcedure(TransactSavings.class); - this.procWriteCheck = this.getProcedure(WriteCheck.class); - - this.numAccounts = benchmarkModule.numAccounts; - this.custNameLength = SmallBankBenchmark.getCustomerNameLength(benchmarkModule.getCatalog().getTable(SmallBankConstants.TABLENAME_ACCOUNTS)); - this.custNameFormat = "%0" + this.custNameLength + "d"; - this.rng = new Flat(rng(), 0, this.numAccounts); + private static final Logger LOG = LoggerFactory.getLogger(SmallBankWorker.class); + + private final Amalgamate procAmalgamate; + private final Balance procBalance; + private final DepositChecking procDepositChecking; + private final SendPayment procSendPayment; + private final TransactSavings procTransactSavings; + private final WriteCheck procWriteCheck; + + private final DiscreteRNG rng; + private final long numAccounts; + private final int custNameLength; + private final String custNameFormat; + private final long[] custIdsBuffer = {-1L, -1L}; + + public SmallBankWorker(SmallBankBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + + // This is a minor speed-up to avoid having to invoke the hashmap look-up + // everytime we want to execute a txn. This is important to do on + // a client machine with not a lot of cores + this.procAmalgamate = this.getProcedure(Amalgamate.class); + this.procBalance = this.getProcedure(Balance.class); + this.procDepositChecking = this.getProcedure(DepositChecking.class); + this.procSendPayment = this.getProcedure(SendPayment.class); + this.procTransactSavings = this.getProcedure(TransactSavings.class); + this.procWriteCheck = this.getProcedure(WriteCheck.class); + + this.numAccounts = benchmarkModule.numAccounts; + this.custNameLength = + SmallBankBenchmark.getCustomerNameLength( + benchmarkModule.getCatalog().getTable(SmallBankConstants.TABLENAME_ACCOUNTS)); + this.custNameFormat = "%0" + this.custNameLength + "d"; + this.rng = new Flat(rng(), 0, this.numAccounts); + } + + protected void generateCustIds(boolean needsTwoAccts) { + for (int i = 0; i < this.custIdsBuffer.length; i++) { + this.custIdsBuffer[i] = this.rng.nextLong(); + + // They can never be the same! + if (i > 0 && this.custIdsBuffer[i - 1] == this.custIdsBuffer[i]) { + i--; + continue; + } + + // If we only need one acctId, break out here. + if (i == 0 && !needsTwoAccts) { + break; + } + // If we need two acctIds, then we need to go generate the second one + if (i == 0) { + continue; + } } - - protected void generateCustIds(boolean needsTwoAccts) { - for (int i = 0; i < this.custIdsBuffer.length; i++) { - this.custIdsBuffer[i] = this.rng.nextLong(); - - // They can never be the same! - if (i > 0 && this.custIdsBuffer[i - 1] == this.custIdsBuffer[i]) { - i--; - continue; - } - - // If we only need one acctId, break out here. - if (i == 0 && !needsTwoAccts) { - break; - } - // If we need two acctIds, then we need to go generate the second one - if (i == 0) { - continue; - } - - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Accounts: %s", Arrays.toString(this.custIdsBuffer))); - } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Accounts: %s", Arrays.toString(this.custIdsBuffer))); } - - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException { - Class procClass = txnType.getProcedureClass(); - - // Amalgamate - if (procClass.equals(Amalgamate.class)) { - this.generateCustIds(true); - this.procAmalgamate.run(conn, this.custIdsBuffer[0], this.custIdsBuffer[1]); - - // Balance - } else if (procClass.equals(Balance.class)) { - this.generateCustIds(false); - String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); - this.procBalance.run(conn, custName); - - // DepositChecking - } else if (procClass.equals(DepositChecking.class)) { - this.generateCustIds(false); - String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); - this.procDepositChecking.run(conn, custName, SmallBankConstants.PARAM_DEPOSIT_CHECKING_AMOUNT); - - // SendPayment - } else if (procClass.equals(SendPayment.class)) { - this.generateCustIds(true); - this.procSendPayment.run(conn, this.custIdsBuffer[0], this.custIdsBuffer[1], SmallBankConstants.PARAM_SEND_PAYMENT_AMOUNT); - - // TransactSavings - } else if (procClass.equals(TransactSavings.class)) { - this.generateCustIds(false); - String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); - this.procTransactSavings.run(conn, custName, SmallBankConstants.PARAM_TRANSACT_SAVINGS_AMOUNT); - - // WriteCheck - } else if (procClass.equals(WriteCheck.class)) { - this.generateCustIds(false); - String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); - this.procWriteCheck.run(conn, custName, SmallBankConstants.PARAM_WRITE_CHECK_AMOUNT); - - } - - return TransactionStatus.SUCCESS; + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException { + Class procClass = txnType.getProcedureClass(); + + // Amalgamate + if (procClass.equals(Amalgamate.class)) { + this.generateCustIds(true); + this.procAmalgamate.run(conn, this.custIdsBuffer[0], this.custIdsBuffer[1]); + + // Balance + } else if (procClass.equals(Balance.class)) { + this.generateCustIds(false); + String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); + this.procBalance.run(conn, custName); + + // DepositChecking + } else if (procClass.equals(DepositChecking.class)) { + this.generateCustIds(false); + String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); + this.procDepositChecking.run( + conn, custName, SmallBankConstants.PARAM_DEPOSIT_CHECKING_AMOUNT); + + // SendPayment + } else if (procClass.equals(SendPayment.class)) { + this.generateCustIds(true); + this.procSendPayment.run( + conn, + this.custIdsBuffer[0], + this.custIdsBuffer[1], + SmallBankConstants.PARAM_SEND_PAYMENT_AMOUNT); + + // TransactSavings + } else if (procClass.equals(TransactSavings.class)) { + this.generateCustIds(false); + String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); + this.procTransactSavings.run( + conn, custName, SmallBankConstants.PARAM_TRANSACT_SAVINGS_AMOUNT); + + // WriteCheck + } else if (procClass.equals(WriteCheck.class)) { + this.generateCustIds(false); + String custName = String.format(this.custNameFormat, this.custIdsBuffer[0]); + this.procWriteCheck.run(conn, custName, SmallBankConstants.PARAM_WRITE_CHECK_AMOUNT); } + return TransactionStatus.SUCCESS; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java index 4f850caca..ec56897d0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Amalgamate.java @@ -28,117 +28,113 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** - * Amalgamate Procedure - * Original version by Mohammad Alomari and Michael Cahill + * Amalgamate Procedure Original version by Mohammad Alomari and Michael Cahill * * @author pavlo */ public class Amalgamate extends Procedure { - // 2013-05-05 - // In the original version of the benchmark, this is suppose to be a look up - // on the customer's name. We don't have fast implementation of replicated - // secondary indexes, so we'll just ignore that part for now. - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE custid = ?" - ); - - public final SQLStmt GetSavingsBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + - " WHERE custid = ?" - ); - - public final SQLStmt GetCheckingBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING + - " WHERE custid = ?" - ); - - public final SQLStmt UpdateSavingsBalance = new SQLStmt( - "UPDATE " + SmallBankConstants.TABLENAME_SAVINGS + - " SET bal = bal - ? " + - " WHERE custid = ?" - ); - - public final SQLStmt UpdateCheckingBalance = new SQLStmt( - "UPDATE " + SmallBankConstants.TABLENAME_CHECKING + - " SET bal = bal + ? " + - " WHERE custid = ?" - ); - - public final SQLStmt ZeroCheckingBalance = new SQLStmt( - "UPDATE " + SmallBankConstants.TABLENAME_CHECKING + - " SET bal = 0.0 " + - " WHERE custid = ?" - ); - - public void run(Connection conn, long custId0, long custId1) throws SQLException { - // Get Account Information - try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custId0)) { - try (ResultSet r0 = stmt0.executeQuery()) { - if (!r0.next()) { - String msg = "Invalid account '" + custId0 + "'"; - throw new UserAbortException(msg); - } - } + // 2013-05-05 + // In the original version of the benchmark, this is suppose to be a look up + // on the customer's name. We don't have fast implementation of replicated + // secondary indexes, so we'll just ignore that part for now. + public final SQLStmt GetAccount = + new SQLStmt("SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + " WHERE custid = ?"); + + public final SQLStmt GetSavingsBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + " WHERE custid = ?"); + + public final SQLStmt GetCheckingBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING + " WHERE custid = ?"); + + public final SQLStmt UpdateSavingsBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_SAVINGS + + " SET bal = bal - ? " + + " WHERE custid = ?"); + + public final SQLStmt UpdateCheckingBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_CHECKING + + " SET bal = bal + ? " + + " WHERE custid = ?"); + + public final SQLStmt ZeroCheckingBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_CHECKING + + " SET bal = 0.0 " + + " WHERE custid = ?"); + + public void run(Connection conn, long custId0, long custId1) throws SQLException { + // Get Account Information + try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custId0)) { + try (ResultSet r0 = stmt0.executeQuery()) { + if (!r0.next()) { + String msg = "Invalid account '" + custId0 + "'"; + throw new UserAbortException(msg); } + } + } - try (PreparedStatement stmt1 = this.getPreparedStatement(conn, GetAccount, custId1)) { - try (ResultSet r1 = stmt1.executeQuery()) { - if (!r1.next()) { - String msg = "Invalid account '" + custId1 + "'"; - throw new UserAbortException(msg); - } - } + try (PreparedStatement stmt1 = this.getPreparedStatement(conn, GetAccount, custId1)) { + try (ResultSet r1 = stmt1.executeQuery()) { + if (!r1.next()) { + String msg = "Invalid account '" + custId1 + "'"; + throw new UserAbortException(msg); } + } + } - // Get Balance Information - double savingsBalance; - try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId0)) { - try (ResultSet balRes0 = balStmt0.executeQuery()) { - if (!balRes0.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_SAVINGS, - custId0); - throw new UserAbortException(msg); - } - savingsBalance = balRes0.getDouble(1); - } + // Get Balance Information + double savingsBalance; + try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId0)) { + try (ResultSet balRes0 = balStmt0.executeQuery()) { + if (!balRes0.next()) { + String msg = + String.format( + "No %s for customer #%d", SmallBankConstants.TABLENAME_SAVINGS, custId0); + throw new UserAbortException(msg); } + savingsBalance = balRes0.getDouble(1); + } + } - double checkingBalance; - try (PreparedStatement balStmt1 = this.getPreparedStatement(conn, GetCheckingBalance, custId1)) { - try (ResultSet balRes1 = balStmt1.executeQuery()) { - if (!balRes1.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_CHECKING, - custId1); - throw new UserAbortException(msg); - } - - checkingBalance = balRes1.getDouble(1); - } + double checkingBalance; + try (PreparedStatement balStmt1 = + this.getPreparedStatement(conn, GetCheckingBalance, custId1)) { + try (ResultSet balRes1 = balStmt1.executeQuery()) { + if (!balRes1.next()) { + String msg = + String.format( + "No %s for customer #%d", SmallBankConstants.TABLENAME_CHECKING, custId1); + throw new UserAbortException(msg); } - double total = checkingBalance + savingsBalance; - // assert(total >= 0); - - // Update Balance Information - try (PreparedStatement updateStmt0 = this.getPreparedStatement(conn, ZeroCheckingBalance, custId0)) { - updateStmt0.executeUpdate(); - } + checkingBalance = balRes1.getDouble(1); + } + } + double total = checkingBalance + savingsBalance; + // assert(total >= 0); - try (PreparedStatement updateStmt1 = this.getPreparedStatement(conn, UpdateSavingsBalance, total, custId1)) { - updateStmt1.executeUpdate(); - } + // Update Balance Information + try (PreparedStatement updateStmt0 = + this.getPreparedStatement(conn, ZeroCheckingBalance, custId0)) { + updateStmt0.executeUpdate(); + } + try (PreparedStatement updateStmt1 = + this.getPreparedStatement(conn, UpdateSavingsBalance, total, custId1)) { + updateStmt1.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Balance.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Balance.java index e9b870071..3bf0310fd 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Balance.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/Balance.java @@ -28,7 +28,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -36,63 +35,56 @@ public class Balance extends Procedure { - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE name = ?" - ); + public final SQLStmt GetAccount = + new SQLStmt("SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + " WHERE name = ?"); - public final SQLStmt GetSavingsBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + - " WHERE custid = ?" - ); + public final SQLStmt GetSavingsBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + " WHERE custid = ?"); - public final SQLStmt GetCheckingBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING + - " WHERE custid = ?" - ); + public final SQLStmt GetCheckingBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING + " WHERE custid = ?"); - public double run(Connection conn, String custName) throws SQLException { - // First convert the acctName to the acctId - long custId; + public double run(Connection conn, String custName) throws SQLException { + // First convert the acctName to the acctId + long custId; - try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { - try (ResultSet r0 = stmt0.executeQuery()) { - if (!r0.next()) { - String msg = "Invalid account '" + custName + "'"; - throw new UserAbortException(msg); - } - custId = r0.getLong(1); - } + try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { + try (ResultSet r0 = stmt0.executeQuery()) { + if (!r0.next()) { + String msg = "Invalid account '" + custName + "'"; + throw new UserAbortException(msg); } + custId = r0.getLong(1); + } + } - // Then get their account balances - double savingsBalance; - try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { - try (ResultSet balRes0 = balStmt0.executeQuery()) { - if (!balRes0.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_SAVINGS, - custId); - throw new UserAbortException(msg); - } - savingsBalance = balRes0.getDouble(1); - } + // Then get their account balances + double savingsBalance; + try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { + try (ResultSet balRes0 = balStmt0.executeQuery()) { + if (!balRes0.next()) { + String msg = + String.format("No %s for customer #%d", SmallBankConstants.TABLENAME_SAVINGS, custId); + throw new UserAbortException(msg); } + savingsBalance = balRes0.getDouble(1); + } + } - double checkingBalance; - try (PreparedStatement balStmt1 = this.getPreparedStatement(conn, GetCheckingBalance, custId)) { - try (ResultSet balRes1 = balStmt1.executeQuery()) { - if (!balRes1.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_CHECKING, - custId); - throw new UserAbortException(msg); - } - - checkingBalance = balRes1.getDouble(1); - } + double checkingBalance; + try (PreparedStatement balStmt1 = this.getPreparedStatement(conn, GetCheckingBalance, custId)) { + try (ResultSet balRes1 = balStmt1.executeQuery()) { + if (!balRes1.next()) { + String msg = + String.format( + "No %s for customer #%d", SmallBankConstants.TABLENAME_CHECKING, custId); + throw new UserAbortException(msg); } - return checkingBalance + savingsBalance; + checkingBalance = balRes1.getDouble(1); + } } -} \ No newline at end of file + + return checkingBalance + savingsBalance; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java index 44264986e..3453f2dae 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/DepositChecking.java @@ -28,49 +28,47 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** - * DepositChecking Procedure - * Original version by Mohammad Alomari and Michael Cahill + * DepositChecking Procedure Original version by Mohammad Alomari and Michael Cahill * * @author pavlo */ public class DepositChecking extends Procedure { - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE name = ?" - ); + public final SQLStmt GetAccount = + new SQLStmt("SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + " WHERE name = ?"); - public final SQLStmt UpdateCheckingBalance = new SQLStmt( - "UPDATE " + SmallBankConstants.TABLENAME_CHECKING + - " SET bal = bal + ? " + - " WHERE custid = ?" - ); + public final SQLStmt UpdateCheckingBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_CHECKING + + " SET bal = bal + ? " + + " WHERE custid = ?"); - public void run(Connection conn, String custName, double amount) throws SQLException { - // First convert the custName to the custId + public void run(Connection conn, String custName, double amount) throws SQLException { + // First convert the custName to the custId - long custId; + long custId; - try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { - try (ResultSet r0 = stmt0.executeQuery()) { - if (!r0.next()) { - String msg = "Invalid account '" + custName + "'"; - throw new UserAbortException(msg); - } - custId = r0.getLong(1); - } + try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { + try (ResultSet r0 = stmt0.executeQuery()) { + if (!r0.next()) { + String msg = "Invalid account '" + custName + "'"; + throw new UserAbortException(msg); } + custId = r0.getLong(1); + } + } - // Then update their checking balance - try (PreparedStatement stmt1 = this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { - stmt1.executeUpdate(); - } + // Then update their checking balance + try (PreparedStatement stmt1 = + this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { + stmt1.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/SendPayment.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/SendPayment.java index 7096d500b..39702d26e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/SendPayment.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/SendPayment.java @@ -28,7 +28,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -41,71 +40,74 @@ */ public class SendPayment extends Procedure { - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE custid = ?" - ); + 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 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 final SQLStmt UpdateCheckingBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_CHECKING + + " SET bal = bal + ? " + + " WHERE custid = ?"); - public void run(Connection conn, long sendAcct, long destAcct, double amount) throws SQLException { - // Get Account Information - try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, sendAcct)) { - try (ResultSet r0 = stmt0.executeQuery()) { - if (!r0.next()) { - String msg = "Invalid account '" + sendAcct + "'"; - throw new UserAbortException(msg); - } - } + public void run(Connection conn, long sendAcct, long destAcct, double amount) + throws SQLException { + // Get Account Information + try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, sendAcct)) { + try (ResultSet r0 = stmt0.executeQuery()) { + if (!r0.next()) { + String msg = "Invalid account '" + sendAcct + "'"; + throw new UserAbortException(msg); } + } + } - try (PreparedStatement stmt1 = this.getPreparedStatement(conn, GetAccount, destAcct)) { - try (ResultSet r1 = stmt1.executeQuery()) { - if (!r1.next()) { - String msg = "Invalid account '" + destAcct + "'"; - throw new UserAbortException(msg); - } - } + try (PreparedStatement stmt1 = this.getPreparedStatement(conn, GetAccount, destAcct)) { + try (ResultSet r1 = stmt1.executeQuery()) { + if (!r1.next()) { + String msg = "Invalid account '" + destAcct + "'"; + throw new UserAbortException(msg); } + } + } - // Get the sender's account balance - double balance; + // Get the sender's account balance + double balance; - try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetCheckingBalance, sendAcct)) { - try (ResultSet balRes0 = balStmt0.executeQuery()) { - if (!balRes0.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_CHECKING, - sendAcct); - throw new UserAbortException(msg); - } - balance = balRes0.getDouble(1); - } + try (PreparedStatement balStmt0 = + this.getPreparedStatement(conn, GetCheckingBalance, sendAcct)) { + try (ResultSet balRes0 = balStmt0.executeQuery()) { + if (!balRes0.next()) { + String msg = + String.format( + "No %s for customer #%d", SmallBankConstants.TABLENAME_CHECKING, sendAcct); + throw new UserAbortException(msg); } + balance = balRes0.getDouble(1); + } + } - // Make sure that they have enough money - if (balance < amount) { - String msg = String.format("Insufficient %s funds for customer #%d", - SmallBankConstants.TABLENAME_CHECKING, sendAcct); - throw new UserAbortException(msg); - } + // Make sure that they have enough money + if (balance < amount) { + String msg = + String.format( + "Insufficient %s funds for customer #%d", + SmallBankConstants.TABLENAME_CHECKING, sendAcct); + throw new UserAbortException(msg); + } - // Debt - try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount * -1d, sendAcct)) { - updateStmt.executeUpdate(); - } - // Credit - try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount, destAcct)) { - updateStmt.executeUpdate(); - } + // Debt + try (PreparedStatement updateStmt = + this.getPreparedStatement(conn, UpdateCheckingBalance, amount * -1d, sendAcct)) { + updateStmt.executeUpdate(); + } + // Credit + try (PreparedStatement updateStmt = + this.getPreparedStatement(conn, UpdateCheckingBalance, amount, destAcct)) { + updateStmt.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java index 5e397925a..a914effb4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/TransactSavings.java @@ -28,77 +28,72 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** - * TransactSavings Procedure - * Original version by Mohammad Alomari and Michael Cahill + * TransactSavings Procedure Original version by Mohammad Alomari and Michael Cahill * * @author pavlo */ public class TransactSavings extends Procedure { - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE name = ?" - ); + public final SQLStmt GetAccount = + new SQLStmt("SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + " WHERE name = ?"); - public final SQLStmt GetSavingsBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + - " WHERE custid = ?" - ); + public final SQLStmt GetSavingsBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + " WHERE custid = ?"); - public final SQLStmt UpdateSavingsBalance = new SQLStmt( - "UPDATE " + SmallBankConstants.TABLENAME_SAVINGS + - " SET bal = bal - ? " + - " WHERE custid = ?" - ); + public final SQLStmt UpdateSavingsBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_SAVINGS + + " SET bal = bal - ? " + + " WHERE custid = ?"); - public void run(Connection conn, String custName, double amount) throws SQLException { - // First convert the custName to the acctId - long custId; + public void run(Connection conn, String custName, double amount) throws SQLException { + // First convert the custName to the acctId + long custId; - try (PreparedStatement stmt = this.getPreparedStatement(conn, GetAccount, custName)) { - try (ResultSet result = stmt.executeQuery()) { - if (!result.next()) { - String msg = "Invalid account '" + custName + "'"; - throw new UserAbortException(msg); - } - custId = result.getLong(1); - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, GetAccount, custName)) { + try (ResultSet result = stmt.executeQuery()) { + if (!result.next()) { + String msg = "Invalid account '" + custName + "'"; + throw new UserAbortException(msg); } + custId = result.getLong(1); + } + } - // Get Balance Information + // Get Balance Information - double balance; + double balance; - try (PreparedStatement stmt = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { - try (ResultSet result = stmt.executeQuery()) { - if (!result.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_SAVINGS, - custId); - throw new UserAbortException(msg); - } - balance = result.getDouble(1) - amount; - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { + try (ResultSet result = stmt.executeQuery()) { + if (!result.next()) { + String msg = + String.format("No %s for customer #%d", SmallBankConstants.TABLENAME_SAVINGS, custId); + throw new UserAbortException(msg); } + balance = result.getDouble(1) - amount; + } + } - // Make sure that they have enough - if (balance < 0) { - String msg = String.format("Negative %s balance for customer #%d", - SmallBankConstants.TABLENAME_SAVINGS, - custId); - throw new UserAbortException(msg); - } + // Make sure that they have enough + if (balance < 0) { + String msg = + String.format( + "Negative %s balance for customer #%d", SmallBankConstants.TABLENAME_SAVINGS, custId); + throw new UserAbortException(msg); + } - // Then update their savings balance - try (PreparedStatement stmt = this.getPreparedStatement(conn, UpdateSavingsBalance, amount, custId)) { - stmt.executeUpdate(); - } + // Then update their savings balance + try (PreparedStatement stmt = + this.getPreparedStatement(conn, UpdateSavingsBalance, amount, custId)) { + stmt.executeUpdate(); } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java index 7bc12ff91..8ab0b1ebd 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/smallbank/procedures/WriteCheck.java @@ -28,96 +28,89 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.smallbank.SmallBankConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** - * WriteCheck Procedure - * Original version by Mohammad Alomari and Michael Cahill + * WriteCheck Procedure Original version by Mohammad Alomari and Michael Cahill * * @author pavlo */ public class WriteCheck extends Procedure { - public final SQLStmt GetAccount = new SQLStmt( - "SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + - " WHERE name = ?" - ); + public final SQLStmt GetAccount = + new SQLStmt("SELECT * FROM " + SmallBankConstants.TABLENAME_ACCOUNTS + " WHERE name = ?"); - public final SQLStmt GetSavingsBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + - " WHERE custid = ?" - ); + public final SQLStmt GetSavingsBalance = + new SQLStmt("SELECT bal FROM " + SmallBankConstants.TABLENAME_SAVINGS + " WHERE custid = ?"); - public final SQLStmt GetCheckingBalance = new SQLStmt( - "SELECT bal FROM " + SmallBankConstants.TABLENAME_CHECKING + - " 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 final SQLStmt UpdateCheckingBalance = + new SQLStmt( + "UPDATE " + + SmallBankConstants.TABLENAME_CHECKING + + " SET bal = bal - ? " + + " WHERE custid = ?"); - public void run(Connection conn, String custName, double amount) throws SQLException { - // First convert the custName to the custId - long custId; + public void run(Connection conn, String custName, double amount) throws SQLException { + // First convert the custName to the custId + long custId; - try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { - try (ResultSet r0 = stmt0.executeQuery()) { - if (!r0.next()) { - String msg = "Invalid account '" + custName + "'"; - throw new UserAbortException(msg); - } - custId = r0.getLong(1); - } + try (PreparedStatement stmt0 = this.getPreparedStatement(conn, GetAccount, custName)) { + try (ResultSet r0 = stmt0.executeQuery()) { + if (!r0.next()) { + String msg = "Invalid account '" + custName + "'"; + throw new UserAbortException(msg); } + custId = r0.getLong(1); + } + } - // Then get their account balances - double savingsBalance; - - try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { - try (ResultSet balRes0 = balStmt0.executeQuery()) { - if (!balRes0.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_SAVINGS, - custId); - throw new UserAbortException(msg); - } + // Then get their account balances + double savingsBalance; - savingsBalance = balRes0.getDouble(1); - } + try (PreparedStatement balStmt0 = this.getPreparedStatement(conn, GetSavingsBalance, custId)) { + try (ResultSet balRes0 = balStmt0.executeQuery()) { + if (!balRes0.next()) { + String msg = + String.format("No %s for customer #%d", SmallBankConstants.TABLENAME_SAVINGS, custId); + throw new UserAbortException(msg); } + savingsBalance = balRes0.getDouble(1); + } + } - double checkingBalance; + double checkingBalance; - try (PreparedStatement balStmt1 = this.getPreparedStatement(conn, GetCheckingBalance, custId)) { - try (ResultSet balRes1 = balStmt1.executeQuery()) { - if (!balRes1.next()) { - String msg = String.format("No %s for customer #%d", - SmallBankConstants.TABLENAME_CHECKING, - custId); - throw new UserAbortException(msg); - } - checkingBalance = balRes1.getDouble(1); - } + try (PreparedStatement balStmt1 = this.getPreparedStatement(conn, GetCheckingBalance, custId)) { + try (ResultSet balRes1 = balStmt1.executeQuery()) { + if (!balRes1.next()) { + String msg = + String.format( + "No %s for customer #%d", SmallBankConstants.TABLENAME_CHECKING, custId); + throw new UserAbortException(msg); } + checkingBalance = balRes1.getDouble(1); + } + } - double total = checkingBalance + savingsBalance; - - if (total < amount) { - try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount - 1, custId)) { - updateStmt.executeUpdate(); - } - } else { - try (PreparedStatement updateStmt = this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { - updateStmt.executeUpdate(); - } - } + double total = checkingBalance + savingsBalance; + + if (total < amount) { + try (PreparedStatement updateStmt = + this.getPreparedStatement(conn, UpdateCheckingBalance, amount - 1, custId)) { + updateStmt.executeUpdate(); + } + } else { + try (PreparedStatement updateStmt = + this.getPreparedStatement(conn, UpdateCheckingBalance, amount, custId)) { + updateStmt.executeUpdate(); + } } -} \ No newline at end of file + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPBenchmark.java index 6d94f78b8..ddc1b72f8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tatp; import com.oltpbenchmark.WorkloadConfiguration; @@ -23,32 +22,31 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tatp.procedures.DeleteCallForwarding; - import java.util.ArrayList; import java.util.List; public final class TATPBenchmark extends BenchmarkModule { - public TATPBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } + public TATPBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected Package getProcedurePackageImpl() { - return (DeleteCallForwarding.class.getPackage()); - } + @Override + protected Package getProcedurePackageImpl() { + return (DeleteCallForwarding.class.getPackage()); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new TATPWorker(this, i)); - } - return (workers); + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new TATPWorker(this, i)); } + return (workers); + } - @Override - protected Loader makeLoaderImpl() { - return (new TATPLoader(this)); - } + @Override + protected Loader makeLoaderImpl() { + return (new TATPLoader(this)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPConstants.java index 72a02b50a..b216a56f3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPConstants.java @@ -15,39 +15,37 @@ * */ - package com.oltpbenchmark.benchmarks.tatp; public abstract class TATPConstants { - public static final long DEFAULT_NUM_SUBSCRIBERS = 100000L; - - public static final int SUB_NBR_PADDING_SIZE = 15; - - - // ---------------------------------------------------------------- - // STORED PROCEDURE EXECUTION FREQUENCIES (0-100) - // ---------------------------------------------------------------- - public static final int FREQUENCY_DELETE_CALL_FORWARDING = 2; // Multi - public static final int FREQUENCY_GET_ACCESS_DATA = 35; // Single - public static final int FREQUENCY_GET_NEW_DESTINATION = 10; // Single - public static final int FREQUENCY_GET_SUBSCRIBER_DATA = 35; // Single - public static final int FREQUENCY_INSERT_CALL_FORWARDING = 2; // Multi - public static final int FREQUENCY_UPDATE_LOCATION = 14; // Multi - public static final int FREQUENCY_UPDATE_SUBSCRIBER_DATA = 2; // Single - - // ---------------------------------------------------------------- - // TABLE NAMES - // ---------------------------------------------------------------- - public static final String TABLENAME_SUBSCRIBER = "subscriber"; - public static final String TABLENAME_ACCESS_INFO = "access_info"; - public static final String TABLENAME_SPECIAL_FACILITY = "special_facility"; - public static final String TABLENAME_CALL_FORWARDING = "call_forwarding"; - - public static final String[] TABLENAMES = { - TABLENAME_SUBSCRIBER, - TABLENAME_ACCESS_INFO, - TABLENAME_SPECIAL_FACILITY, - TABLENAME_CALL_FORWARDING - }; + public static final long DEFAULT_NUM_SUBSCRIBERS = 100000L; + + public static final int SUB_NBR_PADDING_SIZE = 15; + + // ---------------------------------------------------------------- + // STORED PROCEDURE EXECUTION FREQUENCIES (0-100) + // ---------------------------------------------------------------- + public static final int FREQUENCY_DELETE_CALL_FORWARDING = 2; // Multi + public static final int FREQUENCY_GET_ACCESS_DATA = 35; // Single + public static final int FREQUENCY_GET_NEW_DESTINATION = 10; // Single + public static final int FREQUENCY_GET_SUBSCRIBER_DATA = 35; // Single + public static final int FREQUENCY_INSERT_CALL_FORWARDING = 2; // Multi + public static final int FREQUENCY_UPDATE_LOCATION = 14; // Multi + public static final int FREQUENCY_UPDATE_SUBSCRIBER_DATA = 2; // Single + + // ---------------------------------------------------------------- + // TABLE NAMES + // ---------------------------------------------------------------- + public static final String TABLENAME_SUBSCRIBER = "subscriber"; + public static final String TABLENAME_ACCESS_INFO = "access_info"; + public static final String TABLENAME_SPECIAL_FACILITY = "special_facility"; + public static final String TABLENAME_CALL_FORWARDING = "call_forwarding"; + + public static final String[] TABLENAMES = { + TABLENAME_SUBSCRIBER, + TABLENAME_ACCESS_INFO, + TABLENAME_SPECIAL_FACILITY, + TABLENAME_CALL_FORWARDING + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java index 14401fd34..dd0253f89 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPLoader.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.benchmarks.tatp; import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -31,275 +29,288 @@ import java.util.concurrent.CountDownLatch; public final class TATPLoader extends Loader { - private final long subscriberSize; + private final long subscriberSize; - public TATPLoader(TATPBenchmark benchmark) { - super(benchmark); - this.subscriberSize = Math.round(TATPConstants.DEFAULT_NUM_SUBSCRIBERS * this.scaleFactor); - if (LOG.isDebugEnabled()) { - LOG.debug("CONSTRUCTOR: {}", TATPLoader.class.getName()); - } + public TATPLoader(TATPBenchmark benchmark) { + super(benchmark); + this.subscriberSize = Math.round(TATPConstants.DEFAULT_NUM_SUBSCRIBERS * this.scaleFactor); + if (LOG.isDebugEnabled()) { + LOG.debug("CONSTRUCTOR: {}", TATPLoader.class.getName()); } - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - final long itemsPerThread = Math.max(this.subscriberSize / numLoaders, 1); - final int numSubThreads = (int) Math.ceil((double) this.subscriberSize / itemsPerThread); - final CountDownLatch subLatch = new CountDownLatch(numSubThreads); - - // SUBSCRIBER - for (int i = 0; i < numSubThreads; i++) { - final long lo = i * itemsPerThread + 1; - final long hi = Math.min(this.subscriberSize, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - genSubscriber(conn, lo, hi); - - } - - @Override - public void afterLoad() { - subLatch.countDown(); - } - }); - } - - // ACCESS_INFO depends on SUBSCRIBER - threads.add(new LoaderThread(this.benchmark) { + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + final long itemsPerThread = Math.max(this.subscriberSize / numLoaders, 1); + final int numSubThreads = (int) Math.ceil((double) this.subscriberSize / itemsPerThread); + final CountDownLatch subLatch = new CountDownLatch(numSubThreads); + + // SUBSCRIBER + for (int i = 0; i < numSubThreads; i++) { + final long lo = i * itemsPerThread + 1; + final long hi = Math.min(this.subscriberSize, (i + 1) * itemsPerThread); + + threads.add( + new LoaderThread(this.benchmark) { @Override public void load(Connection conn) throws SQLException { - genAccessInfo(conn); + genSubscriber(conn, lo, hi); } @Override - public void beforeLoad() { - try { - subLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + public void afterLoad() { + subLatch.countDown(); } - }); + }); + } - // SPECIAL_FACILITY SPE and CALL_FORWARDING CAL - // SPE depends on SUBSCRIBER, CAL depends on SPE - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - genSpeAndCal(conn); + // ACCESS_INFO depends on SUBSCRIBER + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + genAccessInfo(conn); + } + + @Override + public void beforeLoad() { + try { + subLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } + }); - @Override - public void beforeLoad() { - try { - subLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + // SPECIAL_FACILITY SPE and CALL_FORWARDING CAL + // SPE depends on SUBSCRIBER, CAL depends on SPE + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + genSpeAndCal(conn); + } + + @Override + public void beforeLoad() { + try { + subLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } }); - return threads; - } + return threads; + } - /** - * Populate Subscriber table per benchmark spec. - */ - void genSubscriber(Connection conn, long lo, long hi) throws SQLException { - // Create a prepared statement - Table catalog_tbl = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_SUBSCRIBER); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement pstmt = conn.prepareStatement(sql)) { - - long total = 0; - int batch = 0; - - for (long s_id = lo; s_id <= hi; s_id++) { - int col = 0; - - pstmt.setLong(++col, s_id); - pstmt.setString(++col, TATPUtil.padWithZero(s_id)); - - // BIT_## - for (int j = 0; j < 10; j++) { - pstmt.setByte(++col, TATPUtil.number(0, 1).byteValue()); - } - // HEX_## - for (int j = 0; j < 10; j++) { - pstmt.setByte(++col, TATPUtil.number(0, 15).byteValue()); - } - // BYTE2_## - for (int j = 0; j < 10; j++) { - pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); - } - // msc_location + vlr_location - for (int j = 0; j < 2; j++) { - pstmt.setInt(++col, TATPUtil.number(0, Integer.MAX_VALUE).intValue()); - } - total++; - pstmt.addBatch(); - - if (++batch >= workConf.getBatchSize()) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); - } - pstmt.executeBatch(); - - batch = 0; - } - } - if (batch > 0) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); - } - pstmt.executeBatch(); - } + /** Populate Subscriber table per benchmark spec. */ + void genSubscriber(Connection conn, long lo, long hi) throws SQLException { + // Create a prepared statement + Table catalog_tbl = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_SUBSCRIBER); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + + long total = 0; + int batch = 0; + for (long s_id = lo; s_id <= hi; s_id++) { + int col = 0; + + pstmt.setLong(++col, s_id); + pstmt.setString(++col, TATPUtil.padWithZero(s_id)); + + // BIT_## + for (int j = 0; j < 10; j++) { + pstmt.setByte(++col, TATPUtil.number(0, 1).byteValue()); } - } + // HEX_## + for (int j = 0; j < 10; j++) { + pstmt.setByte(++col, TATPUtil.number(0, 15).byteValue()); + } + // BYTE2_## + for (int j = 0; j < 10; j++) { + pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); + } + // msc_location + vlr_location + for (int j = 0; j < 2; j++) { + pstmt.setInt(++col, TATPUtil.number(0, Integer.MAX_VALUE).intValue()); + } + total++; + pstmt.addBatch(); - /** - * Populate Access_Info table per benchmark spec. - */ - void genAccessInfo(Connection conn) throws SQLException { - // Create a prepared statement - Table catalog_tbl = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_ACCESS_INFO); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement pstmt = conn.prepareStatement(sql)) { - - int s_id = 0; - int[] arr = {1, 2, 3, 4}; - - int[] ai_types = TATPUtil.subArr(arr, 1, 4); - long total = 0; - int batch = 0; - while (s_id++ < subscriberSize) { - for (int ai_type : ai_types) { - int col = 0; - pstmt.setLong(++col, s_id); - pstmt.setByte(++col, (byte) ai_type); - pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); - pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); - pstmt.setString(++col, TATPUtil.astring(3, 3)); - pstmt.setString(++col, TATPUtil.astring(5, 5)); - pstmt.addBatch(); - batch++; - total++; - } - if (batch >= workConf.getBatchSize()) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %6d / %d", TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); - } - pstmt.executeBatch(); - - batch = 0; - } - } - if (batch > 0) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %6d / %d", TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); - } - pstmt.executeBatch(); - } + if (++batch >= workConf.getBatchSize()) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); + } + pstmt.executeBatch(); + + batch = 0; + } + } + if (batch > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: %6d / %d", catalog_tbl.getName(), total, subscriberSize)); + } + pstmt.executeBatch(); + } + } + } + + /** Populate Access_Info table per benchmark spec. */ + void genAccessInfo(Connection conn) throws SQLException { + // Create a prepared statement + Table catalog_tbl = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_ACCESS_INFO); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + + int s_id = 0; + int[] arr = {1, 2, 3, 4}; + + int[] ai_types = TATPUtil.subArr(arr, 1, 4); + long total = 0; + int batch = 0; + while (s_id++ < subscriberSize) { + for (int ai_type : ai_types) { + int col = 0; + pstmt.setLong(++col, s_id); + pstmt.setByte(++col, (byte) ai_type); + pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); + pstmt.setShort(++col, TATPUtil.number(0, 255).shortValue()); + pstmt.setString(++col, TATPUtil.astring(3, 3)); + pstmt.setString(++col, TATPUtil.astring(5, 5)); + pstmt.addBatch(); + batch++; + total++; + } + if (batch >= workConf.getBatchSize()) { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s: %6d / %d", + TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); + } + pstmt.executeBatch(); + + batch = 0; + } + } + if (batch > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s: %6d / %d", + TATPConstants.TABLENAME_ACCESS_INFO, total, ai_types.length * subscriberSize)); } + pstmt.executeBatch(); + } } + } - /** - * Populate Special_Facility table and CallForwarding table per benchmark - * spec. - */ - void genSpeAndCal(Connection conn) throws SQLException { - // Create a prepared statement - Table catalog_spe = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_SPECIAL_FACILITY); - Table catalog_cal = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_CALL_FORWARDING); - String spe_sql = SQLUtil.getInsertSQL(catalog_spe, this.getDatabaseType()); + /** Populate Special_Facility table and CallForwarding table per benchmark spec. */ + void genSpeAndCal(Connection conn) throws SQLException { + // Create a prepared statement + Table catalog_spe = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_SPECIAL_FACILITY); + Table catalog_cal = benchmark.getCatalog().getTable(TATPConstants.TABLENAME_CALL_FORWARDING); + String spe_sql = SQLUtil.getInsertSQL(catalog_spe, this.getDatabaseType()); - int spe_batch = 0; - long spe_total = 0; + int spe_batch = 0; + long spe_total = 0; - String cal_sql = SQLUtil.getInsertSQL(catalog_cal, this.getDatabaseType()); + String cal_sql = SQLUtil.getInsertSQL(catalog_cal, this.getDatabaseType()); - long cal_total = 0; + long cal_total = 0; - int s_id = 0; - int[] spe_arr = {1, 2, 3, 4}; - int[] cal_arr = {0, 8, 6}; - if (LOG.isDebugEnabled()) { - LOG.debug("subscriberSize = {}", subscriberSize); - } - if (LOG.isDebugEnabled()) { - LOG.debug("batchSize = {}", workConf.getBatchSize()); + int s_id = 0; + int[] spe_arr = {1, 2, 3, 4}; + int[] cal_arr = {0, 8, 6}; + if (LOG.isDebugEnabled()) { + LOG.debug("subscriberSize = {}", subscriberSize); + } + if (LOG.isDebugEnabled()) { + LOG.debug("batchSize = {}", workConf.getBatchSize()); + } + + try (PreparedStatement cal_pstmt = conn.prepareStatement(cal_sql); + PreparedStatement spe_pstmt = conn.prepareStatement(spe_sql)) { + boolean cal_added = false; + while (s_id++ < subscriberSize) { + int[] sf_types = TATPUtil.subArr(spe_arr, 1, 4); + for (int sf_type : sf_types) { + int spe_col = 0; + spe_pstmt.setLong(++spe_col, s_id); + spe_pstmt.setByte(++spe_col, (byte) sf_type); + spe_pstmt.setByte(++spe_col, TATPUtil.isActive()); + spe_pstmt.setShort(++spe_col, TATPUtil.number(0, 255).shortValue()); + spe_pstmt.setShort(++spe_col, TATPUtil.number(0, 255).shortValue()); + spe_pstmt.setString(++spe_col, TATPUtil.astring(5, 5)); + spe_pstmt.addBatch(); + spe_batch++; + spe_total++; + + // now call_forwarding + int[] start_times = TATPUtil.subArr(cal_arr, 0, 3); + for (int start_time : start_times) { + int cal_col = 0; + cal_pstmt.setLong(++cal_col, s_id); + cal_pstmt.setByte(++cal_col, (byte) sf_type); + cal_pstmt.setByte(++cal_col, (byte) start_time); + cal_pstmt.setByte(++cal_col, (byte) (start_time + TATPUtil.number(1, 8))); + cal_pstmt.setString(++cal_col, TATPUtil.nstring(15, 15)); + cal_pstmt.addBatch(); + cal_added = true; + cal_total++; + } } - try (PreparedStatement cal_pstmt = conn.prepareStatement(cal_sql); - PreparedStatement spe_pstmt = conn.prepareStatement(spe_sql)) { - boolean cal_added = false; - while (s_id++ < subscriberSize) { - int[] sf_types = TATPUtil.subArr(spe_arr, 1, 4); - for (int sf_type : sf_types) { - int spe_col = 0; - spe_pstmt.setLong(++spe_col, s_id); - spe_pstmt.setByte(++spe_col, (byte) sf_type); - spe_pstmt.setByte(++spe_col, TATPUtil.isActive()); - spe_pstmt.setShort(++spe_col, TATPUtil.number(0, 255).shortValue()); - spe_pstmt.setShort(++spe_col, TATPUtil.number(0, 255).shortValue()); - spe_pstmt.setString(++spe_col, TATPUtil.astring(5, 5)); - spe_pstmt.addBatch(); - spe_batch++; - spe_total++; - - // now call_forwarding - int[] start_times = TATPUtil.subArr(cal_arr, 0, 3); - for (int start_time : start_times) { - int cal_col = 0; - cal_pstmt.setLong(++cal_col, s_id); - cal_pstmt.setByte(++cal_col, (byte) sf_type); - cal_pstmt.setByte(++cal_col, (byte) start_time); - cal_pstmt.setByte(++cal_col, (byte) (start_time + TATPUtil.number(1, 8))); - cal_pstmt.setString(++cal_col, TATPUtil.nstring(15, 15)); - cal_pstmt.addBatch(); - cal_added = true; - cal_total++; - } - } - - if (spe_batch > workConf.getBatchSize()) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %d (%s %d / %d)", TATPConstants.TABLENAME_SPECIAL_FACILITY, spe_total, TATPConstants.TABLENAME_SUBSCRIBER, s_id, subscriberSize)); - } - spe_pstmt.executeBatch(); - - if (cal_added) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %d (%s %d / %d)", TATPConstants.TABLENAME_CALL_FORWARDING, cal_total, TATPConstants.TABLENAME_SUBSCRIBER, s_id, subscriberSize)); - } - cal_pstmt.executeBatch(); - cal_added = false; - } - - spe_batch = 0; - } + if (spe_batch > workConf.getBatchSize()) { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s: %d (%s %d / %d)", + TATPConstants.TABLENAME_SPECIAL_FACILITY, + spe_total, + TATPConstants.TABLENAME_SUBSCRIBER, + s_id, + subscriberSize)); + } + spe_pstmt.executeBatch(); + + if (cal_added) { + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "%s: %d (%s %d / %d)", + TATPConstants.TABLENAME_CALL_FORWARDING, + cal_total, + TATPConstants.TABLENAME_SUBSCRIBER, + s_id, + subscriberSize)); } - LOG.debug("spe_batch = {}", spe_batch); - if (spe_batch > 0) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_SPECIAL_FACILITY, spe_total)); - } - spe_pstmt.executeBatch(); - - if (cal_added) { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_CALL_FORWARDING, cal_total)); - } - cal_pstmt.executeBatch(); - cal_added = false; - } + cal_pstmt.executeBatch(); + cal_added = false; + } - } + spe_batch = 0; + } + } + LOG.debug("spe_batch = {}", spe_batch); + if (spe_batch > 0) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_SPECIAL_FACILITY, spe_total)); + } + spe_pstmt.executeBatch(); + + if (cal_added) { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s: %d", TATPConstants.TABLENAME_CALL_FORWARDING, cal_total)); + } + cal_pstmt.executeBatch(); + cal_added = false; } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPUtil.java index f299226b9..8bec03939 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPUtil.java @@ -15,90 +15,88 @@ * */ - package com.oltpbenchmark.benchmarks.tatp; import java.util.Random; public abstract class TATPUtil { - public static final Random rand = new Random(); - - public static byte isActive() { - return (byte) (number(1, 100) < number(86, 100) ? 1 : 0); - } - - public static Long getSubscriberId(long subscriberSize) { - return (TATPUtil.number(1, subscriberSize)); - } - - // modified from tpcc.RandomGenerator - - /** - * @returns a random alphabetic string with length in range [minimum_length, maximum_length]. - */ - public static String astring(int minimum_length, int maximum_length) { - return randomString(minimum_length, maximum_length, 'A', 26); + public static final Random rand = new Random(); + + public static byte isActive() { + return (byte) (number(1, 100) < number(86, 100) ? 1 : 0); + } + + public static Long getSubscriberId(long subscriberSize) { + return (TATPUtil.number(1, subscriberSize)); + } + + // modified from tpcc.RandomGenerator + + /** + * @returns a random alphabetic string with length in range [minimum_length, maximum_length]. + */ + public static String astring(int minimum_length, int maximum_length) { + return randomString(minimum_length, maximum_length, 'A', 26); + } + + // taken from tpcc.RandomGenerator + + /** + * @returns a random numeric string with length in range [minimum_length, maximum_length]. + */ + public static String nstring(int minimum_length, int maximum_length) { + return randomString(minimum_length, maximum_length, '0', 10); + } + + // taken from tpcc.RandomGenerator + public static String randomString( + int minimum_length, int maximum_length, char base, int numCharacters) { + int length = number(minimum_length, maximum_length).intValue(); + byte baseByte = (byte) base; + byte[] bytes = new byte[length]; + for (int i = 0; i < length; ++i) { + bytes[i] = (byte) (baseByte + number(0, numCharacters - 1)); } + return new String(bytes); + } - // taken from tpcc.RandomGenerator + // taken from tpcc.RandomGenerator + public static Long number(long minimum, long maximum) { - /** - * @returns a random numeric string with length in range [minimum_length, maximum_length]. - */ - public static String nstring(int minimum_length, int maximum_length) { - return randomString(minimum_length, maximum_length, '0', 10); - } + return Math.abs(rand.nextLong()) % (maximum - minimum + 1) + minimum; + } - // taken from tpcc.RandomGenerator - public static String randomString(int minimum_length, int maximum_length, char base, int numCharacters) { - int length = number(minimum_length, maximum_length).intValue(); - byte baseByte = (byte) base; - byte[] bytes = new byte[length]; - for (int i = 0; i < length; ++i) { - bytes[i] = (byte) (baseByte + number(0, numCharacters - 1)); - } - return new String(bytes); + public static String padWithZero(long n) { + String str = Long.toString(n); + char[] zeros = new char[TATPConstants.SUB_NBR_PADDING_SIZE - str.length()]; + for (int i = 0; i < zeros.length; i++) { + zeros[i] = '0'; } - - // taken from tpcc.RandomGenerator - public static Long number(long minimum, long maximum) { - - return Math.abs(rand.nextLong()) % (maximum - minimum + 1) + minimum; - } - - public static String padWithZero(long n) { - String str = Long.toString(n); - char[] zeros = new char[TATPConstants.SUB_NBR_PADDING_SIZE - str.length()]; - for (int i = 0; i < zeros.length; i++) { - zeros[i] = '0'; - } - return (new String(zeros) + str); - } - - /** - * Returns sub array of arr, with length in range [min_len, max_len]. - * Each element in arr appears at most once in sub array. - */ - public static int[] subArr(int[] arr, int min_len, int max_len) { - - int sub_len = number(min_len, max_len).intValue(); - int arr_len = arr.length; - - - int[] sub = new int[sub_len]; - for (int i = 0; i < sub_len; i++) { - int j = number(0, arr_len - 1).intValue(); - sub[i] = arr[j]; - //arr[j] put to tail - int tmp = arr[j]; - arr[j] = arr[arr_len - 1]; - arr[arr_len - 1] = tmp; - - arr_len--; - } - - return sub; + return (new String(zeros) + str); + } + + /** + * Returns sub array of arr, with length in range [min_len, max_len]. Each element in arr appears + * at most once in sub array. + */ + public static int[] subArr(int[] arr, int min_len, int max_len) { + + int sub_len = number(min_len, max_len).intValue(); + int arr_len = arr.length; + + int[] sub = new int[sub_len]; + for (int i = 0; i < sub_len; i++) { + int j = number(0, arr_len - 1).intValue(); + sub[i] = arr[j]; + // arr[j] put to tail + int tmp = arr[j]; + arr[j] = arr[arr_len - 1]; + arr[arr_len - 1] = tmp; + + arr_len--; } + return sub; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPWorker.java index d27f301a6..2e56acbe6 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/TATPWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tatp; import com.oltpbenchmark.api.Procedure; @@ -24,164 +23,180 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tatp.procedures.*; import com.oltpbenchmark.types.TransactionStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class TATPWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(TATPWorker.class); - - /** - * Each Transaction element provides an TransactionInvoker to create the proper - * arguments used to invoke the stored procedure - */ - private interface TransactionInvoker { - /** - * Generate the proper arguments used to invoke the given stored procedure - * - * @param subscriberSize - * @return - */ - void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException; - } + private static final Logger LOG = LoggerFactory.getLogger(TATPWorker.class); + /** + * Each Transaction element provides an TransactionInvoker to create the proper arguments used to + * invoke the stored procedure + */ + private interface TransactionInvoker { /** - * Set of transactions structs with their appropriate parameters + * Generate the proper arguments used to invoke the given stored procedure + * + * @param subscriberSize + * @return */ - public enum Transaction { - DeleteCallForwarding(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((DeleteCallForwarding) proc).run( - conn, - TATPUtil.padWithZero(s_id), // s_id - TATPUtil.number(1, 4).byteValue(), // sf_type - (byte) (8 * TATPUtil.number(0, 2)) // start_time - ); - } + void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException; + } + + /** Set of transactions structs with their appropriate parameters */ + public enum Transaction { + DeleteCallForwarding( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((DeleteCallForwarding) proc) + .run( + conn, + TATPUtil.padWithZero(s_id), // s_id + TATPUtil.number(1, 4).byteValue(), // sf_type + (byte) (8 * TATPUtil.number(0, 2)) // start_time + ); + } }), - GetAccessData(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((GetAccessData) proc).run( - conn, - s_id, // s_id - TATPUtil.number(1, 4).byteValue() // ai_type - ); - } + GetAccessData( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((GetAccessData) proc) + .run( + conn, + s_id, // s_id + TATPUtil.number(1, 4).byteValue() // ai_type + ); + } }), - GetNewDestination(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((GetNewDestination) proc).run( - conn, - s_id, // s_id - TATPUtil.number(1, 4).byteValue(), // sf_type - (byte) (8 * TATPUtil.number(0, 2)), // start_time - TATPUtil.number(1, 24).byteValue() // end_time - ); - } + GetNewDestination( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((GetNewDestination) proc) + .run( + conn, + s_id, // s_id + TATPUtil.number(1, 4).byteValue(), // sf_type + (byte) (8 * TATPUtil.number(0, 2)), // start_time + TATPUtil.number(1, 24).byteValue() // end_time + ); + } }), - GetSubscriberData(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((GetSubscriberData) proc).run( - conn, - s_id // s_id - ); - } + GetSubscriberData( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((GetSubscriberData) proc) + .run( + conn, s_id // s_id + ); + } }), - InsertCallForwarding(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((InsertCallForwarding) proc).run( - conn, - TATPUtil.padWithZero(s_id), // sub_nbr - TATPUtil.number(1, 4).byteValue(), // sf_type - (byte) (8 * TATPUtil.number(0, 2)), // start_time - TATPUtil.number(1, 24).byteValue(), // end_time - TATPUtil.padWithZero(s_id) // numberx - ); - } + InsertCallForwarding( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((InsertCallForwarding) proc) + .run( + conn, + TATPUtil.padWithZero(s_id), // sub_nbr + TATPUtil.number(1, 4).byteValue(), // sf_type + (byte) (8 * TATPUtil.number(0, 2)), // start_time + TATPUtil.number(1, 24).byteValue(), // end_time + TATPUtil.padWithZero(s_id) // numberx + ); + } }), - UpdateLocation(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((UpdateLocation) proc).run( - conn, - TATPUtil.number(0, Integer.MAX_VALUE).intValue(), // vlr_location - TATPUtil.padWithZero(s_id) // sub_nbr - ); - } + UpdateLocation( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((UpdateLocation) proc) + .run( + conn, + TATPUtil.number(0, Integer.MAX_VALUE).intValue(), // vlr_location + TATPUtil.padWithZero(s_id) // sub_nbr + ); + } }), - UpdateSubscriberData(new TransactionInvoker() { - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - long s_id = TATPUtil.getSubscriberId(subscriberSize); - ((UpdateSubscriberData) proc).run( - conn, - s_id, // s_id - TATPUtil.number(0, 1).byteValue(), // bit_1 - TATPUtil.number(0, 255).shortValue(), // data_a - TATPUtil.number(1, 4).byteValue() // sf_type - ); - } + UpdateSubscriberData( + new TransactionInvoker() { + public void invoke(Connection conn, Procedure proc, long subscriberSize) + throws SQLException { + long s_id = TATPUtil.getSubscriberId(subscriberSize); + ((UpdateSubscriberData) proc) + .run( + conn, + s_id, // s_id + TATPUtil.number(0, 1).byteValue(), // bit_1 + TATPUtil.number(0, 255).shortValue(), // data_a + TATPUtil.number(1, 4).byteValue() // sf_type + ); + } }), - ; // END LIST OF STORED PROCEDURES + ; // END LIST OF STORED PROCEDURES - /** - * Constructor - */ - Transaction(TransactionInvoker ag) { - this.generator = ag; - } - - public final TransactionInvoker generator; - - protected static final Map idx_lookup = new HashMap<>(); - protected static final Map name_lookup = new HashMap<>(); - - static { - for (Transaction vt : EnumSet.allOf(Transaction.class)) { - Transaction.idx_lookup.put(vt.ordinal(), vt); - Transaction.name_lookup.put(vt.name().toUpperCase(), vt); - } - } + /** Constructor */ + Transaction(TransactionInvoker ag) { + this.generator = ag; + } - public static Transaction get(String name) { - return (Transaction.name_lookup.get(name.toUpperCase())); - } + public final TransactionInvoker generator; - public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { - this.generator.invoke(conn, proc, subscriberSize); - } + protected static final Map idx_lookup = new HashMap<>(); + protected static final Map name_lookup = new HashMap<>(); + static { + for (Transaction vt : EnumSet.allOf(Transaction.class)) { + Transaction.idx_lookup.put(vt.ordinal(), vt); + Transaction.name_lookup.put(vt.name().toUpperCase(), vt); + } } - private final long subscriberSize; - - public TATPWorker(TATPBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - this.subscriberSize = Math.round(TATPConstants.DEFAULT_NUM_SUBSCRIBERS * benchmarkModule.getWorkloadConfiguration().getScaleFactor()); + public static Transaction get(String name) { + return (Transaction.name_lookup.get(name.toUpperCase())); } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException { - Transaction t = Transaction.get(txnType.getName()); - - - // Get the Procedure handle - Procedure proc = this.getProcedure(txnType); - if (LOG.isDebugEnabled()) { - LOG.debug("Executing {}", proc); - } - - t.invoke(conn, proc, subscriberSize); - return (TransactionStatus.SUCCESS); + public void invoke(Connection conn, Procedure proc, long subscriberSize) throws SQLException { + this.generator.invoke(conn, proc, subscriberSize); + } + } + + private final long subscriberSize; + + public TATPWorker(TATPBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + this.subscriberSize = + Math.round( + TATPConstants.DEFAULT_NUM_SUBSCRIBERS + * benchmarkModule.getWorkloadConfiguration().getScaleFactor()); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException { + Transaction t = Transaction.get(txnType.getName()); + + // Get the Procedure handle + Procedure proc = this.getProcedure(txnType); + if (LOG.isDebugEnabled()) { + LOG.debug("Executing {}", proc); } + t.invoke(conn, proc, subscriberSize); + return (TransactionStatus.SUCCESS); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/DeleteCallForwarding.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/DeleteCallForwarding.java index b395857d7..a83bdbf3f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/DeleteCallForwarding.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/DeleteCallForwarding.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,39 +27,41 @@ public class DeleteCallForwarding extends Procedure { - public final SQLStmt getSubscriber = new SQLStmt( - "SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?" - ); + public final SQLStmt getSubscriber = + new SQLStmt("SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?"); - public final SQLStmt updateCallForwarding = new SQLStmt( - "DELETE FROM " + TATPConstants.TABLENAME_CALL_FORWARDING + - " WHERE s_id = ? AND sf_type = ? AND start_time = ?" - ); + public final SQLStmt updateCallForwarding = + new SQLStmt( + "DELETE FROM " + + TATPConstants.TABLENAME_CALL_FORWARDING + + " WHERE s_id = ? AND sf_type = ? AND start_time = ?"); - public long run(Connection conn, String sub_nbr, byte sf_type, byte start_time) throws SQLException { - long s_id = -1; + public long run(Connection conn, String sub_nbr, byte sf_type, byte start_time) + throws SQLException { + long s_id = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { - stmt.setString(1, sub_nbr); - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - s_id = results.getLong(1); - } - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { + stmt.setString(1, sub_nbr); + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + s_id = results.getLong(1); } + } + } - int rows_updated = -1; + int rows_updated = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateCallForwarding)) { - stmt.setLong(1, s_id); - stmt.setByte(2, sf_type); - stmt.setByte(3, start_time); - rows_updated = stmt.executeUpdate(); - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateCallForwarding)) { + stmt.setLong(1, s_id); + stmt.setByte(2, sf_type); + stmt.setByte(3, start_time); + rows_updated = stmt.executeUpdate(); + } - if (rows_updated == 0) { - throw new UserAbortException("Failed to delete a row in " + TATPConstants.TABLENAME_CALL_FORWARDING); - } - return (rows_updated); + if (rows_updated == 0) { + throw new UserAbortException( + "Failed to delete a row in " + TATPConstants.TABLENAME_CALL_FORWARDING); } -} \ No newline at end of file + return (rows_updated); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java index 886dd0668..9822a7d5c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetAccessData.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,18 +27,19 @@ public class GetAccessData extends Procedure { - public final SQLStmt getAccessInfo = new SQLStmt( - "SELECT data1, data2, data3, data4 FROM " + TATPConstants.TABLENAME_ACCESS_INFO + - " WHERE s_id = ? AND ai_type = ?" - ); + public final SQLStmt getAccessInfo = + new SQLStmt( + "SELECT data1, data2, data3, data4 FROM " + + TATPConstants.TABLENAME_ACCESS_INFO + + " WHERE s_id = ? AND ai_type = ?"); - public void run(Connection conn, long s_id, byte ai_type) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getAccessInfo)) { - stmt.setLong(1, s_id); - stmt.setByte(2, ai_type); - try (ResultSet results = stmt.executeQuery()) { - assert results != null; - } - } + public void run(Connection conn, long s_id, byte ai_type) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getAccessInfo)) { + stmt.setLong(1, s_id); + stmt.setByte(2, ai_type); + try (ResultSet results = stmt.executeQuery()) { + assert results != null; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java index ee9a833b5..0ecb4f39e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetNewDestination.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,28 +27,33 @@ public class GetNewDestination extends Procedure { - public final SQLStmt getNewDestination = new SQLStmt( - "SELECT cf.numberx " + - " FROM " + TATPConstants.TABLENAME_SPECIAL_FACILITY + " sf, " + - " " + TATPConstants.TABLENAME_CALL_FORWARDING + " cf " + - " WHERE sf.s_id = ? " + - " AND sf.sf_type = ? " + - " AND sf.is_active = 1 " + - " AND cf.s_id = sf.s_id " + - " AND cf.sf_type = sf.sf_type " + - " AND cf.start_time <= ? " + - " AND cf.end_time > ?" - ); + public final SQLStmt getNewDestination = + new SQLStmt( + "SELECT cf.numberx " + + " FROM " + + TATPConstants.TABLENAME_SPECIAL_FACILITY + + " sf, " + + " " + + TATPConstants.TABLENAME_CALL_FORWARDING + + " cf " + + " WHERE sf.s_id = ? " + + " AND sf.sf_type = ? " + + " AND sf.is_active = 1 " + + " AND cf.s_id = sf.s_id " + + " AND cf.sf_type = sf.sf_type " + + " AND cf.start_time <= ? " + + " AND cf.end_time > ?"); - public void run(Connection conn, long s_id, byte sf_type, byte start_time, byte end_time) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getNewDestination)) { - stmt.setLong(1, s_id); - stmt.setByte(2, sf_type); - stmt.setByte(3, start_time); - stmt.setByte(4, end_time); - try (ResultSet results = stmt.executeQuery()) { - assert results != null; - } - } + public void run(Connection conn, long s_id, byte sf_type, byte start_time, byte end_time) + throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getNewDestination)) { + stmt.setLong(1, s_id); + stmt.setByte(2, sf_type); + stmt.setByte(3, start_time); + stmt.setByte(4, end_time); + try (ResultSet results = stmt.executeQuery()) { + assert results != null; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java index a0c95144b..12d140683 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/GetSubscriberData.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,14 +27,15 @@ public class GetSubscriberData extends Procedure { - public final SQLStmt getSubscriber = new SQLStmt("SELECT * FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE s_id = ?"); + public final SQLStmt getSubscriber = + new SQLStmt("SELECT * FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE s_id = ?"); - public void run(Connection conn, long s_id) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { - stmt.setLong(1, s_id); - try (ResultSet results = stmt.executeQuery()) { - assert results != null; - } - } + public void run(Connection conn, long s_id) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { + stmt.setLong(1, s_id); + try (ResultSet results = stmt.executeQuery()) { + assert results != null; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java index 7239186a5..2a3976c31 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/InsertCallForwarding.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,55 +27,56 @@ public class InsertCallForwarding extends Procedure { - public final SQLStmt getSubscriber = new SQLStmt( - "SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?" - ); + public final SQLStmt getSubscriber = + new SQLStmt("SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?"); - public final SQLStmt getSpecialFacility = new SQLStmt( - "SELECT sf_type FROM " + TATPConstants.TABLENAME_SPECIAL_FACILITY + " WHERE s_id = ?" - ); + public final SQLStmt getSpecialFacility = + new SQLStmt( + "SELECT sf_type FROM " + TATPConstants.TABLENAME_SPECIAL_FACILITY + " WHERE s_id = ?"); - public final SQLStmt insertCallForwarding = new SQLStmt( - "INSERT INTO " + TATPConstants.TABLENAME_CALL_FORWARDING + " VALUES (?, ?, ?, ?, ?)" - ); + public final SQLStmt insertCallForwarding = + new SQLStmt( + "INSERT INTO " + TATPConstants.TABLENAME_CALL_FORWARDING + " VALUES (?, ?, ?, ?, ?)"); - public long run(Connection conn, String sub_nbr, byte sf_type, byte start_time, byte end_time, String numberx) throws SQLException { - long s_id = -1; - - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { - stmt.setString(1, sub_nbr); - try (ResultSet results = stmt.executeQuery()) { - if (results.next()) { - s_id = results.getLong(1); - } - } - } + public long run( + Connection conn, String sub_nbr, byte sf_type, byte start_time, byte end_time, String numberx) + throws SQLException { + long s_id = -1; - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSpecialFacility)) { - stmt.setLong(1, s_id); - try (ResultSet results = stmt.executeQuery()) { - assert results != null; - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { + stmt.setString(1, sub_nbr); + try (ResultSet results = stmt.executeQuery()) { + if (results.next()) { + s_id = results.getLong(1); } + } + } - // Inserting a new CALL_FORWARDING record only succeeds 30% of the time + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSpecialFacility)) { + stmt.setLong(1, s_id); + try (ResultSet results = stmt.executeQuery()) { + assert results != null; + } + } - int rows_updated = -1; + // Inserting a new CALL_FORWARDING record only succeeds 30% of the time - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertCallForwarding)) { - stmt.setLong(1, s_id); - stmt.setByte(2, sf_type); - stmt.setByte(3, start_time); - stmt.setByte(4, end_time); - stmt.setString(5, numberx); + int rows_updated = -1; + try (PreparedStatement stmt = this.getPreparedStatement(conn, insertCallForwarding)) { + stmt.setLong(1, s_id); + stmt.setByte(2, sf_type); + stmt.setByte(3, start_time); + stmt.setByte(4, end_time); + stmt.setString(5, numberx); - try { - rows_updated = stmt.executeUpdate(); - } catch (SQLException ex) { - throw new UserAbortException("Failed to insert a row in " + TATPConstants.TABLENAME_CALL_FORWARDING); - } - } - return (rows_updated); + try { + rows_updated = stmt.executeUpdate(); + } catch (SQLException ex) { + throw new UserAbortException( + "Failed to insert a row in " + TATPConstants.TABLENAME_CALL_FORWARDING); + } } -} \ No newline at end of file + return (rows_updated); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateLocation.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateLocation.java index f5a6be7b9..9731bbf14 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateLocation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateLocation.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,29 +27,28 @@ public class UpdateLocation extends Procedure { - public final SQLStmt getSubscriber = new SQLStmt( - "SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?" - ); - - public final SQLStmt updateSubscriber = new SQLStmt( - "UPDATE " + TATPConstants.TABLENAME_SUBSCRIBER + " SET vlr_location = ? WHERE s_id = ?" - ); - - public long run(Connection conn, int location, String sub_nbr) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { - stmt.setString(1, sub_nbr); - try (ResultSet results = stmt.executeQuery()) { - - if (results.next()) { - long s_id = results.getLong(1); - try (PreparedStatement stmt2 = this.getPreparedStatement(conn, updateSubscriber)) { - stmt2.setInt(1, location); - stmt2.setLong(2, s_id); - return stmt2.executeUpdate(); - } - } - } + public final SQLStmt getSubscriber = + new SQLStmt("SELECT s_id FROM " + TATPConstants.TABLENAME_SUBSCRIBER + " WHERE sub_nbr = ?"); + + public final SQLStmt updateSubscriber = + new SQLStmt( + "UPDATE " + TATPConstants.TABLENAME_SUBSCRIBER + " SET vlr_location = ? WHERE s_id = ?"); + + public long run(Connection conn, int location, String sub_nbr) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getSubscriber)) { + stmt.setString(1, sub_nbr); + try (ResultSet results = stmt.executeQuery()) { + + if (results.next()) { + long s_id = results.getLong(1); + try (PreparedStatement stmt2 = this.getPreparedStatement(conn, updateSubscriber)) { + stmt2.setInt(1, location); + stmt2.setLong(2, s_id); + return stmt2.executeUpdate(); + } } - return 0; + } } -} \ No newline at end of file + return 0; + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateSubscriberData.java b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateSubscriberData.java index d9564aa05..78b4d0ae8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateSubscriberData.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tatp/procedures/UpdateSubscriberData.java @@ -15,45 +15,46 @@ * */ - package com.oltpbenchmark.benchmarks.tatp.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tatp.TATPConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class UpdateSubscriberData extends Procedure { - public final SQLStmt updateSubscriber = new SQLStmt( - "UPDATE " + TATPConstants.TABLENAME_SUBSCRIBER + " SET bit_1 = ? WHERE s_id = ?" - ); - - public final SQLStmt updateSpecialFacility = new SQLStmt( - "UPDATE " + TATPConstants.TABLENAME_SPECIAL_FACILITY + " SET data_a = ? WHERE s_id = ? AND sf_type = ?" - ); - - public long run(Connection conn, long s_id, byte bit_1, short data_a, byte sf_type) throws SQLException { - int updated; - - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateSubscriber)) { - stmt.setByte(1, bit_1); - stmt.setLong(2, s_id); - updated = stmt.executeUpdate(); - } - - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateSpecialFacility)) { - stmt.setShort(1, data_a); - stmt.setLong(2, s_id); - stmt.setByte(3, sf_type); - updated = stmt.executeUpdate(); - } - if (updated != 0) { - throw new UserAbortException("Failed to update a row in " + TATPConstants.TABLENAME_SPECIAL_FACILITY); - } - return (updated); + public final SQLStmt updateSubscriber = + new SQLStmt("UPDATE " + TATPConstants.TABLENAME_SUBSCRIBER + " SET bit_1 = ? WHERE s_id = ?"); + + public final SQLStmt updateSpecialFacility = + new SQLStmt( + "UPDATE " + + TATPConstants.TABLENAME_SPECIAL_FACILITY + + " SET data_a = ? WHERE s_id = ? AND sf_type = ?"); + + public long run(Connection conn, long s_id, byte bit_1, short data_a, byte sf_type) + throws SQLException { + int updated; + + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateSubscriber)) { + stmt.setByte(1, bit_1); + stmt.setLong(2, s_id); + updated = stmt.executeUpdate(); + } + + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateSpecialFacility)) { + stmt.setShort(1, data_a); + stmt.setLong(2, s_id); + stmt.setByte(3, sf_type); + updated = stmt.executeUpdate(); + } + if (updated != 0) { + throw new UserAbortException( + "Failed to update a row in " + TATPConstants.TABLENAME_SPECIAL_FACILITY); } -} \ No newline at end of file + return (updated); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedBenchmark.java index 2f5448f7a..089c9b025 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedBenchmark.java @@ -16,25 +16,6 @@ */ package com.oltpbenchmark.benchmarks.templated; -import java.io.FileInputStream; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.xml.transform.stream.StreamSource; -import javax.xml.validation.Schema; -import javax.xml.validation.SchemaFactory; - -import org.apache.commons.text.StringEscapeUtils; -import org.codehaus.commons.compiler.CompilerFactoryFactory; -import org.codehaus.commons.compiler.ICompilerFactory; -import org.codehaus.commons.compiler.ISimpleCompiler; -import org.immutables.value.Value; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.oltpbenchmark.WorkloadConfiguration; import com.oltpbenchmark.api.BenchmarkModule; import com.oltpbenchmark.api.Loader; @@ -42,147 +23,163 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.api.Worker; -import com.oltpbenchmark.api.templates.ValuesType; import com.oltpbenchmark.api.templates.TemplateType; import com.oltpbenchmark.api.templates.TemplatesType; +import com.oltpbenchmark.api.templates.ValuesType; import com.oltpbenchmark.benchmarks.templated.procedures.GenericQuery; import com.oltpbenchmark.benchmarks.templated.procedures.GenericQuery.QueryTemplateInfo; import com.oltpbenchmark.benchmarks.templated.util.GenericQueryOperation; import com.oltpbenchmark.benchmarks.templated.util.TraceTransactionGenerator; import com.opencsv.CSVParser; import com.opencsv.CSVParserBuilder; - import jakarta.xml.bind.JAXBContext; import jakarta.xml.bind.JAXBElement; import jakarta.xml.bind.Unmarshaller; +import java.io.FileInputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import org.apache.commons.text.StringEscapeUtils; +import org.codehaus.commons.compiler.CompilerFactoryFactory; +import org.codehaus.commons.compiler.ICompilerFactory; +import org.codehaus.commons.compiler.ISimpleCompiler; +import org.immutables.value.Value; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * This class is used to execute templated benchmarks, i.e., benchmarks that - * have parameters that the user wants to set dynamically. More information - * about the structure of the expected template can be found in the local - * readme file. + * This class is used to execute templated benchmarks, i.e., benchmarks that have parameters that + * the user wants to set dynamically. More information about the structure of the expected template + * can be found in the local readme file. */ public final class TemplatedBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(TemplatedBenchmark.class); - - public TemplatedBenchmark(WorkloadConfiguration workConf) { - super(workConf); - this.setClassLoader(); + private static final Logger LOG = LoggerFactory.getLogger(TemplatedBenchmark.class); + + public TemplatedBenchmark(WorkloadConfiguration workConf) { + super(workConf); + this.setClassLoader(); + } + + @Override + protected void setClassLoader() { + super.setClassLoader(); + + if (workConf != null && workConf.getXmlConfig().containsKey("query_templates_file")) { + this.classLoader = + this.loadQueryTemplates(workConf.getXmlConfig().getString("query_templates_file")); + } else { + LOG.error("No query_templates_file specified in xml config."); } - - @Override - protected void setClassLoader() { - super.setClassLoader(); - - if (workConf != null && workConf.getXmlConfig().containsKey("query_templates_file")) { - this.classLoader = this.loadQueryTemplates( - workConf.getXmlConfig().getString("query_templates_file")); - } else { - LOG.error("No query_templates_file specified in xml config."); + } + + @Override + protected Package getProcedurePackageImpl() { + return (GenericQuery.class.getPackage()); + } + + private CustomClassLoader getCustomClassLoader() { + return (CustomClassLoader) this.classLoader; + } + + public List> getProcedureClasses() { + return this.getCustomClassLoader().getProcedureClasses(); + } + + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + + try { + final Map, TraceTransactionGenerator> generators = new HashMap<>(); + // Create potential parameter bindings for each template. Add those + // to a trace transaction generator that will determine how the + // parameters are used. + for (Entry kv : getProcedures().entrySet()) { + // Sanity check that the procedure has the right type. + if (!(kv.getValue() instanceof GenericQuery)) { + LOG.error( + String.format( + "Procedure %s does not have the correct class type (GenericQuery).", + kv.getValue().toString())); + continue; } - } - - @Override - protected Package getProcedurePackageImpl() { - return (GenericQuery.class.getPackage()); - } - - private CustomClassLoader getCustomClassLoader() { - return (CustomClassLoader) this.classLoader; - } - - public List> getProcedureClasses() { - return this.getCustomClassLoader().getProcedureClasses(); - } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - - try { - final Map, TraceTransactionGenerator> generators = new HashMap<>(); - // Create potential parameter bindings for each template. Add those - // to a trace transaction generator that will determine how the - // parameters are used. - for (Entry kv : getProcedures().entrySet()) { - // Sanity check that the procedure has the right type. - if (!(kv.getValue() instanceof GenericQuery)) { - LOG.error( - String.format( - "Procedure %s does not have the correct class type (GenericQuery).", - kv.getValue().toString())); - continue; - } - GenericQuery proc = (GenericQuery) kv.getValue(); - QueryTemplateInfo info = proc.getQueryTemplateInfo(); - - // Parse parameter values and add each combination to a generator. - // FIXME: This method does not currently support NULLable - // parameters since they will be parsed as an empty string. - // See Also: comments in GenericQuery.getStatement() - // Additionally, it's somewhat unnecessarily expensive, since - // we convert from XML represented values back to CSV separated - // list of params. - List list = new ArrayList<>(); - String[] paramsTypes = info.getParamsTypes(); - CSVParser parser = new CSVParserBuilder() - .withQuoteChar('\'') - .build(); - for (String binding : info.getParamsValues()) { - Object[] params = parser.parseLine(binding); - assert paramsTypes.length == params.length; - list.add(new GenericQueryOperation(params)); - } - generators.put(proc.getClass(), new TraceTransactionGenerator(list)); - } - - // Create workers. - int numTerminals = workConf.getTerminals(); - LOG.info(String.format("Creating %d workers for templated benchmark", numTerminals)); - for (int i = 0; i < numTerminals; i++) { - workers.add(new TemplatedWorker(this, i, generators)); - } - } catch (Exception e) { - throw new IllegalStateException("Unable to create workers", e); + GenericQuery proc = (GenericQuery) kv.getValue(); + QueryTemplateInfo info = proc.getQueryTemplateInfo(); + + // Parse parameter values and add each combination to a generator. + // FIXME: This method does not currently support NULLable + // parameters since they will be parsed as an empty string. + // See Also: comments in GenericQuery.getStatement() + // Additionally, it's somewhat unnecessarily expensive, since + // we convert from XML represented values back to CSV separated + // list of params. + List list = new ArrayList<>(); + String[] paramsTypes = info.getParamsTypes(); + CSVParser parser = new CSVParserBuilder().withQuoteChar('\'').build(); + for (String binding : info.getParamsValues()) { + Object[] params = parser.parseLine(binding); + assert paramsTypes.length == params.length; + list.add(new GenericQueryOperation(params)); } - return workers; - } - - @Override - protected Loader makeLoaderImpl() { - throw new UnsupportedOperationException("Templated benchmarks do not currently support loading directly."); + generators.put(proc.getClass(), new TraceTransactionGenerator(list)); + } + + // Create workers. + int numTerminals = workConf.getTerminals(); + LOG.info(String.format("Creating %d workers for templated benchmark", numTerminals)); + for (int i = 0; i < numTerminals; i++) { + workers.add(new TemplatedWorker(this, i, generators)); + } + } catch (Exception e) { + throw new IllegalStateException("Unable to create workers", e); } + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + throw new UnsupportedOperationException( + "Templated benchmarks do not currently support loading directly."); + } + + private CustomClassLoader loadQueryTemplates(String file) { + // Instantiate Java compiler. + CustomClassLoader ccloader = new CustomClassLoader(this.classLoader); + try { + // Parse template file. + final ICompilerFactory compilerFactory = + CompilerFactoryFactory.getDefaultCompilerFactory( + TemplatedBenchmark.class.getClassLoader()); + + JAXBContext jc = JAXBContext.newInstance("com.oltpbenchmark.api.templates"); + SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = + sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/templates.xsd"))); + Unmarshaller unmarshaller = jc.createUnmarshaller(); + unmarshaller.setSchema(schema); + + StreamSource streamSource = new StreamSource(new FileInputStream(file)); + JAXBElement result = unmarshaller.unmarshal(streamSource, TemplatesType.class); + TemplatesType templates = result.getValue(); + + for (TemplateType template : templates.getTemplateList()) { + ImmutableParsedQueryTemplate.Builder b = ImmutableParsedQueryTemplate.builder(); + b.name(template.getName()); + b.query(template.getQuery()); + b.paramsTypes(template.getTypes().getTypeList()); + for (ValuesType paramValue : template.getValues()) { + b.addParamsValues(String.join(",", paramValue.getValueList())); + } - private CustomClassLoader loadQueryTemplates(String file) { - // Instantiate Java compiler. - CustomClassLoader ccloader = new CustomClassLoader(this.classLoader); - try { - // Parse template file. - final ICompilerFactory compilerFactory = CompilerFactoryFactory.getDefaultCompilerFactory( - TemplatedBenchmark.class.getClassLoader()); - - JAXBContext jc = JAXBContext.newInstance("com.oltpbenchmark.api.templates"); - SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); - Schema schema = sf.newSchema(new StreamSource(this.getClass().getResourceAsStream("/templates.xsd"))); - Unmarshaller unmarshaller = jc.createUnmarshaller(); - unmarshaller.setSchema(schema); - - StreamSource streamSource = new StreamSource(new FileInputStream(file)); - JAXBElement result = unmarshaller.unmarshal(streamSource, TemplatesType.class); - TemplatesType templates = result.getValue(); - - for (TemplateType template : templates.getTemplateList()) { - ImmutableParsedQueryTemplate.Builder b = ImmutableParsedQueryTemplate.builder(); - b.name(template.getName()); - b.query(template.getQuery()); - b.paramsTypes(template.getTypes().getTypeList()); - for (ValuesType paramValue : template.getValues()) { - b.addParamsValues(String.join(",", paramValue.getValueList())); - } - - ParsedQueryTemplate qt = b.build(); - // Create and compile class. - final String s = """ + ParsedQueryTemplate qt = b.build(); + // Create and compile class. + final String s = + """ package %s ; public final class %s extends %s { @Override @@ -194,88 +191,88 @@ public final class %s extends %s { .build(); } } - """.formatted( - GenericQuery.class.getPackageName(), - qt.getName(), - GenericQuery.class.getCanonicalName(), - QueryTemplateInfo.class.getCanonicalName(), - SQLStmt.class.getCanonicalName(), - StringEscapeUtils.escapeJava(qt.getQuery()), - getParamsString(qt.getParamsTypes()), - getParamsString(qt.getParamsValues())); - LOG.debug("Class definition for query template {}:\n {}", qt.getName(), s); - final String qualifiedClassName = GenericQuery.class.getPackageName() + "." + qt.getName(); - final ISimpleCompiler compiler = compilerFactory.newSimpleCompiler(); - compiler.setTargetVersion(17); - compiler.setParentClassLoader(this.classLoader); - compiler.cook(s); - ccloader.putClass(qualifiedClassName, - compiler.getClassLoader().loadClass(qualifiedClassName)); - } - } catch (Exception e) { - throw new IllegalStateException("Unable to load query templates", e); - } - return ccloader; + """ + .formatted( + GenericQuery.class.getPackageName(), + qt.getName(), + GenericQuery.class.getCanonicalName(), + QueryTemplateInfo.class.getCanonicalName(), + SQLStmt.class.getCanonicalName(), + StringEscapeUtils.escapeJava(qt.getQuery()), + getParamsString(qt.getParamsTypes()), + getParamsString(qt.getParamsValues())); + LOG.debug("Class definition for query template {}:\n {}", qt.getName(), s); + final String qualifiedClassName = GenericQuery.class.getPackageName() + "." + qt.getName(); + final ISimpleCompiler compiler = compilerFactory.newSimpleCompiler(); + compiler.setTargetVersion(17); + compiler.setParentClassLoader(this.classLoader); + compiler.cook(s); + ccloader.putClass( + qualifiedClassName, compiler.getClassLoader().loadClass(qualifiedClassName)); + } + } catch (Exception e) { + throw new IllegalStateException("Unable to load query templates", e); } + return ccloader; + } - private String getParamsString(List params) { - String result = ""; - for (String param : params) { - result += "\"" + StringEscapeUtils.escapeJava(param) + "\","; - } - return result.isEmpty() ? "" : result.substring(0, result.length() - 1); + private String getParamsString(List params) { + String result = ""; + for (String param : params) { + result += "\"" + StringEscapeUtils.escapeJava(param) + "\","; } + return result.isEmpty() ? "" : result.substring(0, result.length() - 1); + } - private static class CustomClassLoader extends ClassLoader { + private static class CustomClassLoader extends ClassLoader { - private final Map> classes = new HashMap<>(); + private final Map> classes = new HashMap<>(); - private CustomClassLoader(ClassLoader parent) { - super(parent); - } + private CustomClassLoader(ClassLoader parent) { + super(parent); + } - @Override - public Class findClass(String name) throws ClassNotFoundException { - Class clazz = classes.get(name); - return clazz != null ? clazz : super.findClass(name); - } + @Override + public Class findClass(String name) throws ClassNotFoundException { + Class clazz = classes.get(name); + return clazz != null ? clazz : super.findClass(name); + } - public void putClass(String name, Class clazz) { - classes.put(name, clazz); - } + public void putClass(String name, Class clazz) { + classes.put(name, clazz); + } - @SuppressWarnings("unchecked") - public List> getProcedureClasses() { - List> result = new ArrayList<>(); - for (Class clz : classes.values()) { - if (Procedure.class.isAssignableFrom(clz)) { - result.add((Class) clz); - } - } - return result; + @SuppressWarnings("unchecked") + public List> getProcedureClasses() { + List> result = new ArrayList<>(); + for (Class clz : classes.values()) { + if (Procedure.class.isAssignableFrom(clz)) { + result.add((Class) clz); } + } + return result; } + } - @Value.Immutable - public interface ParsedQueryTemplate { + @Value.Immutable + public interface ParsedQueryTemplate { - /** Template name. */ - String getName(); + /** Template name. */ + String getName(); - /** Query string for this template. */ - String getQuery(); + /** Query string for this template. */ + String getQuery(); - /** Potential query parameter types. */ - @Value.Default - default List getParamsTypes() { - return List.of(); - } - - /** Potential query parameter values. */ - @Value.Default - default List getParamsValues() { - return List.of(); - } + /** Potential query parameter types. */ + @Value.Default + default List getParamsTypes() { + return List.of(); } + /** Potential query parameter values. */ + @Value.Default + default List getParamsValues() { + return List.of(); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedWorker.java index 4f2a5f0e4..a1af7456a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/templated/TemplatedWorker.java @@ -16,51 +16,50 @@ */ package com.oltpbenchmark.benchmarks.templated; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Map; - import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.Procedure.UserAbortException; -import com.oltpbenchmark.benchmarks.templated.procedures.GenericQuery; -import com.oltpbenchmark.benchmarks.templated.util.TraceTransactionGenerator; import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.api.Worker; +import com.oltpbenchmark.benchmarks.templated.procedures.GenericQuery; +import com.oltpbenchmark.benchmarks.templated.util.TraceTransactionGenerator; import com.oltpbenchmark.types.TransactionStatus; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Map; public final class TemplatedWorker extends Worker { - protected final Map, TraceTransactionGenerator> generators; - - public TemplatedWorker(TemplatedBenchmark benchmarkModule, int id, - Map, TraceTransactionGenerator> generators) { - super(benchmarkModule, id); - this.rng().setSeed(benchmarkModule.getWorkloadConfiguration().getRandomSeed()); - this.generators = generators; - } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) - throws UserAbortException, SQLException { - try { - Class clazz = nextTransaction.getProcedureClass(); - GenericQuery proc = (GenericQuery) this.getProcedure(clazz); - if (!generators.get(clazz).isEmpty()) { - // If there is a generator available use it to create a - // parameter binding. - TraceTransactionGenerator generator = generators.get(clazz); - proc.run(conn, generator.nextTransaction().getParams()); - } else { - // If the generator has no transactions, there are no parameters. - proc.run(conn); - } + protected final Map, TraceTransactionGenerator> generators; - } catch (ClassCastException e) { - throw new RuntimeException(e); - } + public TemplatedWorker( + TemplatedBenchmark benchmarkModule, + int id, + Map, TraceTransactionGenerator> generators) { + super(benchmarkModule, id); + this.rng().setSeed(benchmarkModule.getWorkloadConfiguration().getRandomSeed()); + this.generators = generators; + } - return (TransactionStatus.SUCCESS); + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) + throws UserAbortException, SQLException { + try { + Class clazz = nextTransaction.getProcedureClass(); + GenericQuery proc = (GenericQuery) this.getProcedure(clazz); + if (!generators.get(clazz).isEmpty()) { + // If there is a generator available use it to create a + // parameter binding. + TraceTransactionGenerator generator = generators.get(clazz); + proc.run(conn, generator.nextTransaction().getParams()); + } else { + // If the generator has no transactions, there are no parameters. + proc.run(conn); + } + } catch (ClassCastException e) { + throw new RuntimeException(e); } -} + return (TransactionStatus.SUCCESS); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/templated/procedures/GenericQuery.java b/src/main/java/com/oltpbenchmark/benchmarks/templated/procedures/GenericQuery.java index c9c3b7a23..dbcc89f11 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/templated/procedures/GenericQuery.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/templated/procedures/GenericQuery.java @@ -16,102 +16,106 @@ */ package com.oltpbenchmark.benchmarks.templated.procedures; +import com.oltpbenchmark.api.Procedure; +import com.oltpbenchmark.api.SQLStmt; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.List; - import org.immutables.value.Value; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.oltpbenchmark.api.Procedure; -import com.oltpbenchmark.api.SQLStmt; - public abstract class GenericQuery extends Procedure { - protected static final Logger LOG = LoggerFactory.getLogger(GenericQuery.class); - - /** Execution method with parameters. */ - public void run(Connection conn, List params) throws SQLException { - - try (PreparedStatement stmt = getStatement(conn, params)) { - boolean hasResultSet = stmt.execute(); - if (hasResultSet) { - do { - try (ResultSet rs = stmt.getResultSet()) { - while (rs.next()) { - // do nothing - } - } catch (Exception resultException){ - resultException.printStackTrace(); - throw new RuntimeException("Could not retrieve ResultSet"); - } - } while(stmt.getMoreResults()); - } else { - // Case for UPDATE, INSERT, DELETE queries - // do nothing - } - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException("Error when trying to execute statement"); - } - - conn.commit(); - } + protected static final Logger LOG = LoggerFactory.getLogger(GenericQuery.class); - /** Execution method without parameters. */ - public void run(Connection conn) throws SQLException { - QueryTemplateInfo queryTemplateInfo = this.getQueryTemplateInfo(); + /** Execution method with parameters. */ + public void run(Connection conn, List params) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, queryTemplateInfo.getQuery()); ResultSet rs = stmt.executeQuery()) { + try (PreparedStatement stmt = getStatement(conn, params)) { + boolean hasResultSet = stmt.execute(); + if (hasResultSet) { + do { + try (ResultSet rs = stmt.getResultSet()) { while (rs.next()) { - //do nothing + // do nothing } - } - conn.commit(); + } catch (Exception resultException) { + resultException.printStackTrace(); + throw new RuntimeException("Could not retrieve ResultSet"); + } + } while (stmt.getMoreResults()); + } else { + // Case for UPDATE, INSERT, DELETE queries + // do nothing + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Error when trying to execute statement"); } - public PreparedStatement getStatement(Connection conn, List params) throws SQLException { - QueryTemplateInfo queryTemplateInfo = this.getQueryTemplateInfo(); + conn.commit(); + } - PreparedStatement stmt = this.getPreparedStatement(conn, queryTemplateInfo.getQuery()); - String[] paramsTypes = queryTemplateInfo.getParamsTypes(); - for (int i = 0; i < paramsTypes.length; i++) { - if (paramsTypes[i].equalsIgnoreCase("NULL")) { - stmt.setNull(i + 1, Types.NULL); - } else { - try { - // TODO: add support for nullable other types - // For instance, can we provide a tag in the XML file to represent a NULL value? - // Or does it need a special marker like "$null" to signify a NULL value? - Object param = params.get(i); - stmt.setObject(i + 1, param, Integer.parseInt(Types.class.getDeclaredField(paramsTypes[i]).get(null).toString())); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException( - "Error when setting parameters. Parameter type: " + paramsTypes[i] + ", parameter value: " + params.get(i)); - } - } + /** Execution method without parameters. */ + public void run(Connection conn) throws SQLException { + QueryTemplateInfo queryTemplateInfo = this.getQueryTemplateInfo(); + + try (PreparedStatement stmt = this.getPreparedStatement(conn, queryTemplateInfo.getQuery()); + ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + // do nothing + } + } + conn.commit(); + } + + public PreparedStatement getStatement(Connection conn, List params) throws SQLException { + QueryTemplateInfo queryTemplateInfo = this.getQueryTemplateInfo(); + + PreparedStatement stmt = this.getPreparedStatement(conn, queryTemplateInfo.getQuery()); + String[] paramsTypes = queryTemplateInfo.getParamsTypes(); + for (int i = 0; i < paramsTypes.length; i++) { + if (paramsTypes[i].equalsIgnoreCase("NULL")) { + stmt.setNull(i + 1, Types.NULL); + } else { + try { + // TODO: add support for nullable other types + // For instance, can we provide a tag in the XML file to represent a NULL value? + // Or does it need a special marker like "$null" to signify a NULL value? + Object param = params.get(i); + stmt.setObject( + i + 1, + param, + Integer.parseInt(Types.class.getDeclaredField(paramsTypes[i]).get(null).toString())); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException( + "Error when setting parameters. Parameter type: " + + paramsTypes[i] + + ", parameter value: " + + params.get(i)); } - return stmt; + } } + return stmt; + } - public abstract QueryTemplateInfo getQueryTemplateInfo(); + public abstract QueryTemplateInfo getQueryTemplateInfo(); - @Value.Immutable - public interface QueryTemplateInfo { + @Value.Immutable + public interface QueryTemplateInfo { - /** Query string for this template. */ - SQLStmt getQuery(); + /** Query string for this template. */ + SQLStmt getQuery(); - /** Query parameter types. */ - String[] getParamsTypes(); - - /** Potential query parameter values. */ - String[] getParamsValues(); - } + /** Query parameter types. */ + String[] getParamsTypes(); + /** Potential query parameter values. */ + String[] getParamsValues(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/templated/util/GenericQueryOperation.java b/src/main/java/com/oltpbenchmark/benchmarks/templated/util/GenericQueryOperation.java index b2a3cdc73..2a1820fa0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/templated/util/GenericQueryOperation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/templated/util/GenericQueryOperation.java @@ -16,26 +16,22 @@ */ package com.oltpbenchmark.benchmarks.templated.util; +import com.oltpbenchmark.api.Operation; import java.util.Arrays; import java.util.Collections; import java.util.List; -import com.oltpbenchmark.api.Operation; - -/** - * Immutable class containing information about transactions. - */ +/** Immutable class containing information about transactions. */ public class GenericQueryOperation extends Operation { - public final List params; - + public final List params; - public GenericQueryOperation(Object[] params) { - super(); - this.params = Collections.unmodifiableList(Arrays.asList(params)); - } + public GenericQueryOperation(Object[] params) { + super(); + this.params = Collections.unmodifiableList(Arrays.asList(params)); + } - public List getParams() { - return params; - } + public List getParams() { + return params; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/templated/util/TraceTransactionGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/templated/util/TraceTransactionGenerator.java index 782df565d..7c9ae4048 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/templated/util/TraceTransactionGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/templated/util/TraceTransactionGenerator.java @@ -16,32 +16,30 @@ */ package com.oltpbenchmark.benchmarks.templated.util; -import java.util.Collections; -import java.util.List; - import com.oltpbenchmark.api.TransactionGenerator; import com.oltpbenchmark.distributions.CyclicCounterGenerator; +import java.util.Collections; +import java.util.List; public class TraceTransactionGenerator implements TransactionGenerator { - private final List transactions; - private final CyclicCounterGenerator nextInTrace; - - /** - * @param transactions a list of transactions shared between threads. - */ - public TraceTransactionGenerator(List transactions) { - this.transactions = Collections.unmodifiableList(transactions); - this.nextInTrace = new CyclicCounterGenerator(transactions.size()); - } - - @Override - public GenericQueryOperation nextTransaction() { - return transactions.get(nextInTrace.nextInt()); - } - - public boolean isEmpty() { - return transactions.size() == 0; - } - + private final List transactions; + private final CyclicCounterGenerator nextInTrace; + + /** + * @param transactions a list of transactions shared between threads. + */ + public TraceTransactionGenerator(List transactions) { + this.transactions = Collections.unmodifiableList(transactions); + this.nextInTrace = new CyclicCounterGenerator(transactions.size()); + } + + @Override + public GenericQueryOperation nextTransaction() { + return transactions.get(nextInTrace.nextInt()); + } + + public boolean isEmpty() { + return transactions.size() == 0; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCBenchmark.java index fdf8d7af5..4d79e405f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc; import com.oltpbenchmark.WorkloadConfiguration; @@ -23,96 +22,96 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tpcc.procedures.NewOrder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class TPCCBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(TPCCBenchmark.class); - - public TPCCBenchmark(WorkloadConfiguration workConf) { - super(workConf); + private static final Logger LOG = LoggerFactory.getLogger(TPCCBenchmark.class); + + public TPCCBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } + + @Override + protected Package getProcedurePackageImpl() { + return (NewOrder.class.getPackage()); + } + + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + + try { + List terminals = createTerminals(); + workers.addAll(terminals); + } catch (Exception e) { + LOG.error(e.getMessage(), e); } - @Override - protected Package getProcedurePackageImpl() { - return (NewOrder.class.getPackage()); - } + return workers; + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); + @Override + protected Loader makeLoaderImpl() { + return new TPCCLoader(this); + } - try { - List terminals = createTerminals(); - workers.addAll(terminals); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - } + protected List createTerminals() throws SQLException { - return workers; - } + TPCCWorker[] terminals = new TPCCWorker[workConf.getTerminals()]; - @Override - protected Loader makeLoaderImpl() { - return new TPCCLoader(this); + int numWarehouses = (int) workConf.getScaleFactor(); + if (numWarehouses <= 0) { + numWarehouses = 1; } - protected List createTerminals() throws SQLException { - - TPCCWorker[] terminals = new TPCCWorker[workConf.getTerminals()]; - - int numWarehouses = (int) workConf.getScaleFactor(); - if (numWarehouses <= 0) { - numWarehouses = 1; - } - - int numTerminals = workConf.getTerminals(); - - // We distribute terminals evenly across the warehouses - // Eg. if there are 10 terminals across 7 warehouses, they - // are distributed as - // 1, 1, 2, 1, 2, 1, 2 - final double terminalsPerWarehouse = (double) numTerminals / numWarehouses; - int workerId = 0; - - for (int w = 0; w < numWarehouses; w++) { - // Compute the number of terminals in *this* warehouse - int lowerTerminalId = (int) (w * terminalsPerWarehouse); - int upperTerminalId = (int) ((w + 1) * terminalsPerWarehouse); - // protect against double rounding errors - int w_id = w + 1; - if (w_id == numWarehouses) { - upperTerminalId = numTerminals; - } - int numWarehouseTerminals = upperTerminalId - lowerTerminalId; - - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("w_id %d = %d terminals [lower=%d / upper%d]", w_id, numWarehouseTerminals, lowerTerminalId, upperTerminalId)); - } - - final double districtsPerTerminal = TPCCConfig.configDistPerWhse / (double) numWarehouseTerminals; - for (int terminalId = 0; terminalId < numWarehouseTerminals; terminalId++) { - int lowerDistrictId = (int) (terminalId * districtsPerTerminal); - int upperDistrictId = (int) ((terminalId + 1) * districtsPerTerminal); - if (terminalId + 1 == numWarehouseTerminals) { - upperDistrictId = TPCCConfig.configDistPerWhse; - } - lowerDistrictId += 1; - - TPCCWorker terminal = new TPCCWorker(this, workerId++, w_id, lowerDistrictId, upperDistrictId, numWarehouses); - terminals[lowerTerminalId + terminalId] = terminal; - } - + int numTerminals = workConf.getTerminals(); + + // We distribute terminals evenly across the warehouses + // Eg. if there are 10 terminals across 7 warehouses, they + // are distributed as + // 1, 1, 2, 1, 2, 1, 2 + final double terminalsPerWarehouse = (double) numTerminals / numWarehouses; + int workerId = 0; + + for (int w = 0; w < numWarehouses; w++) { + // Compute the number of terminals in *this* warehouse + int lowerTerminalId = (int) (w * terminalsPerWarehouse); + int upperTerminalId = (int) ((w + 1) * terminalsPerWarehouse); + // protect against double rounding errors + int w_id = w + 1; + if (w_id == numWarehouses) { + upperTerminalId = numTerminals; + } + int numWarehouseTerminals = upperTerminalId - lowerTerminalId; + + if (LOG.isDebugEnabled()) { + LOG.debug( + String.format( + "w_id %d = %d terminals [lower=%d / upper%d]", + w_id, numWarehouseTerminals, lowerTerminalId, upperTerminalId)); + } + + final double districtsPerTerminal = + TPCCConfig.configDistPerWhse / (double) numWarehouseTerminals; + for (int terminalId = 0; terminalId < numWarehouseTerminals; terminalId++) { + int lowerDistrictId = (int) (terminalId * districtsPerTerminal); + int upperDistrictId = (int) ((terminalId + 1) * districtsPerTerminal); + if (terminalId + 1 == numWarehouseTerminals) { + upperDistrictId = TPCCConfig.configDistPerWhse; } + lowerDistrictId += 1; - - return Arrays.asList(terminals); + TPCCWorker terminal = + new TPCCWorker(this, workerId++, w_id, lowerDistrictId, upperDistrictId, numWarehouses); + terminals[lowerTerminalId + terminalId] = terminal; + } } - + return Arrays.asList(terminals); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConfig.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConfig.java index 36c785d27..7842d4036 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConfig.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConfig.java @@ -15,27 +15,25 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc; import java.text.SimpleDateFormat; public final class TPCCConfig { - public final static String[] nameTokens = {"BAR", "OUGHT", "ABLE", "PRI", - "PRES", "ESE", "ANTI", "CALLY", "ATION", "EING"}; + public static final String[] nameTokens = { + "BAR", "OUGHT", "ABLE", "PRI", "PRES", "ESE", "ANTI", "CALLY", "ATION", "EING" + }; - public final static String terminalPrefix = "Term-"; + public static final String terminalPrefix = "Term-"; - public final static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - public final static int configWhseCount = 1; - public final static int configItemCount = 100000; // tpc-c std = 100,000 - public final static int configDistPerWhse = 10; // tpc-c std = 10 - public final static int configCustPerDist = 3000; // tpc-c std = 3,000 + public static final int configWhseCount = 1; + public static final int configItemCount = 100000; // tpc-c std = 100,000 + public static final int configDistPerWhse = 10; // tpc-c std = 10 + public static final int configCustPerDist = 3000; // tpc-c std = 3,000 - /** - * An invalid item id used to rollback a new order transaction. - */ - public static final int INVALID_ITEM_ID = -12345; + /** An invalid item id used to rollback a new order transaction. */ + public static final int INVALID_ITEM_ID = -12345; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConstants.java index 46003aff4..20e3aef92 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCConstants.java @@ -18,13 +18,13 @@ package com.oltpbenchmark.benchmarks.tpcc; public abstract class TPCCConstants { - public static final String TABLENAME_DISTRICT = "district"; - public static final String TABLENAME_WAREHOUSE = "warehouse"; - public static final String TABLENAME_ITEM = "item"; - public static final String TABLENAME_STOCK = "stock"; - public static final String TABLENAME_CUSTOMER = "customer"; - public static final String TABLENAME_HISTORY = "history"; - public static final String TABLENAME_OPENORDER = "oorder"; - public static final String TABLENAME_ORDERLINE = "order_line"; - public static final String TABLENAME_NEWORDER = "new_order"; + public static final String TABLENAME_DISTRICT = "district"; + public static final String TABLENAME_WAREHOUSE = "warehouse"; + public static final String TABLENAME_ITEM = "item"; + public static final String TABLENAME_STOCK = "stock"; + public static final String TABLENAME_CUSTOMER = "customer"; + public static final String TABLENAME_HISTORY = "history"; + public static final String TABLENAME_OPENORDER = "oorder"; + public static final String TABLENAME_ORDERLINE = "order_line"; + public static final String TABLENAME_NEWORDER = "new_order"; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCLoader.java index f0c448533..5a299d507 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCLoader.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc; import com.oltpbenchmark.api.Loader; @@ -23,670 +22,671 @@ import com.oltpbenchmark.benchmarks.tpcc.pojo.*; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CountDownLatch; -/** - * TPC-C Benchmark Loader - */ +/** TPC-C Benchmark Loader */ public final class TPCCLoader extends Loader { - private static final int FIRST_UNPROCESSED_O_ID = 2101; - - private final long numWarehouses; - - public TPCCLoader(TPCCBenchmark benchmark) { - super(benchmark); - numWarehouses = Math.max(Math.round(TPCCConfig.configWhseCount * this.scaleFactor), 1); - } - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final CountDownLatch itemLatch = new CountDownLatch(1); + private static final int FIRST_UNPROCESSED_O_ID = 2101; + + private final long numWarehouses; + + public TPCCLoader(TPCCBenchmark benchmark) { + super(benchmark); + numWarehouses = Math.max(Math.round(TPCCConfig.configWhseCount * this.scaleFactor), 1); + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final CountDownLatch itemLatch = new CountDownLatch(1); + + // ITEM + // This will be invoked first and executed in a single thread. + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) { + loadItems(conn, TPCCConfig.configItemCount); + } + + @Override + public void afterLoad() { + itemLatch.countDown(); + } + }); - // ITEM - // This will be invoked first and executed in a single thread. - threads.add(new LoaderThread(this.benchmark) { + // WAREHOUSES + // We use a separate thread per warehouse. Each thread will load + // all of the tables that depend on that warehouse. They all have + // to wait until the ITEM table is loaded first though. + for (int w = 1; w <= numWarehouses; w++) { + final int w_id = w; + LoaderThread t = + new LoaderThread(this.benchmark) { @Override public void load(Connection conn) { - loadItems(conn, TPCCConfig.configItemCount); - } - @Override - public void afterLoad() { - itemLatch.countDown(); + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load WAREHOUSE {}", w_id); + } + // WAREHOUSE + loadWarehouse(conn, w_id); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load STOCK {}", w_id); + } + // STOCK + loadStock(conn, w_id, TPCCConfig.configItemCount); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load DISTRICT {}", w_id); + } + // DISTRICT + loadDistricts(conn, w_id, TPCCConfig.configDistPerWhse); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load CUSTOMER {}", w_id); + } + // CUSTOMER + loadCustomers(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load CUSTOMER HISTORY {}", w_id); + } + // CUSTOMER HISTORY + loadCustomerHistory( + conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load ORDERS {}", w_id); + } + // ORDERS + loadOpenOrders( + conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load NEW ORDERS {}", w_id); + } + // NEW ORDERS + loadNewOrders(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); + + if (LOG.isDebugEnabled()) { + LOG.debug("Starting to load ORDER LINES {}", w_id); + } + // ORDER LINES + loadOrderLines( + conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); } - }); - - // WAREHOUSES - // We use a separate thread per warehouse. Each thread will load - // all of the tables that depend on that warehouse. They all have - // to wait until the ITEM table is loaded first though. - for (int w = 1; w <= numWarehouses; w++) { - final int w_id = w; - LoaderThread t = new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) { - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load WAREHOUSE {}", w_id); - } - // WAREHOUSE - loadWarehouse(conn, w_id); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load STOCK {}", w_id); - } - // STOCK - loadStock(conn, w_id, TPCCConfig.configItemCount); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load DISTRICT {}", w_id); - } - // DISTRICT - loadDistricts(conn, w_id, TPCCConfig.configDistPerWhse); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load CUSTOMER {}", w_id); - } - // CUSTOMER - loadCustomers(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load CUSTOMER HISTORY {}", w_id); - } - // CUSTOMER HISTORY - loadCustomerHistory(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load ORDERS {}", w_id); - } - // ORDERS - loadOpenOrders(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load NEW ORDERS {}", w_id); - } - // NEW ORDERS - loadNewOrders(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); - - if (LOG.isDebugEnabled()) { - LOG.debug("Starting to load ORDER LINES {}", w_id); - } - // ORDER LINES - loadOrderLines(conn, w_id, TPCCConfig.configDistPerWhse, TPCCConfig.configCustPerDist); - - } - - @Override - public void beforeLoad() { - - // Make sure that we load the ITEM table first - - try { - itemLatch.await(); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - } - }; - threads.add(t); - } - return (threads); - } - private PreparedStatement getInsertStatement(Connection conn, String tableName) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - return conn.prepareStatement(sql); - } - - - protected void loadItems(Connection conn, int itemCount) { - - try (PreparedStatement itemPrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_ITEM)) { - - int batchSize = 0; - for (int i = 1; i <= itemCount; i++) { - - Item item = new Item(); - item.i_id = i; - item.i_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(14, 24, benchmark.rng())); - item.i_price = TPCCUtil.randomNumber(100, 10000, benchmark.rng()) / 100.0; - - // i_data - int randPct = TPCCUtil.randomNumber(1, 100, benchmark.rng()); - int len = TPCCUtil.randomNumber(26, 50, benchmark.rng()); - if (randPct > 10) { - // 90% of time i_data isa random string of length [26 .. 50] - item.i_data = TPCCUtil.randomStr(len); - } else { - // 10% of time i_data has "ORIGINAL" crammed somewhere in - // middle - int startORIGINAL = TPCCUtil.randomNumber(2, (len - 8), benchmark.rng()); - item.i_data = TPCCUtil.randomStr(startORIGINAL - 1) + "ORIGINAL" + TPCCUtil.randomStr(len - startORIGINAL - 9); - } - - item.i_im_id = TPCCUtil.randomNumber(1, 10000, benchmark.rng()); - - int idx = 1; - itemPrepStmt.setLong(idx++, item.i_id); - itemPrepStmt.setString(idx++, item.i_name); - itemPrepStmt.setDouble(idx++, item.i_price); - itemPrepStmt.setString(idx++, item.i_data); - itemPrepStmt.setLong(idx, item.i_im_id); - itemPrepStmt.addBatch(); - batchSize++; - - if (batchSize == workConf.getBatchSize()) { - itemPrepStmt.executeBatch(); - itemPrepStmt.clearBatch(); - batchSize = 0; - } - } + @Override + public void beforeLoad() { + // Make sure that we load the ITEM table first - if (batchSize > 0) { - itemPrepStmt.executeBatch(); - itemPrepStmt.clearBatch(); + try { + itemLatch.await(); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } } - - } catch (SQLException se) { - LOG.error(se.getMessage()); - } - + }; + threads.add(t); } - - - protected void loadWarehouse(Connection conn, int w_id) { - - try (PreparedStatement whsePrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_WAREHOUSE)) { - Warehouse warehouse = new Warehouse(); - - warehouse.w_id = w_id; - warehouse.w_ytd = 300000; - - // random within [0.0000 .. 0.2000] - warehouse.w_tax = (TPCCUtil.randomNumber(0, 2000, benchmark.rng())) / 10000.0; - warehouse.w_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(6, 10, benchmark.rng())); - warehouse.w_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - warehouse.w_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - warehouse.w_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - warehouse.w_state = TPCCUtil.randomStr(3).toUpperCase(); - warehouse.w_zip = "123456789"; - - int idx = 1; - whsePrepStmt.setLong(idx++, warehouse.w_id); - whsePrepStmt.setDouble(idx++, warehouse.w_ytd); - whsePrepStmt.setDouble(idx++, warehouse.w_tax); - whsePrepStmt.setString(idx++, warehouse.w_name); - whsePrepStmt.setString(idx++, warehouse.w_street_1); - whsePrepStmt.setString(idx++, warehouse.w_street_2); - whsePrepStmt.setString(idx++, warehouse.w_city); - whsePrepStmt.setString(idx++, warehouse.w_state); - whsePrepStmt.setString(idx, warehouse.w_zip); - whsePrepStmt.execute(); - - } catch (SQLException se) { - LOG.error(se.getMessage()); + return (threads); + } + + private PreparedStatement getInsertStatement(Connection conn, String tableName) + throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(tableName); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + return conn.prepareStatement(sql); + } + + protected void loadItems(Connection conn, int itemCount) { + + try (PreparedStatement itemPrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_ITEM)) { + + int batchSize = 0; + for (int i = 1; i <= itemCount; i++) { + + Item item = new Item(); + item.i_id = i; + item.i_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(14, 24, benchmark.rng())); + item.i_price = TPCCUtil.randomNumber(100, 10000, benchmark.rng()) / 100.0; + + // i_data + int randPct = TPCCUtil.randomNumber(1, 100, benchmark.rng()); + int len = TPCCUtil.randomNumber(26, 50, benchmark.rng()); + if (randPct > 10) { + // 90% of time i_data isa random string of length [26 .. 50] + item.i_data = TPCCUtil.randomStr(len); + } else { + // 10% of time i_data has "ORIGINAL" crammed somewhere in + // middle + int startORIGINAL = TPCCUtil.randomNumber(2, (len - 8), benchmark.rng()); + item.i_data = + TPCCUtil.randomStr(startORIGINAL - 1) + + "ORIGINAL" + + TPCCUtil.randomStr(len - startORIGINAL - 9); } - } - - protected void loadStock(Connection conn, int w_id, int numItems) { - - int k = 0; - - try (PreparedStatement stockPreparedStatement = getInsertStatement(conn, TPCCConstants.TABLENAME_STOCK)) { - - for (int i = 1; i <= numItems; i++) { - Stock stock = new Stock(); - stock.s_i_id = i; - stock.s_w_id = w_id; - stock.s_quantity = TPCCUtil.randomNumber(10, 100, benchmark.rng()); - stock.s_ytd = 0; - stock.s_order_cnt = 0; - stock.s_remote_cnt = 0; - - // s_data - int randPct = TPCCUtil.randomNumber(1, 100, benchmark.rng()); - int len = TPCCUtil.randomNumber(26, 50, benchmark.rng()); - if (randPct > 10) { - // 90% of time i_data isa random string of length [26 .. - // 50] - stock.s_data = TPCCUtil.randomStr(len); - } else { - // 10% of time i_data has "ORIGINAL" crammed somewhere - // in middle - int startORIGINAL = TPCCUtil.randomNumber(2, (len - 8), benchmark.rng()); - stock.s_data = TPCCUtil.randomStr(startORIGINAL - 1) + "ORIGINAL" + TPCCUtil.randomStr(len - startORIGINAL - 9); - } - - int idx = 1; - stockPreparedStatement.setLong(idx++, stock.s_w_id); - stockPreparedStatement.setLong(idx++, stock.s_i_id); - stockPreparedStatement.setLong(idx++, stock.s_quantity); - stockPreparedStatement.setDouble(idx++, stock.s_ytd); - stockPreparedStatement.setLong(idx++, stock.s_order_cnt); - stockPreparedStatement.setLong(idx++, stock.s_remote_cnt); - stockPreparedStatement.setString(idx++, stock.s_data); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); - stockPreparedStatement.setString(idx, TPCCUtil.randomStr(24)); - stockPreparedStatement.addBatch(); - - k++; - - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - stockPreparedStatement.executeBatch(); - stockPreparedStatement.clearBatch(); - } - } - - stockPreparedStatement.executeBatch(); - stockPreparedStatement.clearBatch(); - - } catch (SQLException se) { - LOG.error(se.getMessage()); + item.i_im_id = TPCCUtil.randomNumber(1, 10000, benchmark.rng()); + + int idx = 1; + itemPrepStmt.setLong(idx++, item.i_id); + itemPrepStmt.setString(idx++, item.i_name); + itemPrepStmt.setDouble(idx++, item.i_price); + itemPrepStmt.setString(idx++, item.i_data); + itemPrepStmt.setLong(idx, item.i_im_id); + itemPrepStmt.addBatch(); + batchSize++; + + if (batchSize == workConf.getBatchSize()) { + itemPrepStmt.executeBatch(); + itemPrepStmt.clearBatch(); + batchSize = 0; } + } - } - - protected void loadDistricts(Connection conn, int w_id, int districtsPerWarehouse) { - - try (PreparedStatement distPrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_DISTRICT)) { - - for (int d = 1; d <= districtsPerWarehouse; d++) { - District district = new District(); - district.d_id = d; - district.d_w_id = w_id; - district.d_ytd = 30000; - - // random within [0.0000 .. 0.2000] - district.d_tax = (float) ((TPCCUtil.randomNumber(0, 2000, benchmark.rng())) / 10000.0); - - district.d_next_o_id = TPCCConfig.configCustPerDist + 1; - district.d_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(6, 10, benchmark.rng())); - district.d_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - district.d_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - district.d_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - district.d_state = TPCCUtil.randomStr(3).toUpperCase(); - district.d_zip = "123456789"; - - int idx = 1; - distPrepStmt.setLong(idx++, district.d_w_id); - distPrepStmt.setLong(idx++, district.d_id); - distPrepStmt.setDouble(idx++, district.d_ytd); - distPrepStmt.setDouble(idx++, district.d_tax); - distPrepStmt.setLong(idx++, district.d_next_o_id); - distPrepStmt.setString(idx++, district.d_name); - distPrepStmt.setString(idx++, district.d_street_1); - distPrepStmt.setString(idx++, district.d_street_2); - distPrepStmt.setString(idx++, district.d_city); - distPrepStmt.setString(idx++, district.d_state); - distPrepStmt.setString(idx, district.d_zip); - distPrepStmt.executeUpdate(); - } + if (batchSize > 0) { + itemPrepStmt.executeBatch(); + itemPrepStmt.clearBatch(); + } - } catch (SQLException se) { - LOG.error(se.getMessage()); + } catch (SQLException se) { + LOG.error(se.getMessage()); + } + } + + protected void loadWarehouse(Connection conn, int w_id) { + + try (PreparedStatement whsePrepStmt = + getInsertStatement(conn, TPCCConstants.TABLENAME_WAREHOUSE)) { + Warehouse warehouse = new Warehouse(); + + warehouse.w_id = w_id; + warehouse.w_ytd = 300000; + + // random within [0.0000 .. 0.2000] + warehouse.w_tax = (TPCCUtil.randomNumber(0, 2000, benchmark.rng())) / 10000.0; + warehouse.w_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(6, 10, benchmark.rng())); + warehouse.w_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + warehouse.w_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + warehouse.w_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + warehouse.w_state = TPCCUtil.randomStr(3).toUpperCase(); + warehouse.w_zip = "123456789"; + + int idx = 1; + whsePrepStmt.setLong(idx++, warehouse.w_id); + whsePrepStmt.setDouble(idx++, warehouse.w_ytd); + whsePrepStmt.setDouble(idx++, warehouse.w_tax); + whsePrepStmt.setString(idx++, warehouse.w_name); + whsePrepStmt.setString(idx++, warehouse.w_street_1); + whsePrepStmt.setString(idx++, warehouse.w_street_2); + whsePrepStmt.setString(idx++, warehouse.w_city); + whsePrepStmt.setString(idx++, warehouse.w_state); + whsePrepStmt.setString(idx, warehouse.w_zip); + whsePrepStmt.execute(); + + } catch (SQLException se) { + LOG.error(se.getMessage()); + } + } + + protected void loadStock(Connection conn, int w_id, int numItems) { + + int k = 0; + + try (PreparedStatement stockPreparedStatement = + getInsertStatement(conn, TPCCConstants.TABLENAME_STOCK)) { + + for (int i = 1; i <= numItems; i++) { + Stock stock = new Stock(); + stock.s_i_id = i; + stock.s_w_id = w_id; + stock.s_quantity = TPCCUtil.randomNumber(10, 100, benchmark.rng()); + stock.s_ytd = 0; + stock.s_order_cnt = 0; + stock.s_remote_cnt = 0; + + // s_data + int randPct = TPCCUtil.randomNumber(1, 100, benchmark.rng()); + int len = TPCCUtil.randomNumber(26, 50, benchmark.rng()); + if (randPct > 10) { + // 90% of time i_data isa random string of length [26 .. + // 50] + stock.s_data = TPCCUtil.randomStr(len); + } else { + // 10% of time i_data has "ORIGINAL" crammed somewhere + // in middle + int startORIGINAL = TPCCUtil.randomNumber(2, (len - 8), benchmark.rng()); + stock.s_data = + TPCCUtil.randomStr(startORIGINAL - 1) + + "ORIGINAL" + + TPCCUtil.randomStr(len - startORIGINAL - 9); } - } + int idx = 1; + stockPreparedStatement.setLong(idx++, stock.s_w_id); + stockPreparedStatement.setLong(idx++, stock.s_i_id); + stockPreparedStatement.setLong(idx++, stock.s_quantity); + stockPreparedStatement.setDouble(idx++, stock.s_ytd); + stockPreparedStatement.setLong(idx++, stock.s_order_cnt); + stockPreparedStatement.setLong(idx++, stock.s_remote_cnt); + stockPreparedStatement.setString(idx++, stock.s_data); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx++, TPCCUtil.randomStr(24)); + stockPreparedStatement.setString(idx, TPCCUtil.randomStr(24)); + stockPreparedStatement.addBatch(); + + k++; + + if (k != 0 && (k % workConf.getBatchSize()) == 0) { + stockPreparedStatement.executeBatch(); + stockPreparedStatement.clearBatch(); + } + } - protected void loadCustomers(Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - - int k = 0; - - try (PreparedStatement custPrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_CUSTOMER)) { - - for (int d = 1; d <= districtsPerWarehouse; d++) { - for (int c = 1; c <= customersPerDistrict; c++) { - Timestamp sysdate = new Timestamp(System.currentTimeMillis()); - - Customer customer = new Customer(); - customer.c_id = c; - customer.c_d_id = d; - customer.c_w_id = w_id; - - // discount is random between [0.0000 ... 0.5000] - customer.c_discount = (float) (TPCCUtil.randomNumber(1, 5000, benchmark.rng()) / 10000.0); - - if (TPCCUtil.randomNumber(1, 100, benchmark.rng()) <= 10) { - customer.c_credit = "BC"; // 10% Bad Credit - } else { - customer.c_credit = "GC"; // 90% Good Credit - } - if (c <= 1000) { - customer.c_last = TPCCUtil.getLastName(c - 1); - } else { - customer.c_last = TPCCUtil.getNonUniformRandomLastNameForLoad(benchmark.rng()); - } - customer.c_first = TPCCUtil.randomStr(TPCCUtil.randomNumber(8, 16, benchmark.rng())); - customer.c_credit_lim = 50000; - - customer.c_balance = -10; - customer.c_ytd_payment = 10; - customer.c_payment_cnt = 1; - customer.c_delivery_cnt = 0; - - customer.c_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - customer.c_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - customer.c_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); - customer.c_state = TPCCUtil.randomStr(3).toUpperCase(); - // TPC-C 4.3.2.7: 4 random digits + "11111" - customer.c_zip = TPCCUtil.randomNStr(4) + "11111"; - customer.c_phone = TPCCUtil.randomNStr(16); - customer.c_since = sysdate; - customer.c_middle = "OE"; - customer.c_data = TPCCUtil.randomStr(TPCCUtil.randomNumber(300, 500, benchmark.rng())); - - int idx = 1; - custPrepStmt.setLong(idx++, customer.c_w_id); - custPrepStmt.setLong(idx++, customer.c_d_id); - custPrepStmt.setLong(idx++, customer.c_id); - custPrepStmt.setDouble(idx++, customer.c_discount); - custPrepStmt.setString(idx++, customer.c_credit); - custPrepStmt.setString(idx++, customer.c_last); - custPrepStmt.setString(idx++, customer.c_first); - custPrepStmt.setDouble(idx++, customer.c_credit_lim); - custPrepStmt.setDouble(idx++, customer.c_balance); - custPrepStmt.setDouble(idx++, customer.c_ytd_payment); - custPrepStmt.setLong(idx++, customer.c_payment_cnt); - custPrepStmt.setLong(idx++, customer.c_delivery_cnt); - custPrepStmt.setString(idx++, customer.c_street_1); - custPrepStmt.setString(idx++, customer.c_street_2); - custPrepStmt.setString(idx++, customer.c_city); - custPrepStmt.setString(idx++, customer.c_state); - custPrepStmt.setString(idx++, customer.c_zip); - custPrepStmt.setString(idx++, customer.c_phone); - custPrepStmt.setTimestamp(idx++, customer.c_since); - custPrepStmt.setString(idx++, customer.c_middle); - custPrepStmt.setString(idx, customer.c_data); - custPrepStmt.addBatch(); - - k++; - - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - custPrepStmt.executeBatch(); - custPrepStmt.clearBatch(); - } - } - } + stockPreparedStatement.executeBatch(); + stockPreparedStatement.clearBatch(); + } catch (SQLException se) { + LOG.error(se.getMessage()); + } + } + + protected void loadDistricts(Connection conn, int w_id, int districtsPerWarehouse) { + + try (PreparedStatement distPrepStmt = + getInsertStatement(conn, TPCCConstants.TABLENAME_DISTRICT)) { + + for (int d = 1; d <= districtsPerWarehouse; d++) { + District district = new District(); + district.d_id = d; + district.d_w_id = w_id; + district.d_ytd = 30000; + + // random within [0.0000 .. 0.2000] + district.d_tax = (float) ((TPCCUtil.randomNumber(0, 2000, benchmark.rng())) / 10000.0); + + district.d_next_o_id = TPCCConfig.configCustPerDist + 1; + district.d_name = TPCCUtil.randomStr(TPCCUtil.randomNumber(6, 10, benchmark.rng())); + district.d_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + district.d_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + district.d_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + district.d_state = TPCCUtil.randomStr(3).toUpperCase(); + district.d_zip = "123456789"; + + int idx = 1; + distPrepStmt.setLong(idx++, district.d_w_id); + distPrepStmt.setLong(idx++, district.d_id); + distPrepStmt.setDouble(idx++, district.d_ytd); + distPrepStmt.setDouble(idx++, district.d_tax); + distPrepStmt.setLong(idx++, district.d_next_o_id); + distPrepStmt.setString(idx++, district.d_name); + distPrepStmt.setString(idx++, district.d_street_1); + distPrepStmt.setString(idx++, district.d_street_2); + distPrepStmt.setString(idx++, district.d_city); + distPrepStmt.setString(idx++, district.d_state); + distPrepStmt.setString(idx, district.d_zip); + distPrepStmt.executeUpdate(); + } + + } catch (SQLException se) { + LOG.error(se.getMessage()); + } + } + + protected void loadCustomers( + Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { + + int k = 0; + + try (PreparedStatement custPrepStmt = + getInsertStatement(conn, TPCCConstants.TABLENAME_CUSTOMER)) { + + for (int d = 1; d <= districtsPerWarehouse; d++) { + for (int c = 1; c <= customersPerDistrict; c++) { + Timestamp sysdate = new Timestamp(System.currentTimeMillis()); + + Customer customer = new Customer(); + customer.c_id = c; + customer.c_d_id = d; + customer.c_w_id = w_id; + + // discount is random between [0.0000 ... 0.5000] + customer.c_discount = (float) (TPCCUtil.randomNumber(1, 5000, benchmark.rng()) / 10000.0); + + if (TPCCUtil.randomNumber(1, 100, benchmark.rng()) <= 10) { + customer.c_credit = "BC"; // 10% Bad Credit + } else { + customer.c_credit = "GC"; // 90% Good Credit + } + if (c <= 1000) { + customer.c_last = TPCCUtil.getLastName(c - 1); + } else { + customer.c_last = TPCCUtil.getNonUniformRandomLastNameForLoad(benchmark.rng()); + } + customer.c_first = TPCCUtil.randomStr(TPCCUtil.randomNumber(8, 16, benchmark.rng())); + customer.c_credit_lim = 50000; + + customer.c_balance = -10; + customer.c_ytd_payment = 10; + customer.c_payment_cnt = 1; + customer.c_delivery_cnt = 0; + + customer.c_street_1 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + customer.c_street_2 = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + customer.c_city = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 20, benchmark.rng())); + customer.c_state = TPCCUtil.randomStr(3).toUpperCase(); + // TPC-C 4.3.2.7: 4 random digits + "11111" + customer.c_zip = TPCCUtil.randomNStr(4) + "11111"; + customer.c_phone = TPCCUtil.randomNStr(16); + customer.c_since = sysdate; + customer.c_middle = "OE"; + customer.c_data = TPCCUtil.randomStr(TPCCUtil.randomNumber(300, 500, benchmark.rng())); + + int idx = 1; + custPrepStmt.setLong(idx++, customer.c_w_id); + custPrepStmt.setLong(idx++, customer.c_d_id); + custPrepStmt.setLong(idx++, customer.c_id); + custPrepStmt.setDouble(idx++, customer.c_discount); + custPrepStmt.setString(idx++, customer.c_credit); + custPrepStmt.setString(idx++, customer.c_last); + custPrepStmt.setString(idx++, customer.c_first); + custPrepStmt.setDouble(idx++, customer.c_credit_lim); + custPrepStmt.setDouble(idx++, customer.c_balance); + custPrepStmt.setDouble(idx++, customer.c_ytd_payment); + custPrepStmt.setLong(idx++, customer.c_payment_cnt); + custPrepStmt.setLong(idx++, customer.c_delivery_cnt); + custPrepStmt.setString(idx++, customer.c_street_1); + custPrepStmt.setString(idx++, customer.c_street_2); + custPrepStmt.setString(idx++, customer.c_city); + custPrepStmt.setString(idx++, customer.c_state); + custPrepStmt.setString(idx++, customer.c_zip); + custPrepStmt.setString(idx++, customer.c_phone); + custPrepStmt.setTimestamp(idx++, customer.c_since); + custPrepStmt.setString(idx++, customer.c_middle); + custPrepStmt.setString(idx, customer.c_data); + custPrepStmt.addBatch(); + + k++; + + if (k != 0 && (k % workConf.getBatchSize()) == 0) { custPrepStmt.executeBatch(); custPrepStmt.clearBatch(); - - } catch (SQLException se) { - LOG.error(se.getMessage()); + } } + } - } - - protected void loadCustomerHistory(Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - - int k = 0; - - try (PreparedStatement histPrepStmt = getInsertStatement(conn, TPCCConstants.TABLENAME_HISTORY)) { - - for (int d = 1; d <= districtsPerWarehouse; d++) { - for (int c = 1; c <= customersPerDistrict; c++) { - Timestamp sysdate = new Timestamp(System.currentTimeMillis()); - - History history = new History(); - history.h_c_id = c; - history.h_c_d_id = d; - history.h_c_w_id = w_id; - history.h_d_id = d; - history.h_w_id = w_id; - history.h_date = sysdate; - history.h_amount = 10; - history.h_data = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 24, benchmark.rng())); - - - int idx = 1; - histPrepStmt.setInt(idx++, history.h_c_id); - histPrepStmt.setInt(idx++, history.h_c_d_id); - histPrepStmt.setInt(idx++, history.h_c_w_id); - histPrepStmt.setInt(idx++, history.h_d_id); - histPrepStmt.setInt(idx++, history.h_w_id); - histPrepStmt.setTimestamp(idx++, history.h_date); - histPrepStmt.setDouble(idx++, history.h_amount); - histPrepStmt.setString(idx, history.h_data); - histPrepStmt.addBatch(); - - k++; - - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - histPrepStmt.executeBatch(); - histPrepStmt.clearBatch(); - } - } - } + custPrepStmt.executeBatch(); + custPrepStmt.clearBatch(); + } catch (SQLException se) { + LOG.error(se.getMessage()); + } + } + + protected void loadCustomerHistory( + Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { + + int k = 0; + + try (PreparedStatement histPrepStmt = + getInsertStatement(conn, TPCCConstants.TABLENAME_HISTORY)) { + + for (int d = 1; d <= districtsPerWarehouse; d++) { + for (int c = 1; c <= customersPerDistrict; c++) { + Timestamp sysdate = new Timestamp(System.currentTimeMillis()); + + History history = new History(); + history.h_c_id = c; + history.h_c_d_id = d; + history.h_c_w_id = w_id; + history.h_d_id = d; + history.h_w_id = w_id; + history.h_date = sysdate; + history.h_amount = 10; + history.h_data = TPCCUtil.randomStr(TPCCUtil.randomNumber(10, 24, benchmark.rng())); + + int idx = 1; + histPrepStmt.setInt(idx++, history.h_c_id); + histPrepStmt.setInt(idx++, history.h_c_d_id); + histPrepStmt.setInt(idx++, history.h_c_w_id); + histPrepStmt.setInt(idx++, history.h_d_id); + histPrepStmt.setInt(idx++, history.h_w_id); + histPrepStmt.setTimestamp(idx++, history.h_date); + histPrepStmt.setDouble(idx++, history.h_amount); + histPrepStmt.setString(idx, history.h_data); + histPrepStmt.addBatch(); + + k++; + + if (k != 0 && (k % workConf.getBatchSize()) == 0) { histPrepStmt.executeBatch(); histPrepStmt.clearBatch(); - - } catch (SQLException se) { - LOG.error(se.getMessage()); + } } + } + + histPrepStmt.executeBatch(); + histPrepStmt.clearBatch(); + } catch (SQLException se) { + LOG.error(se.getMessage()); } + } - protected void loadOpenOrders(Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - - int k = 0; - - try (PreparedStatement openOrderStatement = getInsertStatement(conn, TPCCConstants.TABLENAME_OPENORDER)) { - - for (int d = 1; d <= districtsPerWarehouse; d++) { - // TPC-C 4.3.3.1: o_c_id must be a permutation of [1, 3000] - int[] c_ids = new int[customersPerDistrict]; - for (int i = 0; i < customersPerDistrict; ++i) { - c_ids[i] = i + 1; - } - // Collections.shuffle exists, but there is no - // Arrays.shuffle - for (int i = 0; i < c_ids.length - 1; ++i) { - int remaining = c_ids.length - i - 1; - int swapIndex = benchmark.rng().nextInt(remaining) + i + 1; - - int temp = c_ids[swapIndex]; - c_ids[swapIndex] = c_ids[i]; - c_ids[i] = temp; - } - - for (int c = 1; c <= customersPerDistrict; c++) { - - Oorder oorder = new Oorder(); - oorder.o_id = c; - oorder.o_w_id = w_id; - oorder.o_d_id = d; - oorder.o_c_id = c_ids[c - 1]; - // o_carrier_id is set *only* for orders with ids < 2101 - // [4.3.3.1] - if (oorder.o_id < FIRST_UNPROCESSED_O_ID) { - oorder.o_carrier_id = TPCCUtil.randomNumber(1, 10, benchmark.rng()); - } else { - oorder.o_carrier_id = null; - } - oorder.o_ol_cnt = getRandomCount(w_id, c, d); - oorder.o_all_local = 1; - oorder.o_entry_d = new Timestamp(System.currentTimeMillis()); - - - int idx = 1; - openOrderStatement.setInt(idx++, oorder.o_w_id); - openOrderStatement.setInt(idx++, oorder.o_d_id); - openOrderStatement.setInt(idx++, oorder.o_id); - openOrderStatement.setInt(idx++, oorder.o_c_id); - if (oorder.o_carrier_id != null) { - openOrderStatement.setInt(idx++, oorder.o_carrier_id); - } else { - openOrderStatement.setNull(idx++, Types.INTEGER); - } - openOrderStatement.setInt(idx++, oorder.o_ol_cnt); - openOrderStatement.setInt(idx++, oorder.o_all_local); - openOrderStatement.setTimestamp(idx, oorder.o_entry_d); - openOrderStatement.addBatch(); - - k++; - - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - openOrderStatement.executeBatch(); - openOrderStatement.clearBatch(); - } - - } + protected void loadOpenOrders( + Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - } + int k = 0; - openOrderStatement.executeBatch(); - openOrderStatement.clearBatch(); + try (PreparedStatement openOrderStatement = + getInsertStatement(conn, TPCCConstants.TABLENAME_OPENORDER)) { - } catch (SQLException se) { - LOG.error(se.getMessage(), se); + for (int d = 1; d <= districtsPerWarehouse; d++) { + // TPC-C 4.3.3.1: o_c_id must be a permutation of [1, 3000] + int[] c_ids = new int[customersPerDistrict]; + for (int i = 0; i < customersPerDistrict; ++i) { + c_ids[i] = i + 1; + } + // Collections.shuffle exists, but there is no + // Arrays.shuffle + for (int i = 0; i < c_ids.length - 1; ++i) { + int remaining = c_ids.length - i - 1; + int swapIndex = benchmark.rng().nextInt(remaining) + i + 1; + + int temp = c_ids[swapIndex]; + c_ids[swapIndex] = c_ids[i]; + c_ids[i] = temp; } - } - - private int getRandomCount(int w_id, int c, int d) { - Customer customer = new Customer(); - customer.c_id = c; - customer.c_d_id = d; - customer.c_w_id = w_id; + for (int c = 1; c <= customersPerDistrict; c++) { + + Oorder oorder = new Oorder(); + oorder.o_id = c; + oorder.o_w_id = w_id; + oorder.o_d_id = d; + oorder.o_c_id = c_ids[c - 1]; + // o_carrier_id is set *only* for orders with ids < 2101 + // [4.3.3.1] + if (oorder.o_id < FIRST_UNPROCESSED_O_ID) { + oorder.o_carrier_id = TPCCUtil.randomNumber(1, 10, benchmark.rng()); + } else { + oorder.o_carrier_id = null; + } + oorder.o_ol_cnt = getRandomCount(w_id, c, d); + oorder.o_all_local = 1; + oorder.o_entry_d = new Timestamp(System.currentTimeMillis()); + + int idx = 1; + openOrderStatement.setInt(idx++, oorder.o_w_id); + openOrderStatement.setInt(idx++, oorder.o_d_id); + openOrderStatement.setInt(idx++, oorder.o_id); + openOrderStatement.setInt(idx++, oorder.o_c_id); + if (oorder.o_carrier_id != null) { + openOrderStatement.setInt(idx++, oorder.o_carrier_id); + } else { + openOrderStatement.setNull(idx++, Types.INTEGER); + } + openOrderStatement.setInt(idx++, oorder.o_ol_cnt); + openOrderStatement.setInt(idx++, oorder.o_all_local); + openOrderStatement.setTimestamp(idx, oorder.o_entry_d); + openOrderStatement.addBatch(); + + k++; + + if (k != 0 && (k % workConf.getBatchSize()) == 0) { + openOrderStatement.executeBatch(); + openOrderStatement.clearBatch(); + } + } + } - Random random = new Random(customer.hashCode()); + openOrderStatement.executeBatch(); + openOrderStatement.clearBatch(); - return TPCCUtil.randomNumber(5, 15, random); + } catch (SQLException se) { + LOG.error(se.getMessage(), se); } + } - protected void loadNewOrders(Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { + private int getRandomCount(int w_id, int c, int d) { + Customer customer = new Customer(); + customer.c_id = c; + customer.c_d_id = d; + customer.c_w_id = w_id; - int k = 0; + Random random = new Random(customer.hashCode()); - try (PreparedStatement newOrderStatement = getInsertStatement(conn, TPCCConstants.TABLENAME_NEWORDER)) { + return TPCCUtil.randomNumber(5, 15, random); + } - for (int d = 1; d <= districtsPerWarehouse; d++) { + protected void loadNewOrders( + Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - for (int c = 1; c <= customersPerDistrict; c++) { + int k = 0; - // 900 rows in the NEW-ORDER table corresponding to the last - // 900 rows in the ORDER table for that district (i.e., - // with NO_O_ID between 2,101 and 3,000) - if (c >= FIRST_UNPROCESSED_O_ID) { - NewOrder new_order = new NewOrder(); - new_order.no_w_id = w_id; - new_order.no_d_id = d; - new_order.no_o_id = c; + try (PreparedStatement newOrderStatement = + getInsertStatement(conn, TPCCConstants.TABLENAME_NEWORDER)) { - int idx = 1; - newOrderStatement.setInt(idx++, new_order.no_w_id); - newOrderStatement.setInt(idx++, new_order.no_d_id); - newOrderStatement.setInt(idx, new_order.no_o_id); - newOrderStatement.addBatch(); + for (int d = 1; d <= districtsPerWarehouse; d++) { - k++; - } + for (int c = 1; c <= customersPerDistrict; c++) { - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - newOrderStatement.executeBatch(); - newOrderStatement.clearBatch(); - } + // 900 rows in the NEW-ORDER table corresponding to the last + // 900 rows in the ORDER table for that district (i.e., + // with NO_O_ID between 2,101 and 3,000) + if (c >= FIRST_UNPROCESSED_O_ID) { + NewOrder new_order = new NewOrder(); + new_order.no_w_id = w_id; + new_order.no_d_id = d; + new_order.no_o_id = c; - } + int idx = 1; + newOrderStatement.setInt(idx++, new_order.no_w_id); + newOrderStatement.setInt(idx++, new_order.no_d_id); + newOrderStatement.setInt(idx, new_order.no_o_id); + newOrderStatement.addBatch(); - } + k++; + } + if (k != 0 && (k % workConf.getBatchSize()) == 0) { newOrderStatement.executeBatch(); newOrderStatement.clearBatch(); - - } catch (SQLException se) { - LOG.error(se.getMessage(), se); + } } + } - } + newOrderStatement.executeBatch(); + newOrderStatement.clearBatch(); - protected void loadOrderLines(Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { - - int k = 0; - - try (PreparedStatement orderLineStatement = getInsertStatement(conn, TPCCConstants.TABLENAME_ORDERLINE)) { - - for (int d = 1; d <= districtsPerWarehouse; d++) { - - for (int c = 1; c <= customersPerDistrict; c++) { - - int count = getRandomCount(w_id, c, d); - - for (int l = 1; l <= count; l++) { - OrderLine order_line = new OrderLine(); - order_line.ol_w_id = w_id; - order_line.ol_d_id = d; - order_line.ol_o_id = c; - order_line.ol_number = l; // ol_number - order_line.ol_i_id = TPCCUtil.randomNumber(1, TPCCConfig.configItemCount, benchmark.rng()); - if (order_line.ol_o_id < FIRST_UNPROCESSED_O_ID) { - order_line.ol_delivery_d = new Timestamp(System.currentTimeMillis()); - order_line.ol_amount = 0; - } else { - order_line.ol_delivery_d = null; - // random within [0.01 .. 9,999.99] - order_line.ol_amount = (float) (TPCCUtil.randomNumber(1, 999999, benchmark.rng()) / 100.0); - } - order_line.ol_supply_w_id = order_line.ol_w_id; - order_line.ol_quantity = 5; - order_line.ol_dist_info = TPCCUtil.randomStr(24); - - int idx = 1; - orderLineStatement.setInt(idx++, order_line.ol_w_id); - orderLineStatement.setInt(idx++, order_line.ol_d_id); - orderLineStatement.setInt(idx++, order_line.ol_o_id); - orderLineStatement.setInt(idx++, order_line.ol_number); - orderLineStatement.setLong(idx++, order_line.ol_i_id); - if (order_line.ol_delivery_d != null) { - orderLineStatement.setTimestamp(idx++, order_line.ol_delivery_d); - } else { - orderLineStatement.setNull(idx++, 0); - } - orderLineStatement.setDouble(idx++, order_line.ol_amount); - orderLineStatement.setLong(idx++, order_line.ol_supply_w_id); - orderLineStatement.setDouble(idx++, order_line.ol_quantity); - orderLineStatement.setString(idx, order_line.ol_dist_info); - orderLineStatement.addBatch(); - - k++; - - if (k != 0 && (k % workConf.getBatchSize()) == 0) { - orderLineStatement.executeBatch(); - orderLineStatement.clearBatch(); - } - - } - - } + } catch (SQLException se) { + LOG.error(se.getMessage(), se); + } + } + + protected void loadOrderLines( + Connection conn, int w_id, int districtsPerWarehouse, int customersPerDistrict) { + + int k = 0; + + try (PreparedStatement orderLineStatement = + getInsertStatement(conn, TPCCConstants.TABLENAME_ORDERLINE)) { + + for (int d = 1; d <= districtsPerWarehouse; d++) { + + for (int c = 1; c <= customersPerDistrict; c++) { + + int count = getRandomCount(w_id, c, d); + + for (int l = 1; l <= count; l++) { + OrderLine order_line = new OrderLine(); + order_line.ol_w_id = w_id; + order_line.ol_d_id = d; + order_line.ol_o_id = c; + order_line.ol_number = l; // ol_number + order_line.ol_i_id = + TPCCUtil.randomNumber(1, TPCCConfig.configItemCount, benchmark.rng()); + if (order_line.ol_o_id < FIRST_UNPROCESSED_O_ID) { + order_line.ol_delivery_d = new Timestamp(System.currentTimeMillis()); + order_line.ol_amount = 0; + } else { + order_line.ol_delivery_d = null; + // random within [0.01 .. 9,999.99] + order_line.ol_amount = + (float) (TPCCUtil.randomNumber(1, 999999, benchmark.rng()) / 100.0); + } + order_line.ol_supply_w_id = order_line.ol_w_id; + order_line.ol_quantity = 5; + order_line.ol_dist_info = TPCCUtil.randomStr(24); + int idx = 1; + orderLineStatement.setInt(idx++, order_line.ol_w_id); + orderLineStatement.setInt(idx++, order_line.ol_d_id); + orderLineStatement.setInt(idx++, order_line.ol_o_id); + orderLineStatement.setInt(idx++, order_line.ol_number); + orderLineStatement.setLong(idx++, order_line.ol_i_id); + if (order_line.ol_delivery_d != null) { + orderLineStatement.setTimestamp(idx++, order_line.ol_delivery_d); + } else { + orderLineStatement.setNull(idx++, 0); } + orderLineStatement.setDouble(idx++, order_line.ol_amount); + orderLineStatement.setLong(idx++, order_line.ol_supply_w_id); + orderLineStatement.setDouble(idx++, order_line.ol_quantity); + orderLineStatement.setString(idx, order_line.ol_dist_info); + orderLineStatement.addBatch(); - orderLineStatement.executeBatch(); - orderLineStatement.clearBatch(); + k++; - } catch (SQLException se) { - LOG.error(se.getMessage(), se); + if (k != 0 && (k % workConf.getBatchSize()) == 0) { + orderLineStatement.executeBatch(); + orderLineStatement.clearBatch(); + } + } } + } - } + orderLineStatement.executeBatch(); + orderLineStatement.clearBatch(); + } catch (SQLException se) { + LOG.error(se.getMessage(), se); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCUtil.java index 70e594cb4..066f68c68 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCUtil.java @@ -15,119 +15,112 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc; +import static com.oltpbenchmark.benchmarks.tpcc.TPCCConfig.*; + import com.oltpbenchmark.benchmarks.tpcc.pojo.Customer; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.ResultSet; import java.sql.SQLException; import java.util.Random; -import static com.oltpbenchmark.benchmarks.tpcc.TPCCConfig.*; - public class TPCCUtil { - /** - * Creates a Customer object from the current row in the given ResultSet. - * The caller is responsible for closing the ResultSet. - * - * @param rs an open ResultSet positioned to the desired row - * @return the newly created Customer object - * @throws SQLException for problems getting data from row - */ - public static Customer newCustomerFromResults(ResultSet rs) - throws SQLException { - Customer c = new Customer(); - // TODO: Use column indices: probably faster? - c.c_first = rs.getString("c_first"); - c.c_middle = rs.getString("c_middle"); - c.c_street_1 = rs.getString("c_street_1"); - c.c_street_2 = rs.getString("c_street_2"); - c.c_city = rs.getString("c_city"); - c.c_state = rs.getString("c_state"); - c.c_zip = rs.getString("c_zip"); - c.c_phone = rs.getString("c_phone"); - c.c_credit = rs.getString("c_credit"); - c.c_credit_lim = rs.getFloat("c_credit_lim"); - c.c_discount = rs.getFloat("c_discount"); - c.c_balance = rs.getFloat("c_balance"); - c.c_ytd_payment = rs.getFloat("c_ytd_payment"); - c.c_payment_cnt = rs.getInt("c_payment_cnt"); - c.c_since = rs.getTimestamp("c_since"); - return c; - } - - private static final RandomGenerator ran = new RandomGenerator(0); - - public static String randomStr(int strLen) { - if (strLen > 1) { - return ran.astring(strLen - 1, strLen - 1); - } else { - return ""; - } - } - - public static String randomNStr(int stringLength) { - if (stringLength > 0) { - return ran.nstring(stringLength, stringLength); - } else { - return ""; - } - } - - public static String getCurrentTime() { - return dateFormat.format(new java.util.Date()); - } - - public static String formattedDouble(double d) { - String dS = "" + d; - return dS.length() > 6 ? dS.substring(0, 6) : dS; - } - - // TODO: TPCC-C 2.1.6: For non-uniform random number generation, the - // constants for item id, - // customer id and customer name are supposed to be selected ONCE and reused - - // We just hardcode one selection of parameters here, but we should generate - // these each time. - private static final int OL_I_ID_C = 7911; // in range [0, 8191] - private static final int C_ID_C = 259; // in range [0, 1023] - // NOTE: TPC-C 2.1.6.1 specifies that abs(C_LAST_LOAD_C - C_LAST_RUN_C) must - // be within [65, 119] - private static final int C_LAST_LOAD_C = 157; // in range [0, 255] - private static final int C_LAST_RUN_C = 223; // in range [0, 255] - - public static int getItemID(Random r) { - return nonUniformRandom(8191, OL_I_ID_C, 1, configItemCount, r); - } - - public static int getCustomerID(Random r) { - return nonUniformRandom(1023, C_ID_C, 1, configCustPerDist, r); - } - - public static String getLastName(int num) { - return nameTokens[num / 100] + nameTokens[(num / 10) % 10] - + nameTokens[num % 10]; + /** + * Creates a Customer object from the current row in the given ResultSet. The caller is + * responsible for closing the ResultSet. + * + * @param rs an open ResultSet positioned to the desired row + * @return the newly created Customer object + * @throws SQLException for problems getting data from row + */ + public static Customer newCustomerFromResults(ResultSet rs) throws SQLException { + Customer c = new Customer(); + // TODO: Use column indices: probably faster? + c.c_first = rs.getString("c_first"); + c.c_middle = rs.getString("c_middle"); + c.c_street_1 = rs.getString("c_street_1"); + c.c_street_2 = rs.getString("c_street_2"); + c.c_city = rs.getString("c_city"); + c.c_state = rs.getString("c_state"); + c.c_zip = rs.getString("c_zip"); + c.c_phone = rs.getString("c_phone"); + c.c_credit = rs.getString("c_credit"); + c.c_credit_lim = rs.getFloat("c_credit_lim"); + c.c_discount = rs.getFloat("c_discount"); + c.c_balance = rs.getFloat("c_balance"); + c.c_ytd_payment = rs.getFloat("c_ytd_payment"); + c.c_payment_cnt = rs.getInt("c_payment_cnt"); + c.c_since = rs.getTimestamp("c_since"); + return c; + } + + private static final RandomGenerator ran = new RandomGenerator(0); + + public static String randomStr(int strLen) { + if (strLen > 1) { + return ran.astring(strLen - 1, strLen - 1); + } else { + return ""; } + } - public static String getNonUniformRandomLastNameForRun(Random r) { - return getLastName(nonUniformRandom(255, C_LAST_RUN_C, 0, 999, r)); + public static String randomNStr(int stringLength) { + if (stringLength > 0) { + return ran.nstring(stringLength, stringLength); + } else { + return ""; } - - public static String getNonUniformRandomLastNameForLoad(Random r) { - return getLastName(nonUniformRandom(255, C_LAST_LOAD_C, 0, 999, r)); - } - - public static int randomNumber(int min, int max, Random r) { - return (int) (r.nextDouble() * (max - min + 1) + min); - } - - public static int nonUniformRandom(int A, int C, int min, int max, Random r) { - return (((randomNumber(0, A, r) | randomNumber(min, max, r)) + C) % (max - - min + 1)) - + min; - } - + } + + public static String getCurrentTime() { + return dateFormat.format(new java.util.Date()); + } + + public static String formattedDouble(double d) { + String dS = "" + d; + return dS.length() > 6 ? dS.substring(0, 6) : dS; + } + + // TODO: TPCC-C 2.1.6: For non-uniform random number generation, the + // constants for item id, + // customer id and customer name are supposed to be selected ONCE and reused + + // We just hardcode one selection of parameters here, but we should generate + // these each time. + private static final int OL_I_ID_C = 7911; // in range [0, 8191] + private static final int C_ID_C = 259; // in range [0, 1023] + // NOTE: TPC-C 2.1.6.1 specifies that abs(C_LAST_LOAD_C - C_LAST_RUN_C) must + // be within [65, 119] + private static final int C_LAST_LOAD_C = 157; // in range [0, 255] + private static final int C_LAST_RUN_C = 223; // in range [0, 255] + + public static int getItemID(Random r) { + return nonUniformRandom(8191, OL_I_ID_C, 1, configItemCount, r); + } + + public static int getCustomerID(Random r) { + return nonUniformRandom(1023, C_ID_C, 1, configCustPerDist, r); + } + + public static String getLastName(int num) { + return nameTokens[num / 100] + nameTokens[(num / 10) % 10] + nameTokens[num % 10]; + } + + public static String getNonUniformRandomLastNameForRun(Random r) { + return getLastName(nonUniformRandom(255, C_LAST_RUN_C, 0, 999, r)); + } + + public static String getNonUniformRandomLastNameForLoad(Random r) { + return getLastName(nonUniformRandom(255, C_LAST_LOAD_C, 0, 999, r)); + } + + public static int randomNumber(int min, int max, Random r) { + return (int) (r.nextDouble() * (max - min + 1) + min); + } + + public static int nonUniformRandom(int A, int C, int min, int max, Random r) { + return (((randomNumber(0, A, r) | randomNumber(min, max, r)) + C) % (max - min + 1)) + min; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCWorker.java index 9cbb4643c..cc79b36fb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/TPCCWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc; import com.oltpbenchmark.api.Procedure.UserAbortException; @@ -23,75 +22,81 @@ import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tpcc.procedures.TPCCProcedure; import com.oltpbenchmark.types.TransactionStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class TPCCWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(TPCCWorker.class); - - private final int terminalWarehouseID; - /** - * Forms a range [lower, upper] (inclusive). - */ - private final int terminalDistrictLowerID; - private final int terminalDistrictUpperID; - private final Random gen = new Random(); - - private final int numWarehouses; - - public TPCCWorker(TPCCBenchmark benchmarkModule, int id, - int terminalWarehouseID, int terminalDistrictLowerID, - int terminalDistrictUpperID, int numWarehouses) { - super(benchmarkModule, id); - - this.terminalWarehouseID = terminalWarehouseID; - this.terminalDistrictLowerID = terminalDistrictLowerID; - this.terminalDistrictUpperID = terminalDistrictUpperID; - - - this.numWarehouses = numWarehouses; + private static final Logger LOG = LoggerFactory.getLogger(TPCCWorker.class); + + private final int terminalWarehouseID; + + /** Forms a range [lower, upper] (inclusive). */ + private final int terminalDistrictLowerID; + + private final int terminalDistrictUpperID; + private final Random gen = new Random(); + + private final int numWarehouses; + + public TPCCWorker( + TPCCBenchmark benchmarkModule, + int id, + int terminalWarehouseID, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + int numWarehouses) { + super(benchmarkModule, id); + + this.terminalWarehouseID = terminalWarehouseID; + this.terminalDistrictLowerID = terminalDistrictLowerID; + this.terminalDistrictUpperID = terminalDistrictUpperID; + + this.numWarehouses = numWarehouses; + } + + /** Executes a single TPCC transaction of type transactionType. */ + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) + throws UserAbortException, SQLException { + try { + TPCCProcedure proc = (TPCCProcedure) this.getProcedure(nextTransaction.getProcedureClass()); + proc.run( + conn, + gen, + terminalWarehouseID, + numWarehouses, + terminalDistrictLowerID, + terminalDistrictUpperID, + this); + } catch (ClassCastException ex) { + // fail gracefully + LOG.error("We have been invoked with an INVALID transactionType?!", ex); + throw new RuntimeException("Bad transaction type = " + nextTransaction); } - - /** - * Executes a single TPCC transaction of type transactionType. - */ - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) throws UserAbortException, SQLException { - try { - TPCCProcedure proc = (TPCCProcedure) this.getProcedure(nextTransaction.getProcedureClass()); - proc.run(conn, gen, terminalWarehouseID, numWarehouses, - terminalDistrictLowerID, terminalDistrictUpperID, this); - } catch (ClassCastException ex) { - //fail gracefully - LOG.error("We have been invoked with an INVALID transactionType?!", ex); - throw new RuntimeException("Bad transaction type = " + nextTransaction); - } - return (TransactionStatus.SUCCESS); - } - - @Override - protected long getPreExecutionWaitInMillis(TransactionType type) { - // TPC-C 5.2.5.2: For keying times for each type of transaction. - return type.getPreExecutionWait(); - } - - @Override - protected long getPostExecutionWaitInMillis(TransactionType type) { - // TPC-C 5.2.5.4: For think times for each type of transaction. - long mean = type.getPostExecutionWait(); - - float c = this.getBenchmark().rng().nextFloat(); - long thinkTime = (long) (-1 * Math.log(c) * mean); - if (thinkTime > 10 * mean) { - thinkTime = 10 * mean; - } - - return thinkTime; + return (TransactionStatus.SUCCESS); + } + + @Override + protected long getPreExecutionWaitInMillis(TransactionType type) { + // TPC-C 5.2.5.2: For keying times for each type of transaction. + return type.getPreExecutionWait(); + } + + @Override + protected long getPostExecutionWaitInMillis(TransactionType type) { + // TPC-C 5.2.5.4: For think times for each type of transaction. + long mean = type.getPostExecutionWait(); + + float c = this.getBenchmark().rng().nextFloat(); + long thinkTime = (long) (-1 * Math.log(c) * mean); + if (thinkTime > 10 * mean) { + thinkTime = 10 * mean; } + return thinkTime; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Customer.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Customer.java index 2fe492169..10800c862 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Customer.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Customer.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.sql.Timestamp; @@ -23,88 +22,131 @@ public class Customer { - public int c_id; - public int c_d_id; - public int c_w_id; - public int c_payment_cnt; - public int c_delivery_cnt; - public Timestamp c_since; - public float c_discount; - public float c_credit_lim; - public float c_balance; - public float c_ytd_payment; - public String c_credit; - public String c_last; - public String c_first; - public String c_street_1; - public String c_street_2; - public String c_city; - public String c_state; - public String c_zip; - public String c_phone; - public String c_middle; - public String c_data; + public int c_id; + public int c_d_id; + public int c_w_id; + public int c_payment_cnt; + public int c_delivery_cnt; + public Timestamp c_since; + public float c_discount; + public float c_credit_lim; + public float c_balance; + public float c_ytd_payment; + public String c_credit; + public String c_last; + public String c_first; + public String c_street_1; + public String c_street_2; + public String c_city; + public String c_state; + public String c_zip; + public String c_phone; + public String c_middle; + public String c_data; - @Override - public String toString() { - return ("\n***************** Customer ********************" - + "\n* c_id = " - + c_id - + "\n* c_d_id = " - + c_d_id - + "\n* c_w_id = " - + c_w_id - + "\n* c_discount = " - + c_discount - + "\n* c_credit = " - + c_credit - + "\n* c_last = " - + c_last - + "\n* c_first = " - + c_first - + "\n* c_credit_lim = " - + c_credit_lim - + "\n* c_balance = " - + c_balance - + "\n* c_ytd_payment = " - + c_ytd_payment - + "\n* c_payment_cnt = " - + c_payment_cnt - + "\n* c_delivery_cnt = " - + c_delivery_cnt - + "\n* c_street_1 = " - + c_street_1 - + "\n* c_street_2 = " - + c_street_2 - + "\n* c_city = " - + c_city - + "\n* c_state = " - + c_state - + "\n* c_zip = " - + c_zip - + "\n* c_phone = " - + c_phone - + "\n* c_since = " - + c_since - + "\n* c_middle = " - + c_middle - + "\n* c_data = " + c_data + "\n**********************************************"); - } + @Override + public String toString() { + return ("\n***************** Customer ********************" + + "\n* c_id = " + + c_id + + "\n* c_d_id = " + + c_d_id + + "\n* c_w_id = " + + c_w_id + + "\n* c_discount = " + + c_discount + + "\n* c_credit = " + + c_credit + + "\n* c_last = " + + c_last + + "\n* c_first = " + + c_first + + "\n* c_credit_lim = " + + c_credit_lim + + "\n* c_balance = " + + c_balance + + "\n* c_ytd_payment = " + + c_ytd_payment + + "\n* c_payment_cnt = " + + c_payment_cnt + + "\n* c_delivery_cnt = " + + c_delivery_cnt + + "\n* c_street_1 = " + + c_street_1 + + "\n* c_street_2 = " + + c_street_2 + + "\n* c_city = " + + c_city + + "\n* c_state = " + + c_state + + "\n* c_zip = " + + c_zip + + "\n* c_phone = " + + c_phone + + "\n* c_since = " + + c_since + + "\n* c_middle = " + + c_middle + + "\n* c_data = " + + c_data + + "\n**********************************************"); + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Customer customer = (Customer) o; - return c_id == customer.c_id && c_d_id == customer.c_d_id && c_w_id == customer.c_w_id && c_payment_cnt == customer.c_payment_cnt && c_delivery_cnt == customer.c_delivery_cnt && Float.compare(customer.c_discount, c_discount) == 0 && Float.compare(customer.c_credit_lim, c_credit_lim) == 0 && Float.compare(customer.c_balance, c_balance) == 0 && Float.compare(customer.c_ytd_payment, c_ytd_payment) == 0 && Objects.equals(c_since, customer.c_since) && Objects.equals(c_credit, customer.c_credit) && Objects.equals(c_last, customer.c_last) && Objects.equals(c_first, customer.c_first) && Objects.equals(c_street_1, customer.c_street_1) && Objects.equals(c_street_2, customer.c_street_2) && Objects.equals(c_city, customer.c_city) && Objects.equals(c_state, customer.c_state) && Objects.equals(c_zip, customer.c_zip) && Objects.equals(c_phone, customer.c_phone) && Objects.equals(c_middle, customer.c_middle) && Objects.equals(c_data, customer.c_data); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public int hashCode() { - return Objects.hash(c_id, c_d_id, c_w_id, c_payment_cnt, c_delivery_cnt, c_since, c_discount, c_credit_lim, c_balance, c_ytd_payment, c_credit, c_last, c_first, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_middle, c_data); + if (o == null || getClass() != o.getClass()) { + return false; } + Customer customer = (Customer) o; + return c_id == customer.c_id + && c_d_id == customer.c_d_id + && c_w_id == customer.c_w_id + && c_payment_cnt == customer.c_payment_cnt + && c_delivery_cnt == customer.c_delivery_cnt + && Float.compare(customer.c_discount, c_discount) == 0 + && Float.compare(customer.c_credit_lim, c_credit_lim) == 0 + && Float.compare(customer.c_balance, c_balance) == 0 + && Float.compare(customer.c_ytd_payment, c_ytd_payment) == 0 + && Objects.equals(c_since, customer.c_since) + && Objects.equals(c_credit, customer.c_credit) + && Objects.equals(c_last, customer.c_last) + && Objects.equals(c_first, customer.c_first) + && Objects.equals(c_street_1, customer.c_street_1) + && Objects.equals(c_street_2, customer.c_street_2) + && Objects.equals(c_city, customer.c_city) + && Objects.equals(c_state, customer.c_state) + && Objects.equals(c_zip, customer.c_zip) + && Objects.equals(c_phone, customer.c_phone) + && Objects.equals(c_middle, customer.c_middle) + && Objects.equals(c_data, customer.c_data); + } + + @Override + public int hashCode() { + return Objects.hash( + c_id, + c_d_id, + c_w_id, + c_payment_cnt, + c_delivery_cnt, + c_since, + c_discount, + c_credit_lim, + c_balance, + c_ytd_payment, + c_credit, + c_last, + c_first, + c_street_1, + c_street_2, + c_city, + c_state, + c_zip, + c_phone, + c_middle, + c_data); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java index f60fce86e..3c95891df 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/District.java @@ -15,48 +15,50 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.io.Serializable; public class District implements Serializable { - static final long serialVersionUID = 0; - - public int d_id; - public int d_w_id; - public int d_next_o_id; - public float d_ytd; - public float d_tax; - public String d_name; - public String d_street_1; - public String d_street_2; - public String d_city; - public String d_state; - public String d_zip; + static final long serialVersionUID = 0; - @Override - public String toString() { - return ("\n***************** District ********************" - + "\n* d_id = " - + d_id - + "\n* d_w_id = " - + d_w_id - + "\n* d_ytd = " - + d_ytd - + "\n* d_tax = " - + d_tax - + "\n* d_next_o_id = " - + d_next_o_id - + "\n* d_name = " - + d_name - + "\n* d_street_1 = " - + d_street_1 - + "\n* d_street_2 = " - + d_street_2 - + "\n* d_city = " - + d_city - + "\n* d_state = " + d_state + "\n* d_zip = " + d_zip + "\n**********************************************"); - } + public int d_id; + public int d_w_id; + public int d_next_o_id; + public float d_ytd; + public float d_tax; + public String d_name; + public String d_street_1; + public String d_street_2; + public String d_city; + public String d_state; + public String d_zip; + @Override + public String toString() { + return ("\n***************** District ********************" + + "\n* d_id = " + + d_id + + "\n* d_w_id = " + + d_w_id + + "\n* d_ytd = " + + d_ytd + + "\n* d_tax = " + + d_tax + + "\n* d_next_o_id = " + + d_next_o_id + + "\n* d_name = " + + d_name + + "\n* d_street_1 = " + + d_street_1 + + "\n* d_street_2 = " + + d_street_2 + + "\n* d_city = " + + d_city + + "\n* d_state = " + + d_state + + "\n* d_zip = " + + d_zip + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/History.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/History.java index ff8d3be82..2459f2090 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/History.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/History.java @@ -15,29 +15,40 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.sql.Timestamp; public class History { - public int h_c_id; - public int h_c_d_id; - public int h_c_w_id; - public int h_d_id; - public int h_w_id; - public Timestamp h_date; - public float h_amount; - public String h_data; - - @Override - public String toString() { - return ("\n***************** History ********************" - + "\n* h_c_id = " + h_c_id + "\n* h_c_d_id = " + h_c_d_id - + "\n* h_c_w_id = " + h_c_w_id + "\n* h_d_id = " + h_d_id - + "\n* h_w_id = " + h_w_id + "\n* h_date = " + h_date - + "\n* h_amount = " + h_amount + "\n* h_data = " + h_data + "\n**********************************************"); - } + public int h_c_id; + public int h_c_d_id; + public int h_c_w_id; + public int h_d_id; + public int h_w_id; + public Timestamp h_date; + public float h_amount; + public String h_data; + @Override + public String toString() { + return ("\n***************** History ********************" + + "\n* h_c_id = " + + h_c_id + + "\n* h_c_d_id = " + + h_c_d_id + + "\n* h_c_w_id = " + + h_c_w_id + + "\n* h_d_id = " + + h_d_id + + "\n* h_w_id = " + + h_w_id + + "\n* h_date = " + + h_date + + "\n* h_amount = " + + h_amount + + "\n* h_data = " + + h_data + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Item.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Item.java index fcf603bfa..0b27d9af3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Item.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Item.java @@ -15,23 +15,29 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; public class Item { - public int i_id; // PRIMARY KEY - public int i_im_id; - public double i_price; - public String i_name; - public String i_data; - - @Override - public String toString() { - return ("\n***************** Item ********************" - + "\n* i_id = " + i_id + "\n* i_name = " + i_name - + "\n* i_price = " + i_price + "\n* i_data = " + i_data - + "\n* i_im_id = " + i_im_id + "\n**********************************************"); - } + public int i_id; // PRIMARY KEY + public int i_im_id; + public double i_price; + public String i_name; + public String i_data; + @Override + public String toString() { + return ("\n***************** Item ********************" + + "\n* i_id = " + + i_id + + "\n* i_name = " + + i_name + + "\n* i_price = " + + i_price + + "\n* i_data = " + + i_data + + "\n* i_im_id = " + + i_im_id + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java index 2614bb881..ef0c9faed 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/NewOrder.java @@ -15,23 +15,26 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.io.Serializable; public class NewOrder implements Serializable { - private static final long serialVersionUID = 1L; - - public int no_w_id; - public int no_d_id; - public int no_o_id; + private static final long serialVersionUID = 1L; - @Override - public String toString() { - return ("\n***************** NewOrder ********************" - + "\n* no_w_id = " + no_w_id + "\n* no_d_id = " - + no_d_id + "\n* no_o_id = " + no_o_id + "\n**********************************************"); - } + public int no_w_id; + public int no_d_id; + public int no_o_id; + @Override + public String toString() { + return ("\n***************** NewOrder ********************" + + "\n* no_w_id = " + + no_w_id + + "\n* no_d_id = " + + no_d_id + + "\n* no_o_id = " + + no_o_id + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Oorder.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Oorder.java index 3ea73bb54..e2833c807 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Oorder.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Oorder.java @@ -15,34 +15,40 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.sql.Timestamp; public class Oorder { - public int o_id; - public int o_w_id; - public int o_d_id; - public int o_c_id; - public Integer o_carrier_id; - public int o_ol_cnt; - public int o_all_local; - public Timestamp o_entry_d; - - @Override - public String toString() { - return ("\n***************** Oorder ********************" - + "\n* o_id = " + o_id - + "\n* o_w_id = " + o_w_id - + "\n* o_d_id = " + o_d_id - + "\n* o_c_id = " + o_c_id - + "\n* o_carrier_id = " + o_carrier_id - + "\n* o_ol_cnt = " + o_ol_cnt - + "\n* o_all_local = " + o_all_local - + "\n* o_entry_d = " + o_entry_d + - "\n**********************************************"); - } + public int o_id; + public int o_w_id; + public int o_d_id; + public int o_c_id; + public Integer o_carrier_id; + public int o_ol_cnt; + public int o_all_local; + public Timestamp o_entry_d; + @Override + public String toString() { + return ("\n***************** Oorder ********************" + + "\n* o_id = " + + o_id + + "\n* o_w_id = " + + o_w_id + + "\n* o_d_id = " + + o_d_id + + "\n* o_c_id = " + + o_c_id + + "\n* o_carrier_id = " + + o_carrier_id + + "\n* o_ol_cnt = " + + o_ol_cnt + + "\n* o_all_local = " + + o_all_local + + "\n* o_entry_d = " + + o_entry_d + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/OrderLine.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/OrderLine.java index 6f4ae0e0b..c2a6d7c84 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/OrderLine.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/OrderLine.java @@ -15,38 +15,46 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.sql.Timestamp; public class OrderLine { - public int ol_w_id; - public int ol_d_id; - public int ol_o_id; - public int ol_number; - public int ol_i_id; - public int ol_supply_w_id; - public int ol_quantity; - public Timestamp ol_delivery_d; - public float ol_amount; - public String ol_dist_info; - - @Override - public String toString() { - return ("\n***************** OrderLine ********************" - + "\n* ol_w_id = " + ol_w_id - + "\n* ol_d_id = " + ol_d_id - + "\n* ol_o_id = " + ol_o_id - + "\n* ol_number = " + ol_number - + "\n* ol_i_id = " + ol_i_id - + "\n* ol_delivery_d = " + ol_delivery_d - + "\n* ol_amount = " + ol_amount - + "\n* ol_supply_w_id = " + ol_supply_w_id - + "\n* ol_quantity = " + ol_quantity - + "\n* ol_dist_info = " + ol_dist_info - + "\n**********************************************"); - } + public int ol_w_id; + public int ol_d_id; + public int ol_o_id; + public int ol_number; + public int ol_i_id; + public int ol_supply_w_id; + public int ol_quantity; + public Timestamp ol_delivery_d; + public float ol_amount; + public String ol_dist_info; + @Override + public String toString() { + return ("\n***************** OrderLine ********************" + + "\n* ol_w_id = " + + ol_w_id + + "\n* ol_d_id = " + + ol_d_id + + "\n* ol_o_id = " + + ol_o_id + + "\n* ol_number = " + + ol_number + + "\n* ol_i_id = " + + ol_i_id + + "\n* ol_delivery_d = " + + ol_delivery_d + + "\n* ol_amount = " + + ol_amount + + "\n* ol_supply_w_id = " + + ol_supply_w_id + + "\n* ol_quantity = " + + ol_quantity + + "\n* ol_dist_info = " + + ol_dist_info + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java index fde832b1e..9fb30df70 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Stock.java @@ -15,69 +15,68 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.io.Serializable; public class Stock implements Serializable { - static final long serialVersionUID = 0; - - public int s_i_id; // PRIMARY KEY 2 - public int s_w_id; // PRIMARY KEY 1 - public int s_order_cnt; - public int s_remote_cnt; - public int s_quantity; - public float s_ytd; - public String s_data; - public String s_dist_01; - public String s_dist_02; - public String s_dist_03; - public String s_dist_04; - public String s_dist_05; - public String s_dist_06; - public String s_dist_07; - public String s_dist_08; - public String s_dist_09; - public String s_dist_10; - - @Override - public String toString() { - return ( + static final long serialVersionUID = 0; - "\n***************** Stock ********************" - + "\n* s_i_id = " - + s_i_id - + "\n* s_w_id = " - + s_w_id - + "\n* s_quantity = " - + s_quantity - + "\n* s_ytd = " - + s_ytd - + "\n* s_order_cnt = " - + s_order_cnt - + "\n* s_remote_cnt = " - + s_remote_cnt - + "\n* s_data = " - + s_data - + "\n* s_dist_01 = " - + s_dist_01 - + "\n* s_dist_02 = " - + s_dist_02 - + "\n* s_dist_03 = " - + s_dist_03 - + "\n* s_dist_04 = " - + s_dist_04 - + "\n* s_dist_05 = " - + s_dist_05 - + "\n* s_dist_06 = " - + s_dist_06 - + "\n* s_dist_07 = " - + s_dist_07 - + "\n* s_dist_08 = " - + s_dist_08 - + "\n* s_dist_09 = " - + s_dist_09 + "\n* s_dist_10 = " + s_dist_10 + "\n**********************************************"); - } + public int s_i_id; // PRIMARY KEY 2 + public int s_w_id; // PRIMARY KEY 1 + public int s_order_cnt; + public int s_remote_cnt; + public int s_quantity; + public float s_ytd; + public String s_data; + public String s_dist_01; + public String s_dist_02; + public String s_dist_03; + public String s_dist_04; + public String s_dist_05; + public String s_dist_06; + public String s_dist_07; + public String s_dist_08; + public String s_dist_09; + public String s_dist_10; + @Override + public String toString() { + return ("\n***************** Stock ********************" + + "\n* s_i_id = " + + s_i_id + + "\n* s_w_id = " + + s_w_id + + "\n* s_quantity = " + + s_quantity + + "\n* s_ytd = " + + s_ytd + + "\n* s_order_cnt = " + + s_order_cnt + + "\n* s_remote_cnt = " + + s_remote_cnt + + "\n* s_data = " + + s_data + + "\n* s_dist_01 = " + + s_dist_01 + + "\n* s_dist_02 = " + + s_dist_02 + + "\n* s_dist_03 = " + + s_dist_03 + + "\n* s_dist_04 = " + + s_dist_04 + + "\n* s_dist_05 = " + + s_dist_05 + + "\n* s_dist_06 = " + + s_dist_06 + + "\n* s_dist_07 = " + + s_dist_07 + + "\n* s_dist_08 = " + + s_dist_08 + + "\n* s_dist_09 = " + + s_dist_09 + + "\n* s_dist_10 = " + + s_dist_10 + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java index 6e5a9d22e..c6797d37d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/pojo/Warehouse.java @@ -15,32 +15,44 @@ * */ - package com.oltpbenchmark.benchmarks.tpcc.pojo; import java.io.Serializable; public class Warehouse implements Serializable { - static final long serialVersionUID = 0; - - public int w_id; // PRIMARY KEY - public float w_ytd; - public double w_tax; - public String w_name; - public String w_street_1; - public String w_street_2; - public String w_city; - public String w_state; - public String w_zip; + static final long serialVersionUID = 0; - @Override - public String toString() { - return ("\n***************** Warehouse ********************" - + "\n* w_id = " + w_id + "\n* w_ytd = " + w_ytd - + "\n* w_tax = " + w_tax + "\n* w_name = " + w_name - + "\n* w_street_1 = " + w_street_1 + "\n* w_street_2 = " - + w_street_2 + "\n* w_city = " + w_city - + "\n* w_state = " + w_state + "\n* w_zip = " + w_zip + "\n**********************************************"); - } + public int w_id; // PRIMARY KEY + public float w_ytd; + public double w_tax; + public String w_name; + public String w_street_1; + public String w_street_2; + public String w_city; + public String w_state; + public String w_zip; + @Override + public String toString() { + return ("\n***************** Warehouse ********************" + + "\n* w_id = " + + w_id + + "\n* w_ytd = " + + w_ytd + + "\n* w_tax = " + + w_tax + + "\n* w_name = " + + w_name + + "\n* w_street_1 = " + + w_street_1 + + "\n* w_street_2 = " + + w_street_2 + + "\n* w_city = " + + w_city + + "\n* w_state = " + + w_state + + "\n* w_zip = " + + w_zip + + "\n**********************************************"); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Delivery.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Delivery.java index 9626b491f..2cf7acee7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Delivery.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Delivery.java @@ -22,263 +22,307 @@ import com.oltpbenchmark.benchmarks.tpcc.TPCCConstants; import com.oltpbenchmark.benchmarks.tpcc.TPCCUtil; import com.oltpbenchmark.benchmarks.tpcc.TPCCWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.math.BigDecimal; import java.sql.*; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Delivery extends TPCCProcedure { - private static final Logger LOG = LoggerFactory.getLogger(Delivery.class); + private static final Logger LOG = LoggerFactory.getLogger(Delivery.class); - public SQLStmt delivGetOrderIdSQL = new SQLStmt( - """ + public SQLStmt delivGetOrderIdSQL = + new SQLStmt( + """ SELECT NO_O_ID FROM %s WHERE NO_D_ID = ? AND NO_W_ID = ? ORDER BY NO_O_ID ASC LIMIT 1 - """.formatted(TPCCConstants.TABLENAME_NEWORDER)); - - public SQLStmt delivDeleteNewOrderSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_NEWORDER)); + + public SQLStmt delivDeleteNewOrderSQL = + new SQLStmt( + """ DELETE FROM %s WHERE NO_O_ID = ? AND NO_D_ID = ? AND NO_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_NEWORDER)); - - public SQLStmt delivGetCustIdSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_NEWORDER)); + + public SQLStmt delivGetCustIdSQL = + new SQLStmt( + """ SELECT O_C_ID FROM %s WHERE O_ID = ? AND O_D_ID = ? AND O_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_OPENORDER)); + """ + .formatted(TPCCConstants.TABLENAME_OPENORDER)); - public SQLStmt delivUpdateCarrierIdSQL = new SQLStmt( - """ + public SQLStmt delivUpdateCarrierIdSQL = + new SQLStmt( + """ UPDATE %s SET O_CARRIER_ID = ? WHERE O_ID = ? AND O_D_ID = ? AND O_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_OPENORDER)); - - public SQLStmt delivUpdateDeliveryDateSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_OPENORDER)); + + public SQLStmt delivUpdateDeliveryDateSQL = + new SQLStmt( + """ UPDATE %s SET OL_DELIVERY_D = ? WHERE OL_O_ID = ? AND OL_D_ID = ? AND OL_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_ORDERLINE)); - - public SQLStmt delivSumOrderAmountSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_ORDERLINE)); + + public SQLStmt delivSumOrderAmountSQL = + new SQLStmt( + """ SELECT SUM(OL_AMOUNT) AS OL_TOTAL FROM %s WHERE OL_O_ID = ? AND OL_D_ID = ? AND OL_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_ORDERLINE)); - - public SQLStmt delivUpdateCustBalDelivCntSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_ORDERLINE)); + + public SQLStmt delivUpdateCustBalDelivCntSQL = + new SQLStmt( + """ UPDATE %s SET C_BALANCE = C_BALANCE + ?, C_DELIVERY_CNT = C_DELIVERY_CNT + 1 WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - + """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); - public void run(Connection conn, Random gen, int w_id, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker w) throws SQLException { + public void run( + Connection conn, + Random gen, + int w_id, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker w) + throws SQLException { - int o_carrier_id = TPCCUtil.randomNumber(1, 10, gen); + int o_carrier_id = TPCCUtil.randomNumber(1, 10, gen); - int d_id; + int d_id; - int[] orderIDs = new int[10]; + int[] orderIDs = new int[10]; - for (d_id = 1; d_id <= terminalDistrictUpperID; d_id++) { - Integer no_o_id = getOrderId(conn, w_id, d_id); + for (d_id = 1; d_id <= terminalDistrictUpperID; d_id++) { + Integer no_o_id = getOrderId(conn, w_id, d_id); - if (no_o_id == null) { - continue; - } + if (no_o_id == null) { + continue; + } - orderIDs[d_id - 1] = no_o_id; + orderIDs[d_id - 1] = no_o_id; - deleteOrder(conn, w_id, d_id, no_o_id); + deleteOrder(conn, w_id, d_id, no_o_id); - int customerId = getCustomerId(conn, w_id, d_id, no_o_id); + int customerId = getCustomerId(conn, w_id, d_id, no_o_id); - updateCarrierId(conn, w_id, o_carrier_id, d_id, no_o_id); + updateCarrierId(conn, w_id, o_carrier_id, d_id, no_o_id); - updateDeliveryDate(conn, w_id, d_id, no_o_id); + updateDeliveryDate(conn, w_id, d_id, no_o_id); - float orderLineTotal = getOrderLineTotal(conn, w_id, d_id, no_o_id); + float orderLineTotal = getOrderLineTotal(conn, w_id, d_id, no_o_id); - updateBalanceAndDelivery(conn, w_id, d_id, customerId, orderLineTotal); - } + updateBalanceAndDelivery(conn, w_id, d_id, customerId, orderLineTotal); + } - if (LOG.isTraceEnabled()) { - StringBuilder terminalMessage = new StringBuilder(); - terminalMessage.append("\n+---------------------------- DELIVERY ---------------------------+\n"); - terminalMessage.append(" Date: "); - terminalMessage.append(TPCCUtil.getCurrentTime()); - terminalMessage.append("\n\n Warehouse: "); - terminalMessage.append(w_id); - terminalMessage.append("\n Carrier: "); - terminalMessage.append(o_carrier_id); - terminalMessage.append("\n\n Delivered Orders\n"); - for (int i = 1; i <= TPCCConfig.configDistPerWhse; i++) { - if (orderIDs[i - 1] >= 0) { - terminalMessage.append(" District "); - terminalMessage.append(i < 10 ? " " : ""); - terminalMessage.append(i); - terminalMessage.append(": Order number "); - terminalMessage.append(orderIDs[i - 1]); - terminalMessage.append(" was delivered.\n"); - } - } - terminalMessage.append("+-----------------------------------------------------------------+\n\n"); - LOG.trace(terminalMessage.toString()); + if (LOG.isTraceEnabled()) { + StringBuilder terminalMessage = new StringBuilder(); + terminalMessage.append( + "\n+---------------------------- DELIVERY ---------------------------+\n"); + terminalMessage.append(" Date: "); + terminalMessage.append(TPCCUtil.getCurrentTime()); + terminalMessage.append("\n\n Warehouse: "); + terminalMessage.append(w_id); + terminalMessage.append("\n Carrier: "); + terminalMessage.append(o_carrier_id); + terminalMessage.append("\n\n Delivered Orders\n"); + for (int i = 1; i <= TPCCConfig.configDistPerWhse; i++) { + if (orderIDs[i - 1] >= 0) { + terminalMessage.append(" District "); + terminalMessage.append(i < 10 ? " " : ""); + terminalMessage.append(i); + terminalMessage.append(": Order number "); + terminalMessage.append(orderIDs[i - 1]); + terminalMessage.append(" was delivered.\n"); } - + } + terminalMessage.append( + "+-----------------------------------------------------------------+\n\n"); + LOG.trace(terminalMessage.toString()); } + } - private Integer getOrderId(Connection conn, int w_id, int d_id) throws SQLException { - - try (PreparedStatement delivGetOrderId = this.getPreparedStatement(conn, delivGetOrderIdSQL)) { - delivGetOrderId.setInt(1, d_id); - delivGetOrderId.setInt(2, w_id); - - try (ResultSet rs = delivGetOrderId.executeQuery()) { + private Integer getOrderId(Connection conn, int w_id, int d_id) throws SQLException { - if (!rs.next()) { - // This district has no new orders. This can happen but should be rare + try (PreparedStatement delivGetOrderId = this.getPreparedStatement(conn, delivGetOrderIdSQL)) { + delivGetOrderId.setInt(1, d_id); + delivGetOrderId.setInt(2, w_id); - LOG.warn(String.format("District has no new orders [W_ID=%d, D_ID=%d]", w_id, d_id)); + try (ResultSet rs = delivGetOrderId.executeQuery()) { - return null; - } + if (!rs.next()) { + // This district has no new orders. This can happen but should be rare - return rs.getInt("NO_O_ID"); + LOG.warn(String.format("District has no new orders [W_ID=%d, D_ID=%d]", w_id, d_id)); - } + return null; } - } - private void deleteOrder(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { - try (PreparedStatement delivDeleteNewOrder = this.getPreparedStatement(conn, delivDeleteNewOrderSQL)) { - delivDeleteNewOrder.setInt(1, no_o_id); - delivDeleteNewOrder.setInt(2, d_id); - delivDeleteNewOrder.setInt(3, w_id); - - int result = delivDeleteNewOrder.executeUpdate(); - - if (result != 1) { - // This code used to run in a loop in an attempt to make this work - // with MySQL's default weird consistency level. We just always run - // this as SERIALIZABLE instead. I don't *think* that fixing this one - // error makes this work with MySQL's default consistency. - // Careful auditing would be required. - String msg = String.format("NewOrder delete failed. Not running with SERIALIZABLE isolation? [w_id=%d, d_id=%d, no_o_id=%d]", w_id, d_id, no_o_id); - throw new UserAbortException(msg); - } - } + return rs.getInt("NO_O_ID"); + } } + } + + private void deleteOrder(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { + try (PreparedStatement delivDeleteNewOrder = + this.getPreparedStatement(conn, delivDeleteNewOrderSQL)) { + delivDeleteNewOrder.setInt(1, no_o_id); + delivDeleteNewOrder.setInt(2, d_id); + delivDeleteNewOrder.setInt(3, w_id); + + int result = delivDeleteNewOrder.executeUpdate(); + + if (result != 1) { + // This code used to run in a loop in an attempt to make this work + // with MySQL's default weird consistency level. We just always run + // this as SERIALIZABLE instead. I don't *think* that fixing this one + // error makes this work with MySQL's default consistency. + // Careful auditing would be required. + String msg = + String.format( + "NewOrder delete failed. Not running with SERIALIZABLE isolation? [w_id=%d, d_id=%d, no_o_id=%d]", + w_id, d_id, no_o_id); + throw new UserAbortException(msg); + } + } + } - private int getCustomerId(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { - - try (PreparedStatement delivGetCustId = this.getPreparedStatement(conn, delivGetCustIdSQL)) { - delivGetCustId.setInt(1, no_o_id); - delivGetCustId.setInt(2, d_id); - delivGetCustId.setInt(3, w_id); + private int getCustomerId(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { - try (ResultSet rs = delivGetCustId.executeQuery()) { + try (PreparedStatement delivGetCustId = this.getPreparedStatement(conn, delivGetCustIdSQL)) { + delivGetCustId.setInt(1, no_o_id); + delivGetCustId.setInt(2, d_id); + delivGetCustId.setInt(3, w_id); - if (!rs.next()) { - String msg = String.format("Failed to retrieve ORDER record [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, no_o_id); - throw new RuntimeException(msg); - } + try (ResultSet rs = delivGetCustId.executeQuery()) { - return rs.getInt("O_C_ID"); - } + if (!rs.next()) { + String msg = + String.format( + "Failed to retrieve ORDER record [W_ID=%d, D_ID=%d, O_ID=%d]", + w_id, d_id, no_o_id); + throw new RuntimeException(msg); } - } - - private void updateCarrierId(Connection conn, int w_id, int o_carrier_id, int d_id, int no_o_id) throws SQLException { - try (PreparedStatement delivUpdateCarrierId = this.getPreparedStatement(conn, delivUpdateCarrierIdSQL)) { - delivUpdateCarrierId.setInt(1, o_carrier_id); - delivUpdateCarrierId.setInt(2, no_o_id); - delivUpdateCarrierId.setInt(3, d_id); - delivUpdateCarrierId.setInt(4, w_id); - int result = delivUpdateCarrierId.executeUpdate(); - - if (result != 1) { - String msg = String.format("Failed to update ORDER record [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, no_o_id); - throw new RuntimeException(msg); - } - } + return rs.getInt("O_C_ID"); + } } - - private void updateDeliveryDate(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { - Timestamp timestamp = new Timestamp(System.currentTimeMillis()); - - try (PreparedStatement delivUpdateDeliveryDate = this.getPreparedStatement(conn, delivUpdateDeliveryDateSQL)) { - delivUpdateDeliveryDate.setTimestamp(1, timestamp); - delivUpdateDeliveryDate.setInt(2, no_o_id); - delivUpdateDeliveryDate.setInt(3, d_id); - delivUpdateDeliveryDate.setInt(4, w_id); - - int result = delivUpdateDeliveryDate.executeUpdate(); - - if (result == 0) { - String msg = String.format("Failed to update ORDER_LINE records [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, no_o_id); - throw new RuntimeException(msg); - } - } + } + + private void updateCarrierId(Connection conn, int w_id, int o_carrier_id, int d_id, int no_o_id) + throws SQLException { + try (PreparedStatement delivUpdateCarrierId = + this.getPreparedStatement(conn, delivUpdateCarrierIdSQL)) { + delivUpdateCarrierId.setInt(1, o_carrier_id); + delivUpdateCarrierId.setInt(2, no_o_id); + delivUpdateCarrierId.setInt(3, d_id); + delivUpdateCarrierId.setInt(4, w_id); + + int result = delivUpdateCarrierId.executeUpdate(); + + if (result != 1) { + String msg = + String.format( + "Failed to update ORDER record [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, no_o_id); + throw new RuntimeException(msg); + } } - - private float getOrderLineTotal(Connection conn, int w_id, int d_id, int no_o_id) throws SQLException { - try (PreparedStatement delivSumOrderAmount = this.getPreparedStatement(conn, delivSumOrderAmountSQL)) { - delivSumOrderAmount.setInt(1, no_o_id); - delivSumOrderAmount.setInt(2, d_id); - delivSumOrderAmount.setInt(3, w_id); - - try (ResultSet rs = delivSumOrderAmount.executeQuery()) { - if (!rs.next()) { - String msg = String.format("Failed to retrieve ORDER_LINE records [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, no_o_id); - throw new RuntimeException(msg); - } - - return rs.getFloat("OL_TOTAL"); - } - } + } + + private void updateDeliveryDate(Connection conn, int w_id, int d_id, int no_o_id) + throws SQLException { + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + + try (PreparedStatement delivUpdateDeliveryDate = + this.getPreparedStatement(conn, delivUpdateDeliveryDateSQL)) { + delivUpdateDeliveryDate.setTimestamp(1, timestamp); + delivUpdateDeliveryDate.setInt(2, no_o_id); + delivUpdateDeliveryDate.setInt(3, d_id); + delivUpdateDeliveryDate.setInt(4, w_id); + + int result = delivUpdateDeliveryDate.executeUpdate(); + + if (result == 0) { + String msg = + String.format( + "Failed to update ORDER_LINE records [W_ID=%d, D_ID=%d, O_ID=%d]", + w_id, d_id, no_o_id); + throw new RuntimeException(msg); + } } - - private void updateBalanceAndDelivery(Connection conn, int w_id, int d_id, int c_id, float orderLineTotal) throws SQLException { - - try (PreparedStatement delivUpdateCustBalDelivCnt = this.getPreparedStatement(conn, delivUpdateCustBalDelivCntSQL)) { - delivUpdateCustBalDelivCnt.setBigDecimal(1, BigDecimal.valueOf(orderLineTotal)); - delivUpdateCustBalDelivCnt.setInt(2, w_id); - delivUpdateCustBalDelivCnt.setInt(3, d_id); - delivUpdateCustBalDelivCnt.setInt(4, c_id); - - int result = delivUpdateCustBalDelivCnt.executeUpdate(); - - if (result == 0) { - String msg = String.format("Failed to update CUSTOMER record [W_ID=%d, D_ID=%d, C_ID=%d]", w_id, d_id, c_id); - throw new RuntimeException(msg); - } + } + + private float getOrderLineTotal(Connection conn, int w_id, int d_id, int no_o_id) + throws SQLException { + try (PreparedStatement delivSumOrderAmount = + this.getPreparedStatement(conn, delivSumOrderAmountSQL)) { + delivSumOrderAmount.setInt(1, no_o_id); + delivSumOrderAmount.setInt(2, d_id); + delivSumOrderAmount.setInt(3, w_id); + + try (ResultSet rs = delivSumOrderAmount.executeQuery()) { + if (!rs.next()) { + String msg = + String.format( + "Failed to retrieve ORDER_LINE records [W_ID=%d, D_ID=%d, O_ID=%d]", + w_id, d_id, no_o_id); + throw new RuntimeException(msg); } - } + return rs.getFloat("OL_TOTAL"); + } + } + } + + private void updateBalanceAndDelivery( + Connection conn, int w_id, int d_id, int c_id, float orderLineTotal) throws SQLException { + + try (PreparedStatement delivUpdateCustBalDelivCnt = + this.getPreparedStatement(conn, delivUpdateCustBalDelivCntSQL)) { + delivUpdateCustBalDelivCnt.setBigDecimal(1, BigDecimal.valueOf(orderLineTotal)); + delivUpdateCustBalDelivCnt.setInt(2, w_id); + delivUpdateCustBalDelivCnt.setInt(3, d_id); + delivUpdateCustBalDelivCnt.setInt(4, c_id); + + int result = delivUpdateCustBalDelivCnt.executeUpdate(); + + if (result == 0) { + String msg = + String.format( + "Failed to update CUSTOMER record [W_ID=%d, D_ID=%d, C_ID=%d]", w_id, d_id, c_id); + throw new RuntimeException(msg); + } + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/NewOrder.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/NewOrder.java index 0e1c6a2bd..e98f9ebe1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/NewOrder.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/NewOrder.java @@ -23,79 +23,95 @@ import com.oltpbenchmark.benchmarks.tpcc.TPCCUtil; import com.oltpbenchmark.benchmarks.tpcc.TPCCWorker; import com.oltpbenchmark.benchmarks.tpcc.pojo.Stock; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.*; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NewOrder extends TPCCProcedure { - private static final Logger LOG = LoggerFactory.getLogger(NewOrder.class); + private static final Logger LOG = LoggerFactory.getLogger(NewOrder.class); - public final SQLStmt stmtGetCustSQL = new SQLStmt( - """ + public final SQLStmt stmtGetCustSQL = + new SQLStmt( + """ SELECT C_DISCOUNT, C_LAST, C_CREDIT FROM %s WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public final SQLStmt stmtGetWhseSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public final SQLStmt stmtGetWhseSQL = + new SQLStmt( + """ SELECT W_TAX FROM %s WHERE W_ID = ? - """.formatted(TPCCConstants.TABLENAME_WAREHOUSE)); - - public final SQLStmt stmtGetDistSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_WAREHOUSE)); + + public final SQLStmt stmtGetDistSQL = + new SQLStmt( + """ SELECT D_NEXT_O_ID, D_TAX FROM %s WHERE D_W_ID = ? AND D_ID = ? FOR UPDATE - """.formatted(TPCCConstants.TABLENAME_DISTRICT)); - - public final SQLStmt stmtInsertNewOrderSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_DISTRICT)); + + public final SQLStmt stmtInsertNewOrderSQL = + new SQLStmt( + """ INSERT INTO %s (NO_O_ID, NO_D_ID, NO_W_ID) VALUES ( ?, ?, ?) - """.formatted(TPCCConstants.TABLENAME_NEWORDER)); - - public final SQLStmt stmtUpdateDistSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_NEWORDER)); + + public final SQLStmt stmtUpdateDistSQL = + new SQLStmt( + """ UPDATE %s SET D_NEXT_O_ID = D_NEXT_O_ID + 1 WHERE D_W_ID = ? AND D_ID = ? - """.formatted(TPCCConstants.TABLENAME_DISTRICT)); - - public final SQLStmt stmtInsertOOrderSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_DISTRICT)); + + public final SQLStmt stmtInsertOOrderSQL = + new SQLStmt( + """ INSERT INTO %s (O_ID, O_D_ID, O_W_ID, O_C_ID, O_ENTRY_D, O_OL_CNT, O_ALL_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?) - """.formatted(TPCCConstants.TABLENAME_OPENORDER)); - - public final SQLStmt stmtGetItemSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_OPENORDER)); + + public final SQLStmt stmtGetItemSQL = + new SQLStmt( + """ SELECT I_PRICE, I_NAME , I_DATA FROM %s WHERE I_ID = ? - """.formatted(TPCCConstants.TABLENAME_ITEM)); - - public final SQLStmt stmtGetStockSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_ITEM)); + + public final SQLStmt stmtGetStockSQL = + new SQLStmt( + """ SELECT S_QUANTITY, S_DATA, S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04, S_DIST_05, S_DIST_06, S_DIST_07, S_DIST_08, S_DIST_09, S_DIST_10 FROM %s WHERE S_I_ID = ? AND S_W_ID = ? FOR UPDATE - """.formatted(TPCCConstants.TABLENAME_STOCK)); - - public final SQLStmt stmtUpdateStockSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_STOCK)); + + public final SQLStmt stmtUpdateStockSQL = + new SQLStmt( + """ UPDATE %s SET S_QUANTITY = ? , S_YTD = S_YTD + ?, @@ -103,263 +119,289 @@ public class NewOrder extends TPCCProcedure { S_REMOTE_CNT = S_REMOTE_CNT + ? WHERE S_I_ID = ? AND S_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_STOCK)); - - public final SQLStmt stmtInsertOrderLineSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_STOCK)); + + public final SQLStmt stmtInsertOrderLineSQL = + new SQLStmt( + """ INSERT INTO %s (OL_O_ID, OL_D_ID, OL_W_ID, OL_NUMBER, OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, OL_DIST_INFO) VALUES (?,?,?,?,?,?,?,?,?) - """.formatted(TPCCConstants.TABLENAME_ORDERLINE)); - - - - public void run(Connection conn, Random gen, int terminalWarehouseID, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker w) throws SQLException { - - int districtID = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); - int customerID = TPCCUtil.getCustomerID(gen); + """ + .formatted(TPCCConstants.TABLENAME_ORDERLINE)); + + public void run( + Connection conn, + Random gen, + int terminalWarehouseID, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker w) + throws SQLException { + + int districtID = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); + int customerID = TPCCUtil.getCustomerID(gen); + + int numItems = TPCCUtil.randomNumber(5, 15, gen); + int[] itemIDs = new int[numItems]; + int[] supplierWarehouseIDs = new int[numItems]; + int[] orderQuantities = new int[numItems]; + int allLocal = 1; + + for (int i = 0; i < numItems; i++) { + itemIDs[i] = TPCCUtil.getItemID(gen); + if (TPCCUtil.randomNumber(1, 100, gen) > 1) { + supplierWarehouseIDs[i] = terminalWarehouseID; + } else { + do { + supplierWarehouseIDs[i] = TPCCUtil.randomNumber(1, numWarehouses, gen); + } while (supplierWarehouseIDs[i] == terminalWarehouseID && numWarehouses > 1); + allLocal = 0; + } + orderQuantities[i] = TPCCUtil.randomNumber(1, 10, gen); + } - int numItems = TPCCUtil.randomNumber(5, 15, gen); - int[] itemIDs = new int[numItems]; - int[] supplierWarehouseIDs = new int[numItems]; - int[] orderQuantities = new int[numItems]; - int allLocal = 1; + // we need to cause 1% of the new orders to be rolled back. + if (TPCCUtil.randomNumber(1, 100, gen) == 1) { + itemIDs[numItems - 1] = TPCCConfig.INVALID_ITEM_ID; + } - for (int i = 0; i < numItems; i++) { - itemIDs[i] = TPCCUtil.getItemID(gen); - if (TPCCUtil.randomNumber(1, 100, gen) > 1) { - supplierWarehouseIDs[i] = terminalWarehouseID; - } else { - do { - supplierWarehouseIDs[i] = TPCCUtil.randomNumber(1, numWarehouses, gen); - } - while (supplierWarehouseIDs[i] == terminalWarehouseID && numWarehouses > 1); - allLocal = 0; - } - orderQuantities[i] = TPCCUtil.randomNumber(1, 10, gen); + newOrderTransaction( + terminalWarehouseID, + districtID, + customerID, + numItems, + allLocal, + itemIDs, + supplierWarehouseIDs, + orderQuantities, + conn); + } + + private void newOrderTransaction( + int w_id, + int d_id, + int c_id, + int o_ol_cnt, + int o_all_local, + int[] itemIDs, + int[] supplierWarehouseIDs, + int[] orderQuantities, + Connection conn) + throws SQLException { + + getCustomer(conn, w_id, d_id, c_id); + + getWarehouse(conn, w_id); + + int d_next_o_id = getDistrict(conn, w_id, d_id); + + updateDistrict(conn, w_id, d_id); + + insertOpenOrder(conn, w_id, d_id, c_id, o_ol_cnt, o_all_local, d_next_o_id); + + insertNewOrder(conn, w_id, d_id, d_next_o_id); + + try (PreparedStatement stmtUpdateStock = this.getPreparedStatement(conn, stmtUpdateStockSQL); + PreparedStatement stmtInsertOrderLine = + this.getPreparedStatement(conn, stmtInsertOrderLineSQL)) { + + for (int ol_number = 1; ol_number <= o_ol_cnt; ol_number++) { + int ol_supply_w_id = supplierWarehouseIDs[ol_number - 1]; + int ol_i_id = itemIDs[ol_number - 1]; + int ol_quantity = orderQuantities[ol_number - 1]; + + // this may occasionally error and that's ok! + float i_price = getItemPrice(conn, ol_i_id); + + float ol_amount = ol_quantity * i_price; + + Stock s = getStock(conn, ol_supply_w_id, ol_i_id, ol_quantity); + + String ol_dist_info = getDistInfo(d_id, s); + + stmtInsertOrderLine.setInt(1, d_next_o_id); + stmtInsertOrderLine.setInt(2, d_id); + stmtInsertOrderLine.setInt(3, w_id); + stmtInsertOrderLine.setInt(4, ol_number); + stmtInsertOrderLine.setInt(5, ol_i_id); + stmtInsertOrderLine.setInt(6, ol_supply_w_id); + stmtInsertOrderLine.setInt(7, ol_quantity); + stmtInsertOrderLine.setDouble(8, ol_amount); + stmtInsertOrderLine.setString(9, ol_dist_info); + stmtInsertOrderLine.addBatch(); + + int s_remote_cnt_increment; + + if (ol_supply_w_id == w_id) { + s_remote_cnt_increment = 0; + } else { + s_remote_cnt_increment = 1; } - // we need to cause 1% of the new orders to be rolled back. - if (TPCCUtil.randomNumber(1, 100, gen) == 1) { - itemIDs[numItems - 1] = TPCCConfig.INVALID_ITEM_ID; - } + stmtUpdateStock.setInt(1, s.s_quantity); + stmtUpdateStock.setInt(2, ol_quantity); + stmtUpdateStock.setInt(3, s_remote_cnt_increment); + stmtUpdateStock.setInt(4, ol_i_id); + stmtUpdateStock.setInt(5, ol_supply_w_id); + stmtUpdateStock.addBatch(); + } - newOrderTransaction(terminalWarehouseID, districtID, customerID, numItems, allLocal, itemIDs, supplierWarehouseIDs, orderQuantities, conn); + stmtInsertOrderLine.executeBatch(); + stmtInsertOrderLine.clearBatch(); + stmtUpdateStock.executeBatch(); + stmtUpdateStock.clearBatch(); } - - - private void newOrderTransaction(int w_id, int d_id, int c_id, - int o_ol_cnt, int o_all_local, int[] itemIDs, - int[] supplierWarehouseIDs, int[] orderQuantities, Connection conn) throws SQLException { - - - getCustomer(conn, w_id, d_id, c_id); - - getWarehouse(conn, w_id); - - int d_next_o_id = getDistrict(conn, w_id, d_id); - - updateDistrict(conn, w_id, d_id); - - insertOpenOrder(conn, w_id, d_id, c_id, o_ol_cnt, o_all_local, d_next_o_id); - - insertNewOrder(conn, w_id, d_id, d_next_o_id); - - try (PreparedStatement stmtUpdateStock = this.getPreparedStatement(conn, stmtUpdateStockSQL); - PreparedStatement stmtInsertOrderLine = this.getPreparedStatement(conn, stmtInsertOrderLineSQL)) { - - for (int ol_number = 1; ol_number <= o_ol_cnt; ol_number++) { - int ol_supply_w_id = supplierWarehouseIDs[ol_number - 1]; - int ol_i_id = itemIDs[ol_number - 1]; - int ol_quantity = orderQuantities[ol_number - 1]; - - // this may occasionally error and that's ok! - float i_price = getItemPrice(conn, ol_i_id); - - float ol_amount = ol_quantity * i_price; - - Stock s = getStock(conn, ol_supply_w_id, ol_i_id, ol_quantity); - - String ol_dist_info = getDistInfo(d_id, s); - - stmtInsertOrderLine.setInt(1, d_next_o_id); - stmtInsertOrderLine.setInt(2, d_id); - stmtInsertOrderLine.setInt(3, w_id); - stmtInsertOrderLine.setInt(4, ol_number); - stmtInsertOrderLine.setInt(5, ol_i_id); - stmtInsertOrderLine.setInt(6, ol_supply_w_id); - stmtInsertOrderLine.setInt(7, ol_quantity); - stmtInsertOrderLine.setDouble(8, ol_amount); - stmtInsertOrderLine.setString(9, ol_dist_info); - stmtInsertOrderLine.addBatch(); - - int s_remote_cnt_increment; - - if (ol_supply_w_id == w_id) { - s_remote_cnt_increment = 0; - } else { - s_remote_cnt_increment = 1; - } - - stmtUpdateStock.setInt(1, s.s_quantity); - stmtUpdateStock.setInt(2, ol_quantity); - stmtUpdateStock.setInt(3, s_remote_cnt_increment); - stmtUpdateStock.setInt(4, ol_i_id); - stmtUpdateStock.setInt(5, ol_supply_w_id); - stmtUpdateStock.addBatch(); - - } - - stmtInsertOrderLine.executeBatch(); - stmtInsertOrderLine.clearBatch(); - - stmtUpdateStock.executeBatch(); - stmtUpdateStock.clearBatch(); - + } + + private String getDistInfo(int d_id, Stock s) { + return switch (d_id) { + case 1 -> s.s_dist_01; + case 2 -> s.s_dist_02; + case 3 -> s.s_dist_03; + case 4 -> s.s_dist_04; + case 5 -> s.s_dist_05; + case 6 -> s.s_dist_06; + case 7 -> s.s_dist_07; + case 8 -> s.s_dist_08; + case 9 -> s.s_dist_09; + case 10 -> s.s_dist_10; + default -> null; + }; + } + + private Stock getStock(Connection conn, int ol_supply_w_id, int ol_i_id, int ol_quantity) + throws SQLException { + try (PreparedStatement stmtGetStock = this.getPreparedStatement(conn, stmtGetStockSQL)) { + stmtGetStock.setInt(1, ol_i_id); + stmtGetStock.setInt(2, ol_supply_w_id); + try (ResultSet rs = stmtGetStock.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("S_I_ID=" + ol_i_id + " not found!"); + } + Stock s = new Stock(); + s.s_quantity = rs.getInt("S_QUANTITY"); + s.s_dist_01 = rs.getString("S_DIST_01"); + s.s_dist_02 = rs.getString("S_DIST_02"); + s.s_dist_03 = rs.getString("S_DIST_03"); + s.s_dist_04 = rs.getString("S_DIST_04"); + s.s_dist_05 = rs.getString("S_DIST_05"); + s.s_dist_06 = rs.getString("S_DIST_06"); + s.s_dist_07 = rs.getString("S_DIST_07"); + s.s_dist_08 = rs.getString("S_DIST_08"); + s.s_dist_09 = rs.getString("S_DIST_09"); + s.s_dist_10 = rs.getString("S_DIST_10"); + + if (s.s_quantity - ol_quantity >= 10) { + s.s_quantity -= ol_quantity; + } else { + s.s_quantity += -ol_quantity + 91; } + return s; + } } - - private String getDistInfo(int d_id, Stock s) { - return switch (d_id) { - case 1 -> s.s_dist_01; - case 2 -> s.s_dist_02; - case 3 -> s.s_dist_03; - case 4 -> s.s_dist_04; - case 5 -> s.s_dist_05; - case 6 -> s.s_dist_06; - case 7 -> s.s_dist_07; - case 8 -> s.s_dist_08; - case 9 -> s.s_dist_09; - case 10 -> s.s_dist_10; - default -> null; - }; - } - - private Stock getStock(Connection conn, int ol_supply_w_id, int ol_i_id, int ol_quantity) throws SQLException { - try (PreparedStatement stmtGetStock = this.getPreparedStatement(conn, stmtGetStockSQL)) { - stmtGetStock.setInt(1, ol_i_id); - stmtGetStock.setInt(2, ol_supply_w_id); - try (ResultSet rs = stmtGetStock.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("S_I_ID=" + ol_i_id + " not found!"); - } - Stock s = new Stock(); - s.s_quantity = rs.getInt("S_QUANTITY"); - s.s_dist_01 = rs.getString("S_DIST_01"); - s.s_dist_02 = rs.getString("S_DIST_02"); - s.s_dist_03 = rs.getString("S_DIST_03"); - s.s_dist_04 = rs.getString("S_DIST_04"); - s.s_dist_05 = rs.getString("S_DIST_05"); - s.s_dist_06 = rs.getString("S_DIST_06"); - s.s_dist_07 = rs.getString("S_DIST_07"); - s.s_dist_08 = rs.getString("S_DIST_08"); - s.s_dist_09 = rs.getString("S_DIST_09"); - s.s_dist_10 = rs.getString("S_DIST_10"); - - if (s.s_quantity - ol_quantity >= 10) { - s.s_quantity -= ol_quantity; - } else { - s.s_quantity += -ol_quantity + 91; - } - - return s; - } + } + + private float getItemPrice(Connection conn, int ol_i_id) throws SQLException { + try (PreparedStatement stmtGetItem = this.getPreparedStatement(conn, stmtGetItemSQL)) { + stmtGetItem.setInt(1, ol_i_id); + try (ResultSet rs = stmtGetItem.executeQuery()) { + if (!rs.next()) { + // This is (hopefully) an expected error: this is an expected new order rollback + throw new UserAbortException( + "EXPECTED new order rollback: I_ID=" + ol_i_id + " not found!"); } - } - private float getItemPrice(Connection conn, int ol_i_id) throws SQLException { - try (PreparedStatement stmtGetItem = this.getPreparedStatement(conn, stmtGetItemSQL)) { - stmtGetItem.setInt(1, ol_i_id); - try (ResultSet rs = stmtGetItem.executeQuery()) { - if (!rs.next()) { - // This is (hopefully) an expected error: this is an expected new order rollback - throw new UserAbortException("EXPECTED new order rollback: I_ID=" + ol_i_id + " not found!"); - } - - return rs.getFloat("I_PRICE"); - } - } + return rs.getFloat("I_PRICE"); + } } - - private void insertNewOrder(Connection conn, int w_id, int d_id, int o_id) throws SQLException { - try (PreparedStatement stmtInsertNewOrder = this.getPreparedStatement(conn, stmtInsertNewOrderSQL);) { - stmtInsertNewOrder.setInt(1, o_id); - stmtInsertNewOrder.setInt(2, d_id); - stmtInsertNewOrder.setInt(3, w_id); - int result = stmtInsertNewOrder.executeUpdate(); - - if (result == 0) { - LOG.warn("new order not inserted"); - } - } + } + + private void insertNewOrder(Connection conn, int w_id, int d_id, int o_id) throws SQLException { + try (PreparedStatement stmtInsertNewOrder = + this.getPreparedStatement(conn, stmtInsertNewOrderSQL); ) { + stmtInsertNewOrder.setInt(1, o_id); + stmtInsertNewOrder.setInt(2, d_id); + stmtInsertNewOrder.setInt(3, w_id); + int result = stmtInsertNewOrder.executeUpdate(); + + if (result == 0) { + LOG.warn("new order not inserted"); + } } - - private void insertOpenOrder(Connection conn, int w_id, int d_id, int c_id, int o_ol_cnt, int o_all_local, int o_id) throws SQLException { - try (PreparedStatement stmtInsertOOrder = this.getPreparedStatement(conn, stmtInsertOOrderSQL);) { - stmtInsertOOrder.setInt(1, o_id); - stmtInsertOOrder.setInt(2, d_id); - stmtInsertOOrder.setInt(3, w_id); - stmtInsertOOrder.setInt(4, c_id); - stmtInsertOOrder.setTimestamp(5, new Timestamp(System.currentTimeMillis())); - stmtInsertOOrder.setInt(6, o_ol_cnt); - stmtInsertOOrder.setInt(7, o_all_local); - - int result = stmtInsertOOrder.executeUpdate(); - - if (result == 0) { - LOG.warn("open order not inserted"); - } - } + } + + private void insertOpenOrder( + Connection conn, int w_id, int d_id, int c_id, int o_ol_cnt, int o_all_local, int o_id) + throws SQLException { + try (PreparedStatement stmtInsertOOrder = + this.getPreparedStatement(conn, stmtInsertOOrderSQL); ) { + stmtInsertOOrder.setInt(1, o_id); + stmtInsertOOrder.setInt(2, d_id); + stmtInsertOOrder.setInt(3, w_id); + stmtInsertOOrder.setInt(4, c_id); + stmtInsertOOrder.setTimestamp(5, new Timestamp(System.currentTimeMillis())); + stmtInsertOOrder.setInt(6, o_ol_cnt); + stmtInsertOOrder.setInt(7, o_all_local); + + int result = stmtInsertOOrder.executeUpdate(); + + if (result == 0) { + LOG.warn("open order not inserted"); + } } - - private void updateDistrict(Connection conn, int w_id, int d_id) throws SQLException { - try (PreparedStatement stmtUpdateDist = this.getPreparedStatement(conn, stmtUpdateDistSQL)) { - stmtUpdateDist.setInt(1, w_id); - stmtUpdateDist.setInt(2, d_id); - int result = stmtUpdateDist.executeUpdate(); - if (result == 0) { - throw new RuntimeException("Error!! Cannot update next_order_id on district for D_ID=" + d_id + " D_W_ID=" + w_id); - } - } + } + + private void updateDistrict(Connection conn, int w_id, int d_id) throws SQLException { + try (PreparedStatement stmtUpdateDist = this.getPreparedStatement(conn, stmtUpdateDistSQL)) { + stmtUpdateDist.setInt(1, w_id); + stmtUpdateDist.setInt(2, d_id); + int result = stmtUpdateDist.executeUpdate(); + if (result == 0) { + throw new RuntimeException( + "Error!! Cannot update next_order_id on district for D_ID=" + d_id + " D_W_ID=" + w_id); + } } - - private int getDistrict(Connection conn, int w_id, int d_id) throws SQLException { - try (PreparedStatement stmtGetDist = this.getPreparedStatement(conn, stmtGetDistSQL)) { - stmtGetDist.setInt(1, w_id); - stmtGetDist.setInt(2, d_id); - try (ResultSet rs = stmtGetDist.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("D_ID=" + d_id + " D_W_ID=" + w_id + " not found!"); - } - return rs.getInt("D_NEXT_O_ID"); - } + } + + private int getDistrict(Connection conn, int w_id, int d_id) throws SQLException { + try (PreparedStatement stmtGetDist = this.getPreparedStatement(conn, stmtGetDistSQL)) { + stmtGetDist.setInt(1, w_id); + stmtGetDist.setInt(2, d_id); + try (ResultSet rs = stmtGetDist.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("D_ID=" + d_id + " D_W_ID=" + w_id + " not found!"); } + return rs.getInt("D_NEXT_O_ID"); + } } - - private void getWarehouse(Connection conn, int w_id) throws SQLException { - try (PreparedStatement stmtGetWhse = this.getPreparedStatement(conn, stmtGetWhseSQL)) { - stmtGetWhse.setInt(1, w_id); - try (ResultSet rs = stmtGetWhse.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("W_ID=" + w_id + " not found!"); - } - } + } + + private void getWarehouse(Connection conn, int w_id) throws SQLException { + try (PreparedStatement stmtGetWhse = this.getPreparedStatement(conn, stmtGetWhseSQL)) { + stmtGetWhse.setInt(1, w_id); + try (ResultSet rs = stmtGetWhse.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("W_ID=" + w_id + " not found!"); } + } } - - private void getCustomer(Connection conn, int w_id, int d_id, int c_id) throws SQLException { - try (PreparedStatement stmtGetCust = this.getPreparedStatement(conn, stmtGetCustSQL)) { - stmtGetCust.setInt(1, w_id); - stmtGetCust.setInt(2, d_id); - stmtGetCust.setInt(3, c_id); - try (ResultSet rs = stmtGetCust.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("C_D_ID=" + d_id + " C_ID=" + c_id + " not found!"); - } - } + } + + private void getCustomer(Connection conn, int w_id, int d_id, int c_id) throws SQLException { + try (PreparedStatement stmtGetCust = this.getPreparedStatement(conn, stmtGetCustSQL)) { + stmtGetCust.setInt(1, w_id); + stmtGetCust.setInt(2, d_id); + stmtGetCust.setInt(3, c_id); + try (ResultSet rs = stmtGetCust.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("C_D_ID=" + d_id + " C_ID=" + c_id + " not found!"); } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java index 7ab943e51..eeedcfd2f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/OrderStatus.java @@ -23,9 +23,6 @@ import com.oltpbenchmark.benchmarks.tpcc.TPCCWorker; import com.oltpbenchmark.benchmarks.tpcc.pojo.Customer; import com.oltpbenchmark.benchmarks.tpcc.pojo.Oorder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -33,32 +30,39 @@ import java.util.ArrayList; import java.util.List; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class OrderStatus extends TPCCProcedure { - private static final Logger LOG = LoggerFactory.getLogger(OrderStatus.class); + private static final Logger LOG = LoggerFactory.getLogger(OrderStatus.class); - public SQLStmt ordStatGetNewestOrdSQL = new SQLStmt( - """ + public SQLStmt ordStatGetNewestOrdSQL = + new SQLStmt( + """ SELECT O_ID, O_CARRIER_ID, O_ENTRY_D FROM %s WHERE O_W_ID = ? AND O_D_ID = ? AND O_C_ID = ? ORDER BY O_ID DESC LIMIT 1 - """.formatted(TPCCConstants.TABLENAME_OPENORDER)); - - public SQLStmt ordStatGetOrderLinesSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_OPENORDER)); + + public SQLStmt ordStatGetOrderLinesSQL = + new SQLStmt( + """ SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT, OL_DELIVERY_D FROM %s WHERE OL_O_ID = ? AND OL_D_ID = ? AND OL_W_ID = ? - """.formatted(TPCCConstants.TABLENAME_ORDERLINE)); - - public SQLStmt payGetCustSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_ORDERLINE)); + + public SQLStmt payGetCustSQL = + new SQLStmt( + """ SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE @@ -66,10 +70,12 @@ public class OrderStatus extends TPCCProcedure { WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public SQLStmt customerByNameSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public SQLStmt customerByNameSQL = + new SQLStmt( + """ SELECT C_FIRST, C_MIDDLE, C_ID, C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE @@ -78,221 +84,235 @@ public class OrderStatus extends TPCCProcedure { AND C_D_ID = ? AND C_LAST = ? ORDER BY C_FIRST - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public void run(Connection conn, Random gen, int w_id, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker w) throws SQLException { - - int d_id = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); - int y = TPCCUtil.randomNumber(1, 100, gen); - - boolean c_by_name; - String c_last = null; - int c_id = -1; - - if (y <= 60) { - c_by_name = true; - c_last = TPCCUtil.getNonUniformRandomLastNameForRun(gen); - } else { - c_by_name = false; - c_id = TPCCUtil.getCustomerID(gen); - } - - - Customer c; - - if (c_by_name) { - c = getCustomerByName(w_id, d_id, c_last, conn); - } else { - c = getCustomerById(w_id, d_id, c_id, conn); - } - + """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public void run( + Connection conn, + Random gen, + int w_id, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker w) + throws SQLException { + + int d_id = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); + int y = TPCCUtil.randomNumber(1, 100, gen); + + boolean c_by_name; + String c_last = null; + int c_id = -1; + + if (y <= 60) { + c_by_name = true; + c_last = TPCCUtil.getNonUniformRandomLastNameForRun(gen); + } else { + c_by_name = false; + c_id = TPCCUtil.getCustomerID(gen); + } - Oorder o = getOrderDetails(conn, w_id, d_id, c); + Customer c; - // retrieve the order lines for the most recent order - List orderLines = getOrderLines(conn, w_id, d_id, o.o_id, c); + if (c_by_name) { + c = getCustomerByName(w_id, d_id, c_last, conn); + } else { + c = getCustomerById(w_id, d_id, c_id, conn); + } - if (LOG.isTraceEnabled()) { - StringBuilder sb = new StringBuilder(); - sb.append("\n"); - sb.append("+-------------------------- ORDER-STATUS -------------------------+\n"); - sb.append(" Date: "); - sb.append(TPCCUtil.getCurrentTime()); - sb.append("\n\n Warehouse: "); - sb.append(w_id); - sb.append("\n District: "); - sb.append(d_id); - sb.append("\n\n Customer: "); - sb.append(c.c_id); - sb.append("\n Name: "); - sb.append(c.c_first); - sb.append(" "); - sb.append(c.c_middle); + Oorder o = getOrderDetails(conn, w_id, d_id, c); + + // retrieve the order lines for the most recent order + List orderLines = getOrderLines(conn, w_id, d_id, o.o_id, c); + + if (LOG.isTraceEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + sb.append("+-------------------------- ORDER-STATUS -------------------------+\n"); + sb.append(" Date: "); + sb.append(TPCCUtil.getCurrentTime()); + sb.append("\n\n Warehouse: "); + sb.append(w_id); + sb.append("\n District: "); + sb.append(d_id); + sb.append("\n\n Customer: "); + sb.append(c.c_id); + sb.append("\n Name: "); + sb.append(c.c_first); + sb.append(" "); + sb.append(c.c_middle); + sb.append(" "); + sb.append(c.c_last); + sb.append("\n Balance: "); + sb.append(c.c_balance); + sb.append("\n\n"); + if (o.o_id == -1) { + sb.append(" Customer has no orders placed.\n"); + } else { + sb.append(" Order-Number: "); + sb.append(o.o_id); + sb.append("\n Entry-Date: "); + sb.append(o.o_entry_d); + sb.append("\n Carrier-Number: "); + sb.append(o.o_carrier_id); + sb.append("\n\n"); + if (orderLines.size() != 0) { + sb.append(" [Supply_W - Item_ID - Qty - Amount - Delivery-Date]\n"); + for (String orderLine : orderLines) { sb.append(" "); - sb.append(c.c_last); - sb.append("\n Balance: "); - sb.append(c.c_balance); - sb.append("\n\n"); - if (o.o_id == -1) { - sb.append(" Customer has no orders placed.\n"); - } else { - sb.append(" Order-Number: "); - sb.append(o.o_id); - sb.append("\n Entry-Date: "); - sb.append(o.o_entry_d); - sb.append("\n Carrier-Number: "); - sb.append(o.o_carrier_id); - sb.append("\n\n"); - if (orderLines.size() != 0) { - sb.append(" [Supply_W - Item_ID - Qty - Amount - Delivery-Date]\n"); - for (String orderLine : orderLines) { - sb.append(" "); - sb.append(orderLine); - sb.append("\n"); - } - } else { - LOG.trace(" This Order has no Order-Lines.\n"); - } - } - sb.append("+-----------------------------------------------------------------+\n\n"); - LOG.trace(sb.toString()); + sb.append(orderLine); + sb.append("\n"); + } + } else { + LOG.trace(" This Order has no Order-Lines.\n"); } - - + } + sb.append("+-----------------------------------------------------------------+\n\n"); + LOG.trace(sb.toString()); } + } - private Oorder getOrderDetails(Connection conn, int w_id, int d_id, Customer c) throws SQLException { - try (PreparedStatement ordStatGetNewestOrd = this.getPreparedStatement(conn, ordStatGetNewestOrdSQL)) { + private Oorder getOrderDetails(Connection conn, int w_id, int d_id, Customer c) + throws SQLException { + try (PreparedStatement ordStatGetNewestOrd = + this.getPreparedStatement(conn, ordStatGetNewestOrdSQL)) { + // find the newest order for the customer + // retrieve the carrier & order date for the most recent order. - // find the newest order for the customer - // retrieve the carrier & order date for the most recent order. + ordStatGetNewestOrd.setInt(1, w_id); + ordStatGetNewestOrd.setInt(2, d_id); + ordStatGetNewestOrd.setInt(3, c.c_id); - ordStatGetNewestOrd.setInt(1, w_id); - ordStatGetNewestOrd.setInt(2, d_id); - ordStatGetNewestOrd.setInt(3, c.c_id); + try (ResultSet rs = ordStatGetNewestOrd.executeQuery()) { - try (ResultSet rs = ordStatGetNewestOrd.executeQuery()) { + if (!rs.next()) { + String msg = + String.format( + "No order records for CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_ID=%d]", + w_id, d_id, c.c_id); - if (!rs.next()) { - String msg = String.format("No order records for CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_ID=%d]", w_id, d_id, c.c_id); - - throw new RuntimeException(msg); - } - Oorder o = new Oorder(); - o.o_id=rs.getInt("O_ID"); - o.o_carrier_id = rs.getInt("O_CARRIER_ID"); - o.o_entry_d = rs.getTimestamp("O_ENTRY_D"); - return o; - } + throw new RuntimeException(msg); } + Oorder o = new Oorder(); + o.o_id = rs.getInt("O_ID"); + o.o_carrier_id = rs.getInt("O_CARRIER_ID"); + o.o_entry_d = rs.getTimestamp("O_ENTRY_D"); + return o; + } } - - private List getOrderLines(Connection conn, int w_id, int d_id, int o_id, Customer c) throws SQLException { - List orderLines = new ArrayList<>(); - - try (PreparedStatement ordStatGetOrderLines = this.getPreparedStatement(conn, ordStatGetOrderLinesSQL)) { - ordStatGetOrderLines.setInt(1, o_id); - ordStatGetOrderLines.setInt(2, d_id); - ordStatGetOrderLines.setInt(3, w_id); - - try (ResultSet rs = ordStatGetOrderLines.executeQuery()) { - - while (rs.next()) { - StringBuilder sb = new StringBuilder(); - sb.append("["); - sb.append(rs.getLong("OL_SUPPLY_W_ID")); - sb.append(" - "); - sb.append(rs.getLong("OL_I_ID")); - sb.append(" - "); - sb.append(rs.getLong("OL_QUANTITY")); - sb.append(" - "); - sb.append(TPCCUtil.formattedDouble(rs.getDouble("OL_AMOUNT"))); - sb.append(" - "); - if (rs.getTimestamp("OL_DELIVERY_D") != null) { - sb.append(rs.getTimestamp("OL_DELIVERY_D")); - } else { - sb.append("99-99-9999"); - } - sb.append("]"); - orderLines.add(sb.toString()); - } - } - - - if (orderLines.isEmpty()) { - String msg = String.format("Order record had no order line items [C_W_ID=%d, C_D_ID=%d, C_ID=%d, O_ID=%d]", w_id, d_id, c.c_id, o_id); - LOG.trace(msg); - } + } + + private List getOrderLines(Connection conn, int w_id, int d_id, int o_id, Customer c) + throws SQLException { + List orderLines = new ArrayList<>(); + + try (PreparedStatement ordStatGetOrderLines = + this.getPreparedStatement(conn, ordStatGetOrderLinesSQL)) { + ordStatGetOrderLines.setInt(1, o_id); + ordStatGetOrderLines.setInt(2, d_id); + ordStatGetOrderLines.setInt(3, w_id); + + try (ResultSet rs = ordStatGetOrderLines.executeQuery()) { + + while (rs.next()) { + StringBuilder sb = new StringBuilder(); + sb.append("["); + sb.append(rs.getLong("OL_SUPPLY_W_ID")); + sb.append(" - "); + sb.append(rs.getLong("OL_I_ID")); + sb.append(" - "); + sb.append(rs.getLong("OL_QUANTITY")); + sb.append(" - "); + sb.append(TPCCUtil.formattedDouble(rs.getDouble("OL_AMOUNT"))); + sb.append(" - "); + if (rs.getTimestamp("OL_DELIVERY_D") != null) { + sb.append(rs.getTimestamp("OL_DELIVERY_D")); + } else { + sb.append("99-99-9999"); + } + sb.append("]"); + orderLines.add(sb.toString()); } - - return orderLines; + } + + if (orderLines.isEmpty()) { + String msg = + String.format( + "Order record had no order line items [C_W_ID=%d, C_D_ID=%d, C_ID=%d, O_ID=%d]", + w_id, d_id, c.c_id, o_id); + LOG.trace(msg); + } } - // attention duplicated code across trans... ok for now to maintain separate - // prepared statements - public Customer getCustomerById(int c_w_id, int c_d_id, int c_id, Connection conn) throws SQLException { + return orderLines; + } - try (PreparedStatement payGetCust = this.getPreparedStatement(conn, payGetCustSQL)) { + // attention duplicated code across trans... ok for now to maintain separate + // prepared statements + public Customer getCustomerById(int c_w_id, int c_d_id, int c_id, Connection conn) + throws SQLException { - payGetCust.setInt(1, c_w_id); - payGetCust.setInt(2, c_d_id); - payGetCust.setInt(3, c_id); + try (PreparedStatement payGetCust = this.getPreparedStatement(conn, payGetCustSQL)) { - try (ResultSet rs = payGetCust.executeQuery()) { + payGetCust.setInt(1, c_w_id); + payGetCust.setInt(2, c_d_id); + payGetCust.setInt(3, c_id); - if (!rs.next()) { - String msg = String.format("Failed to get CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_ID=%d]", c_w_id, c_d_id, c_id); + try (ResultSet rs = payGetCust.executeQuery()) { - throw new RuntimeException(msg); - } + if (!rs.next()) { + String msg = + String.format( + "Failed to get CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_ID=%d]", c_w_id, c_d_id, c_id); - Customer c = TPCCUtil.newCustomerFromResults(rs); - c.c_id = c_id; - c.c_last = rs.getString("C_LAST"); - return c; - } + throw new RuntimeException(msg); } - } - // attention this code is repeated in other transacitons... ok for now to - // allow for separate statements. - public Customer getCustomerByName(int c_w_id, int c_d_id, String c_last, Connection conn) throws SQLException { - ArrayList customers = new ArrayList<>(); - - try (PreparedStatement customerByName = this.getPreparedStatement(conn, customerByNameSQL)) { - - customerByName.setInt(1, c_w_id); - customerByName.setInt(2, c_d_id); - customerByName.setString(3, c_last); - - try (ResultSet rs = customerByName.executeQuery()) { - while (rs.next()) { - Customer c = TPCCUtil.newCustomerFromResults(rs); - c.c_id = rs.getInt("C_ID"); - c.c_last = c_last; - customers.add(c); - } - } + Customer c = TPCCUtil.newCustomerFromResults(rs); + c.c_id = c_id; + c.c_last = rs.getString("C_LAST"); + return c; + } + } + } + + // attention this code is repeated in other transacitons... ok for now to + // allow for separate statements. + public Customer getCustomerByName(int c_w_id, int c_d_id, String c_last, Connection conn) + throws SQLException { + ArrayList customers = new ArrayList<>(); + + try (PreparedStatement customerByName = this.getPreparedStatement(conn, customerByNameSQL)) { + + customerByName.setInt(1, c_w_id); + customerByName.setInt(2, c_d_id); + customerByName.setString(3, c_last); + + try (ResultSet rs = customerByName.executeQuery()) { + while (rs.next()) { + Customer c = TPCCUtil.newCustomerFromResults(rs); + c.c_id = rs.getInt("C_ID"); + c.c_last = c_last; + customers.add(c); } + } + } - if (customers.size() == 0) { - String msg = String.format("Failed to get CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_LAST=%s]", c_w_id, c_d_id, c_last); - - throw new RuntimeException(msg); - } + if (customers.size() == 0) { + String msg = + String.format( + "Failed to get CUSTOMER [C_W_ID=%d, C_D_ID=%d, C_LAST=%s]", c_w_id, c_d_id, c_last); - // TPC-C 2.5.2.2: Position n / 2 rounded up to the next integer, but - // that counts starting from 1. - int index = customers.size() / 2; - if (customers.size() % 2 == 0) { - index -= 1; - } - return customers.get(index); + throw new RuntimeException(msg); } - + // TPC-C 2.5.2.2: Position n / 2 rounded up to the next integer, but + // that counts starting from 1. + int index = customers.size() / 2; + if (customers.size() % 2 == 0) { + index -= 1; + } + return customers.get(index); + } } - - - diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java index 1531a87eb..7f3ea5c88 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/Payment.java @@ -25,50 +25,58 @@ import com.oltpbenchmark.benchmarks.tpcc.pojo.Customer; import com.oltpbenchmark.benchmarks.tpcc.pojo.District; import com.oltpbenchmark.benchmarks.tpcc.pojo.Warehouse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.math.BigDecimal; import java.sql.*; import java.util.ArrayList; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Payment extends TPCCProcedure { - private static final Logger LOG = LoggerFactory.getLogger(Payment.class); + private static final Logger LOG = LoggerFactory.getLogger(Payment.class); - public SQLStmt payUpdateWhseSQL = new SQLStmt( - """ + public SQLStmt payUpdateWhseSQL = + new SQLStmt( + """ UPDATE %s SET W_YTD = W_YTD + ? WHERE W_ID = ? - """.formatted(TPCCConstants.TABLENAME_WAREHOUSE)); - - public SQLStmt payGetWhseSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_WAREHOUSE)); + + public SQLStmt payGetWhseSQL = + new SQLStmt( + """ SELECT W_STREET_1, W_STREET_2, W_CITY, W_STATE, W_ZIP, W_NAME FROM %s WHERE W_ID = ? - """.formatted(TPCCConstants.TABLENAME_WAREHOUSE)); - - public SQLStmt payUpdateDistSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_WAREHOUSE)); + + public SQLStmt payUpdateDistSQL = + new SQLStmt( + """ UPDATE %s SET D_YTD = D_YTD + ? WHERE D_W_ID = ? AND D_ID = ? - """.formatted(TPCCConstants.TABLENAME_DISTRICT)); - - public SQLStmt payGetDistSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_DISTRICT)); + + public SQLStmt payGetDistSQL = + new SQLStmt( + """ SELECT D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, D_NAME FROM %s WHERE D_W_ID = ? AND D_ID = ? - """.formatted(TPCCConstants.TABLENAME_DISTRICT)); - - public SQLStmt payGetCustSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_DISTRICT)); + + public SQLStmt payGetCustSQL = + new SQLStmt( + """ SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE @@ -76,19 +84,23 @@ public class Payment extends TPCCProcedure { WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public SQLStmt payGetCustCdataSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public SQLStmt payGetCustCdataSQL = + new SQLStmt( + """ SELECT C_DATA FROM %s WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public SQLStmt payUpdateCustBalCdataSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public SQLStmt payUpdateCustBalCdataSQL = + new SQLStmt( + """ UPDATE %s SET C_BALANCE = ?, C_YTD_PAYMENT = ?, @@ -97,10 +109,12 @@ public class Payment extends TPCCProcedure { WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public SQLStmt payUpdateCustBalSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public SQLStmt payUpdateCustBalSQL = + new SQLStmt( + """ UPDATE %s SET C_BALANCE = ?, C_YTD_PAYMENT = ?, @@ -108,17 +122,21 @@ public class Payment extends TPCCProcedure { WHERE C_W_ID = ? AND C_D_ID = ? AND C_ID = ? - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); - - public SQLStmt payInsertHistSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); + + public SQLStmt payInsertHistSQL = + new SQLStmt( + """ INSERT INTO %s (H_C_D_ID, H_C_W_ID, H_C_ID, H_D_ID, H_W_ID, H_DATE, H_AMOUNT, H_DATA) VALUES (?,?,?,?,?,?,?,?) - """.formatted(TPCCConstants.TABLENAME_HISTORY)); - - public SQLStmt customerByNameSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_HISTORY)); + + public SQLStmt customerByNameSQL = + new SQLStmt( + """ SELECT C_FIRST, C_MIDDLE, C_ID, C_STREET_1, C_STREET_2, C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT, C_CREDIT_LIM, C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, C_PAYMENT_CNT, C_SINCE @@ -127,384 +145,474 @@ public class Payment extends TPCCProcedure { AND C_D_ID = ? AND C_LAST = ? ORDER BY C_FIRST - """.formatted(TPCCConstants.TABLENAME_CUSTOMER)); + """ + .formatted(TPCCConstants.TABLENAME_CUSTOMER)); - public void run(Connection conn, Random gen, int w_id, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker worker) throws SQLException { + public void run( + Connection conn, + Random gen, + int w_id, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker worker) + throws SQLException { - int districtID = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); + int districtID = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); - float paymentAmount = (float) (TPCCUtil.randomNumber(100, 500000, gen) / 100.0); + float paymentAmount = (float) (TPCCUtil.randomNumber(100, 500000, gen) / 100.0); - updateWarehouse(conn, w_id, paymentAmount); + updateWarehouse(conn, w_id, paymentAmount); - Warehouse w = getWarehouse(conn, w_id); + Warehouse w = getWarehouse(conn, w_id); - updateDistrict(conn, w_id, districtID, paymentAmount); + updateDistrict(conn, w_id, districtID, paymentAmount); - District d = getDistrict(conn, w_id, districtID); + District d = getDistrict(conn, w_id, districtID); - int x = TPCCUtil.randomNumber(1, 100, gen); + int x = TPCCUtil.randomNumber(1, 100, gen); - int customerDistrictID = getCustomerDistrictId(gen, districtID, x); - int customerWarehouseID = getCustomerWarehouseID(gen, w_id, numWarehouses, x); + int customerDistrictID = getCustomerDistrictId(gen, districtID, x); + int customerWarehouseID = getCustomerWarehouseID(gen, w_id, numWarehouses, x); - Customer c = getCustomer(conn, gen, customerDistrictID, customerWarehouseID, paymentAmount); + Customer c = getCustomer(conn, gen, customerDistrictID, customerWarehouseID, paymentAmount); - if (c.c_credit.equals("BC")) { - // bad credit - c.c_data = getCData(conn, w_id, districtID, customerDistrictID, customerWarehouseID, paymentAmount, c); + if (c.c_credit.equals("BC")) { + // bad credit + c.c_data = + getCData( + conn, w_id, districtID, customerDistrictID, customerWarehouseID, paymentAmount, c); - updateBalanceCData(conn, customerDistrictID, customerWarehouseID, c); + updateBalanceCData(conn, customerDistrictID, customerWarehouseID, c); - } else { - // GoodCredit + } else { + // GoodCredit - updateBalance(conn, customerDistrictID, customerWarehouseID, c); + updateBalance(conn, customerDistrictID, customerWarehouseID, c); + } + insertHistory( + conn, + w_id, + districtID, + customerDistrictID, + customerWarehouseID, + paymentAmount, + w.w_name, + d.d_name, + c); + + if (LOG.isTraceEnabled()) { + StringBuilder terminalMessage = new StringBuilder(); + terminalMessage.append( + "\n+---------------------------- PAYMENT ----------------------------+"); + terminalMessage.append("\n Date: ").append(TPCCUtil.getCurrentTime()); + terminalMessage.append("\n\n Warehouse: "); + terminalMessage.append(w_id); + terminalMessage.append("\n Street: "); + terminalMessage.append(w.w_street_1); + terminalMessage.append("\n Street: "); + terminalMessage.append(w.w_street_2); + terminalMessage.append("\n City: "); + terminalMessage.append(w.w_city); + terminalMessage.append(" State: "); + terminalMessage.append(w.w_state); + terminalMessage.append(" Zip: "); + terminalMessage.append(w.w_zip); + terminalMessage.append("\n\n District: "); + terminalMessage.append(districtID); + terminalMessage.append("\n Street: "); + terminalMessage.append(d.d_street_1); + terminalMessage.append("\n Street: "); + terminalMessage.append(d.d_street_2); + terminalMessage.append("\n City: "); + terminalMessage.append(d.d_city); + terminalMessage.append(" State: "); + terminalMessage.append(d.d_state); + terminalMessage.append(" Zip: "); + terminalMessage.append(d.d_zip); + terminalMessage.append("\n\n Customer: "); + terminalMessage.append(c.c_id); + terminalMessage.append("\n Name: "); + terminalMessage.append(c.c_first); + terminalMessage.append(" "); + terminalMessage.append(c.c_middle); + terminalMessage.append(" "); + terminalMessage.append(c.c_last); + terminalMessage.append("\n Street: "); + terminalMessage.append(c.c_street_1); + terminalMessage.append("\n Street: "); + terminalMessage.append(c.c_street_2); + terminalMessage.append("\n City: "); + terminalMessage.append(c.c_city); + terminalMessage.append(" State: "); + terminalMessage.append(c.c_state); + terminalMessage.append(" Zip: "); + terminalMessage.append(c.c_zip); + terminalMessage.append("\n Since: "); + if (c.c_since != null) { + terminalMessage.append(c.c_since.toString()); + } else { + terminalMessage.append(""); + } + terminalMessage.append("\n Credit: "); + terminalMessage.append(c.c_credit); + terminalMessage.append("\n %Disc: "); + terminalMessage.append(c.c_discount); + terminalMessage.append("\n Phone: "); + terminalMessage.append(c.c_phone); + terminalMessage.append("\n\n Amount Paid: "); + terminalMessage.append(paymentAmount); + terminalMessage.append("\n Credit Limit: "); + terminalMessage.append(c.c_credit_lim); + terminalMessage.append("\n New Cust-Balance: "); + terminalMessage.append(c.c_balance); + if (c.c_credit.equals("BC")) { + if (c.c_data.length() > 50) { + terminalMessage.append("\n\n Cust-Data: ").append(c.c_data.substring(0, 50)); + int data_chunks = c.c_data.length() > 200 ? 4 : c.c_data.length() / 50; + for (int n = 1; n < data_chunks; n++) { + terminalMessage + .append("\n ") + .append(c.c_data.substring(n * 50, (n + 1) * 50)); + } + } else { + terminalMessage.append("\n\n Cust-Data: ").append(c.c_data); } + } + terminalMessage.append( + "\n+-----------------------------------------------------------------+\n\n"); - insertHistory(conn, w_id, districtID, customerDistrictID, customerWarehouseID, paymentAmount, w.w_name, d.d_name, c); + LOG.trace(terminalMessage.toString()); + } + } + + private int getCustomerWarehouseID(Random gen, int w_id, int numWarehouses, int x) { + int customerWarehouseID; + if (x <= 85) { + customerWarehouseID = w_id; + } else { + do { + customerWarehouseID = TPCCUtil.randomNumber(1, numWarehouses, gen); + } while (customerWarehouseID == w_id && numWarehouses > 1); + } + return customerWarehouseID; + } + + private int getCustomerDistrictId(Random gen, int districtID, int x) { + if (x <= 85) { + return districtID; + } else { + return TPCCUtil.randomNumber(1, TPCCConfig.configDistPerWhse, gen); + } + } + + private void updateWarehouse(Connection conn, int w_id, float paymentAmount) throws SQLException { + try (PreparedStatement payUpdateWhse = this.getPreparedStatement(conn, payUpdateWhseSQL)) { + payUpdateWhse.setBigDecimal(1, BigDecimal.valueOf(paymentAmount)); + payUpdateWhse.setInt(2, w_id); + // MySQL reports deadlocks due to lock upgrades: + // t1: read w_id = x; t2: update w_id = x; t1 update w_id = x + int result = payUpdateWhse.executeUpdate(); + if (result == 0) { + throw new RuntimeException("W_ID=" + w_id + " not found!"); + } + } + } - if (LOG.isTraceEnabled()) { - StringBuilder terminalMessage = new StringBuilder(); - terminalMessage.append("\n+---------------------------- PAYMENT ----------------------------+"); - terminalMessage.append("\n Date: ").append(TPCCUtil.getCurrentTime()); - terminalMessage.append("\n\n Warehouse: "); - terminalMessage.append(w_id); - terminalMessage.append("\n Street: "); - terminalMessage.append(w.w_street_1); - terminalMessage.append("\n Street: "); - terminalMessage.append(w.w_street_2); - terminalMessage.append("\n City: "); - terminalMessage.append(w.w_city); - terminalMessage.append(" State: "); - terminalMessage.append(w.w_state); - terminalMessage.append(" Zip: "); - terminalMessage.append(w.w_zip); - terminalMessage.append("\n\n District: "); - terminalMessage.append(districtID); - terminalMessage.append("\n Street: "); - terminalMessage.append(d.d_street_1); - terminalMessage.append("\n Street: "); - terminalMessage.append(d.d_street_2); - terminalMessage.append("\n City: "); - terminalMessage.append(d.d_city); - terminalMessage.append(" State: "); - terminalMessage.append(d.d_state); - terminalMessage.append(" Zip: "); - terminalMessage.append(d.d_zip); - terminalMessage.append("\n\n Customer: "); - terminalMessage.append(c.c_id); - terminalMessage.append("\n Name: "); - terminalMessage.append(c.c_first); - terminalMessage.append(" "); - terminalMessage.append(c.c_middle); - terminalMessage.append(" "); - terminalMessage.append(c.c_last); - terminalMessage.append("\n Street: "); - terminalMessage.append(c.c_street_1); - terminalMessage.append("\n Street: "); - terminalMessage.append(c.c_street_2); - terminalMessage.append("\n City: "); - terminalMessage.append(c.c_city); - terminalMessage.append(" State: "); - terminalMessage.append(c.c_state); - terminalMessage.append(" Zip: "); - terminalMessage.append(c.c_zip); - terminalMessage.append("\n Since: "); - if (c.c_since != null) { - terminalMessage.append(c.c_since.toString()); - } else { - terminalMessage.append(""); - } - terminalMessage.append("\n Credit: "); - terminalMessage.append(c.c_credit); - terminalMessage.append("\n %Disc: "); - terminalMessage.append(c.c_discount); - terminalMessage.append("\n Phone: "); - terminalMessage.append(c.c_phone); - terminalMessage.append("\n\n Amount Paid: "); - terminalMessage.append(paymentAmount); - terminalMessage.append("\n Credit Limit: "); - terminalMessage.append(c.c_credit_lim); - terminalMessage.append("\n New Cust-Balance: "); - terminalMessage.append(c.c_balance); - if (c.c_credit.equals("BC")) { - if (c.c_data.length() > 50) { - terminalMessage.append("\n\n Cust-Data: ").append(c.c_data.substring(0, 50)); - int data_chunks = c.c_data.length() > 200 ? 4 : c.c_data.length() / 50; - for (int n = 1; n < data_chunks; n++) { - terminalMessage.append("\n ").append(c.c_data.substring(n * 50, (n + 1) * 50)); - } - } else { - terminalMessage.append("\n\n Cust-Data: ").append(c.c_data); - } - } - terminalMessage.append("\n+-----------------------------------------------------------------+\n\n"); - - LOG.trace(terminalMessage.toString()); + private Warehouse getWarehouse(Connection conn, int w_id) throws SQLException { + try (PreparedStatement payGetWhse = this.getPreparedStatement(conn, payGetWhseSQL)) { + payGetWhse.setInt(1, w_id); + try (ResultSet rs = payGetWhse.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("W_ID=" + w_id + " not found!"); } - } + Warehouse w = new Warehouse(); + w.w_street_1 = rs.getString("W_STREET_1"); + w.w_street_2 = rs.getString("W_STREET_2"); + w.w_city = rs.getString("W_CITY"); + w.w_state = rs.getString("W_STATE"); + w.w_zip = rs.getString("W_ZIP"); + w.w_name = rs.getString("W_NAME"); - private int getCustomerWarehouseID(Random gen, int w_id, int numWarehouses, int x) { - int customerWarehouseID; - if (x <= 85) { - customerWarehouseID = w_id; - } else { - do { - customerWarehouseID = TPCCUtil.randomNumber(1, numWarehouses, gen); - } - while (customerWarehouseID == w_id && numWarehouses > 1); - } - return customerWarehouseID; + return w; + } + } + } + + private Customer getCustomer( + Connection conn, + Random gen, + int customerDistrictID, + int customerWarehouseID, + float paymentAmount) + throws SQLException { + int y = TPCCUtil.randomNumber(1, 100, gen); + + Customer c; + + if (y <= 60) { + // 60% lookups by last name + c = + getCustomerByName( + customerWarehouseID, + customerDistrictID, + TPCCUtil.getNonUniformRandomLastNameForRun(gen), + conn); + } else { + // 40% lookups by customer ID + c = + getCustomerById( + customerWarehouseID, customerDistrictID, TPCCUtil.getCustomerID(gen), conn); } - private int getCustomerDistrictId(Random gen, int districtID, int x) { - if (x <= 85) { - return districtID; - } else { - return TPCCUtil.randomNumber(1, TPCCConfig.configDistPerWhse, gen); - } + c.c_balance -= paymentAmount; + c.c_ytd_payment += paymentAmount; + c.c_payment_cnt += 1; + return c; + } - } + private void updateDistrict(Connection conn, int w_id, int districtID, float paymentAmount) + throws SQLException { + try (PreparedStatement payUpdateDist = this.getPreparedStatement(conn, payUpdateDistSQL)) { + payUpdateDist.setBigDecimal(1, BigDecimal.valueOf(paymentAmount)); + payUpdateDist.setInt(2, w_id); + payUpdateDist.setInt(3, districtID); - private void updateWarehouse(Connection conn, int w_id, float paymentAmount) throws SQLException { - try (PreparedStatement payUpdateWhse = this.getPreparedStatement(conn, payUpdateWhseSQL)) { - payUpdateWhse.setBigDecimal(1, BigDecimal.valueOf(paymentAmount)); - payUpdateWhse.setInt(2, w_id); - // MySQL reports deadlocks due to lock upgrades: - // t1: read w_id = x; t2: update w_id = x; t1 update w_id = x - int result = payUpdateWhse.executeUpdate(); - if (result == 0) { - throw new RuntimeException("W_ID=" + w_id + " not found!"); - } - } - } + int result = payUpdateDist.executeUpdate(); - private Warehouse getWarehouse(Connection conn, int w_id) throws SQLException { - try (PreparedStatement payGetWhse = this.getPreparedStatement(conn, payGetWhseSQL)) { - payGetWhse.setInt(1, w_id); - - try (ResultSet rs = payGetWhse.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("W_ID=" + w_id + " not found!"); - } - - Warehouse w = new Warehouse(); - w.w_street_1 = rs.getString("W_STREET_1"); - w.w_street_2 = rs.getString("W_STREET_2"); - w.w_city = rs.getString("W_CITY"); - w.w_state = rs.getString("W_STATE"); - w.w_zip = rs.getString("W_ZIP"); - w.w_name = rs.getString("W_NAME"); - - return w; - } - } + if (result == 0) { + throw new RuntimeException("D_ID=" + districtID + " D_W_ID=" + w_id + " not found!"); + } } + } - private Customer getCustomer(Connection conn, Random gen, int customerDistrictID, int customerWarehouseID, float paymentAmount) throws SQLException { - int y = TPCCUtil.randomNumber(1, 100, gen); - - Customer c; + private District getDistrict(Connection conn, int w_id, int districtID) throws SQLException { + try (PreparedStatement payGetDist = this.getPreparedStatement(conn, payGetDistSQL)) { + payGetDist.setInt(1, w_id); + payGetDist.setInt(2, districtID); - if (y <= 60) { - // 60% lookups by last name - c = getCustomerByName(customerWarehouseID, customerDistrictID, TPCCUtil.getNonUniformRandomLastNameForRun(gen), conn); - } else { - // 40% lookups by customer ID - c = getCustomerById(customerWarehouseID, customerDistrictID, TPCCUtil.getCustomerID(gen), conn); + try (ResultSet rs = payGetDist.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException("D_ID=" + districtID + " D_W_ID=" + w_id + " not found!"); } - c.c_balance -= paymentAmount; - c.c_ytd_payment += paymentAmount; - c.c_payment_cnt += 1; + District d = new District(); + d.d_street_1 = rs.getString("D_STREET_1"); + d.d_street_2 = rs.getString("D_STREET_2"); + d.d_city = rs.getString("D_CITY"); + d.d_state = rs.getString("D_STATE"); + d.d_zip = rs.getString("D_ZIP"); + d.d_name = rs.getString("D_NAME"); - return c; + return d; + } } - - private void updateDistrict(Connection conn, int w_id, int districtID, float paymentAmount) throws SQLException { - try (PreparedStatement payUpdateDist = this.getPreparedStatement(conn, payUpdateDistSQL)) { - payUpdateDist.setBigDecimal(1, BigDecimal.valueOf(paymentAmount)); - payUpdateDist.setInt(2, w_id); - payUpdateDist.setInt(3, districtID); - - int result = payUpdateDist.executeUpdate(); - - if (result == 0) { - throw new RuntimeException("D_ID=" + districtID + " D_W_ID=" + w_id + " not found!"); - } + } + + private String getCData( + Connection conn, + int w_id, + int districtID, + int customerDistrictID, + int customerWarehouseID, + float paymentAmount, + Customer c) + throws SQLException { + + try (PreparedStatement payGetCustCdata = this.getPreparedStatement(conn, payGetCustCdataSQL)) { + String c_data; + payGetCustCdata.setInt(1, customerWarehouseID); + payGetCustCdata.setInt(2, customerDistrictID); + payGetCustCdata.setInt(3, c.c_id); + try (ResultSet rs = payGetCustCdata.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException( + "C_ID=" + + c.c_id + + " C_W_ID=" + + customerWarehouseID + + " C_D_ID=" + + customerDistrictID + + " not found!"); } + c_data = rs.getString("C_DATA"); + } + + c_data = + c.c_id + + " " + + customerDistrictID + + " " + + customerWarehouseID + + " " + + districtID + + " " + + w_id + + " " + + paymentAmount + + " | " + + c_data; + if (c_data.length() > 500) { + c_data = c_data.substring(0, 500); + } + + return c_data; } - - private District getDistrict(Connection conn, int w_id, int districtID) throws SQLException { - try (PreparedStatement payGetDist = this.getPreparedStatement(conn, payGetDistSQL)) { - payGetDist.setInt(1, w_id); - payGetDist.setInt(2, districtID); - - try (ResultSet rs = payGetDist.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("D_ID=" + districtID + " D_W_ID=" + w_id + " not found!"); - } - - District d = new District(); - d.d_street_1 = rs.getString("D_STREET_1"); - d.d_street_2 = rs.getString("D_STREET_2"); - d.d_city = rs.getString("D_CITY"); - d.d_state = rs.getString("D_STATE"); - d.d_zip = rs.getString("D_ZIP"); - d.d_name = rs.getString("D_NAME"); - - return d; - } - } + } + + private void updateBalanceCData( + Connection conn, int customerDistrictID, int customerWarehouseID, Customer c) + throws SQLException { + try (PreparedStatement payUpdateCustBalCdata = + this.getPreparedStatement(conn, payUpdateCustBalCdataSQL)) { + payUpdateCustBalCdata.setDouble(1, c.c_balance); + payUpdateCustBalCdata.setDouble(2, c.c_ytd_payment); + payUpdateCustBalCdata.setInt(3, c.c_payment_cnt); + payUpdateCustBalCdata.setString(4, c.c_data); + payUpdateCustBalCdata.setInt(5, customerWarehouseID); + payUpdateCustBalCdata.setInt(6, customerDistrictID); + payUpdateCustBalCdata.setInt(7, c.c_id); + + int result = payUpdateCustBalCdata.executeUpdate(); + + if (result == 0) { + throw new RuntimeException( + "Error in PYMNT Txn updating Customer C_ID=" + + c.c_id + + " C_W_ID=" + + customerWarehouseID + + " C_D_ID=" + + customerDistrictID); + } } - - private String getCData(Connection conn, int w_id, int districtID, int customerDistrictID, int customerWarehouseID, float paymentAmount, Customer c) throws SQLException { - - try (PreparedStatement payGetCustCdata = this.getPreparedStatement(conn, payGetCustCdataSQL)) { - String c_data; - payGetCustCdata.setInt(1, customerWarehouseID); - payGetCustCdata.setInt(2, customerDistrictID); - payGetCustCdata.setInt(3, c.c_id); - try (ResultSet rs = payGetCustCdata.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("C_ID=" + c.c_id + " C_W_ID=" + customerWarehouseID + " C_D_ID=" + customerDistrictID + " not found!"); - } - c_data = rs.getString("C_DATA"); - } - - c_data = c.c_id + " " + customerDistrictID + " " + customerWarehouseID + " " + districtID + " " + w_id + " " + paymentAmount + " | " + c_data; - if (c_data.length() > 500) { - c_data = c_data.substring(0, 500); - } - - return c_data; - } - + } + + private void updateBalance( + Connection conn, int customerDistrictID, int customerWarehouseID, Customer c) + throws SQLException { + + try (PreparedStatement payUpdateCustBal = + this.getPreparedStatement(conn, payUpdateCustBalSQL)) { + payUpdateCustBal.setDouble(1, c.c_balance); + payUpdateCustBal.setDouble(2, c.c_ytd_payment); + payUpdateCustBal.setInt(3, c.c_payment_cnt); + payUpdateCustBal.setInt(4, customerWarehouseID); + payUpdateCustBal.setInt(5, customerDistrictID); + payUpdateCustBal.setInt(6, c.c_id); + + int result = payUpdateCustBal.executeUpdate(); + + if (result == 0) { + throw new RuntimeException( + "C_ID=" + + c.c_id + + " C_W_ID=" + + customerWarehouseID + + " C_D_ID=" + + customerDistrictID + + " not found!"); + } } - - private void updateBalanceCData(Connection conn, int customerDistrictID, int customerWarehouseID, Customer c) throws SQLException { - try (PreparedStatement payUpdateCustBalCdata = this.getPreparedStatement(conn, payUpdateCustBalCdataSQL)) { - payUpdateCustBalCdata.setDouble(1, c.c_balance); - payUpdateCustBalCdata.setDouble(2, c.c_ytd_payment); - payUpdateCustBalCdata.setInt(3, c.c_payment_cnt); - payUpdateCustBalCdata.setString(4, c.c_data); - payUpdateCustBalCdata.setInt(5, customerWarehouseID); - payUpdateCustBalCdata.setInt(6, customerDistrictID); - payUpdateCustBalCdata.setInt(7, c.c_id); - - int result = payUpdateCustBalCdata.executeUpdate(); - - if (result == 0) { - throw new RuntimeException("Error in PYMNT Txn updating Customer C_ID=" + c.c_id + " C_W_ID=" + customerWarehouseID + " C_D_ID=" + customerDistrictID); - } - } + } + + private void insertHistory( + Connection conn, + int w_id, + int districtID, + int customerDistrictID, + int customerWarehouseID, + float paymentAmount, + String w_name, + String d_name, + Customer c) + throws SQLException { + if (w_name.length() > 10) { + w_name = w_name.substring(0, 10); } - - private void updateBalance(Connection conn, int customerDistrictID, int customerWarehouseID, Customer c) throws SQLException { - - try (PreparedStatement payUpdateCustBal = this.getPreparedStatement(conn, payUpdateCustBalSQL)) { - payUpdateCustBal.setDouble(1, c.c_balance); - payUpdateCustBal.setDouble(2, c.c_ytd_payment); - payUpdateCustBal.setInt(3, c.c_payment_cnt); - payUpdateCustBal.setInt(4, customerWarehouseID); - payUpdateCustBal.setInt(5, customerDistrictID); - payUpdateCustBal.setInt(6, c.c_id); - - int result = payUpdateCustBal.executeUpdate(); - - if (result == 0) { - throw new RuntimeException("C_ID=" + c.c_id + " C_W_ID=" + customerWarehouseID + " C_D_ID=" + customerDistrictID + " not found!"); - } - } + if (d_name.length() > 10) { + d_name = d_name.substring(0, 10); } - - private void insertHistory(Connection conn, int w_id, int districtID, int customerDistrictID, int customerWarehouseID, float paymentAmount, String w_name, String d_name, Customer c) throws SQLException { - if (w_name.length() > 10) { - w_name = w_name.substring(0, 10); - } - if (d_name.length() > 10) { - d_name = d_name.substring(0, 10); - } - String h_data = w_name + " " + d_name; - - try (PreparedStatement payInsertHist = this.getPreparedStatement(conn, payInsertHistSQL)) { - payInsertHist.setInt(1, customerDistrictID); - payInsertHist.setInt(2, customerWarehouseID); - payInsertHist.setInt(3, c.c_id); - payInsertHist.setInt(4, districtID); - payInsertHist.setInt(5, w_id); - payInsertHist.setTimestamp(6, new Timestamp(System.currentTimeMillis())); - payInsertHist.setDouble(7, paymentAmount); - payInsertHist.setString(8, h_data); - payInsertHist.executeUpdate(); - } + String h_data = w_name + " " + d_name; + + try (PreparedStatement payInsertHist = this.getPreparedStatement(conn, payInsertHistSQL)) { + payInsertHist.setInt(1, customerDistrictID); + payInsertHist.setInt(2, customerWarehouseID); + payInsertHist.setInt(3, c.c_id); + payInsertHist.setInt(4, districtID); + payInsertHist.setInt(5, w_id); + payInsertHist.setTimestamp(6, new Timestamp(System.currentTimeMillis())); + payInsertHist.setDouble(7, paymentAmount); + payInsertHist.setString(8, h_data); + payInsertHist.executeUpdate(); } + } - // attention duplicated code across trans... ok for now to maintain separate - // prepared statements - public Customer getCustomerById(int c_w_id, int c_d_id, int c_id, Connection conn) throws SQLException { - - try (PreparedStatement payGetCust = this.getPreparedStatement(conn, payGetCustSQL)) { + // attention duplicated code across trans... ok for now to maintain separate + // prepared statements + public Customer getCustomerById(int c_w_id, int c_d_id, int c_id, Connection conn) + throws SQLException { - payGetCust.setInt(1, c_w_id); - payGetCust.setInt(2, c_d_id); - payGetCust.setInt(3, c_id); + try (PreparedStatement payGetCust = this.getPreparedStatement(conn, payGetCustSQL)) { - try (ResultSet rs = payGetCust.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("C_ID=" + c_id + " C_D_ID=" + c_d_id + " C_W_ID=" + c_w_id + " not found!"); - } + payGetCust.setInt(1, c_w_id); + payGetCust.setInt(2, c_d_id); + payGetCust.setInt(3, c_id); - Customer c = TPCCUtil.newCustomerFromResults(rs); - c.c_id = c_id; - c.c_last = rs.getString("C_LAST"); - return c; - } + try (ResultSet rs = payGetCust.executeQuery()) { + if (!rs.next()) { + throw new RuntimeException( + "C_ID=" + c_id + " C_D_ID=" + c_d_id + " C_W_ID=" + c_w_id + " not found!"); } + + Customer c = TPCCUtil.newCustomerFromResults(rs); + c.c_id = c_id; + c.c_last = rs.getString("C_LAST"); + return c; + } } + } - // attention this code is repeated in other transacitons... ok for now to - // allow for separate statements. - public Customer getCustomerByName(int c_w_id, int c_d_id, String customerLastName, Connection conn) throws SQLException { - ArrayList customers = new ArrayList<>(); - - try (PreparedStatement customerByName = this.getPreparedStatement(conn, customerByNameSQL)) { - - customerByName.setInt(1, c_w_id); - customerByName.setInt(2, c_d_id); - customerByName.setString(3, customerLastName); - try (ResultSet rs = customerByName.executeQuery()) { - if (LOG.isTraceEnabled()) { - LOG.trace("C_LAST={} C_D_ID={} C_W_ID={}", customerLastName, c_d_id, c_w_id); - } - - while (rs.next()) { - Customer c = TPCCUtil.newCustomerFromResults(rs); - c.c_id = rs.getInt("C_ID"); - c.c_last = customerLastName; - customers.add(c); - } - } - } + // attention this code is repeated in other transacitons... ok for now to + // allow for separate statements. + public Customer getCustomerByName( + int c_w_id, int c_d_id, String customerLastName, Connection conn) throws SQLException { + ArrayList customers = new ArrayList<>(); - if (customers.size() == 0) { - throw new RuntimeException("C_LAST=" + customerLastName + " C_D_ID=" + c_d_id + " C_W_ID=" + c_w_id + " not found!"); + try (PreparedStatement customerByName = this.getPreparedStatement(conn, customerByNameSQL)) { + + customerByName.setInt(1, c_w_id); + customerByName.setInt(2, c_d_id); + customerByName.setString(3, customerLastName); + try (ResultSet rs = customerByName.executeQuery()) { + if (LOG.isTraceEnabled()) { + LOG.trace("C_LAST={} C_D_ID={} C_W_ID={}", customerLastName, c_d_id, c_w_id); } - // TPC-C 2.5.2.2: Position n / 2 rounded up to the next integer, but - // that - // counts starting from 1. - int index = customers.size() / 2; - if (customers.size() % 2 == 0) { - index -= 1; + while (rs.next()) { + Customer c = TPCCUtil.newCustomerFromResults(rs); + c.c_id = rs.getInt("C_ID"); + c.c_last = customerLastName; + customers.add(c); } - return customers.get(index); + } } + if (customers.size() == 0) { + throw new RuntimeException( + "C_LAST=" + customerLastName + " C_D_ID=" + c_d_id + " C_W_ID=" + c_w_id + " not found!"); + } + // TPC-C 2.5.2.2: Position n / 2 rounded up to the next integer, but + // that + // counts starting from 1. + int index = customers.size() / 2; + if (customers.size() % 2 == 0) { + index -= 1; + } + return customers.get(index); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java index 307014450..184ee7379 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/StockLevel.java @@ -21,29 +21,31 @@ import com.oltpbenchmark.benchmarks.tpcc.TPCCConstants; import com.oltpbenchmark.benchmarks.tpcc.TPCCUtil; import com.oltpbenchmark.benchmarks.tpcc.TPCCWorker; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Random; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class StockLevel extends TPCCProcedure { - private static final Logger LOG = LoggerFactory.getLogger(StockLevel.class); + private static final Logger LOG = LoggerFactory.getLogger(StockLevel.class); - public SQLStmt stockGetDistOrderIdSQL = new SQLStmt( - """ + public SQLStmt stockGetDistOrderIdSQL = + new SQLStmt( + """ SELECT D_NEXT_O_ID FROM %s WHERE D_W_ID = ? AND D_ID = ? - """.formatted(TPCCConstants.TABLENAME_DISTRICT)); - - public SQLStmt stockGetCountStockSQL = new SQLStmt( """ + .formatted(TPCCConstants.TABLENAME_DISTRICT)); + + public SQLStmt stockGetCountStockSQL = + new SQLStmt( + """ SELECT COUNT(DISTINCT (S_I_ID)) AS STOCK_COUNT FROM %s, %s WHERE OL_W_ID = ? @@ -53,68 +55,81 @@ SELECT COUNT(DISTINCT (S_I_ID)) AS STOCK_COUNT AND S_W_ID = ? AND S_I_ID = OL_I_ID AND S_QUANTITY < ? - """.formatted(TPCCConstants.TABLENAME_ORDERLINE, TPCCConstants.TABLENAME_STOCK)); - - public void run(Connection conn, Random gen, int w_id, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker w) throws SQLException { - - int threshold = TPCCUtil.randomNumber(10, 20, gen); - int d_id = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); - - int o_id = getOrderId(conn, w_id, d_id); - - int stock_count = getStockCount(conn, w_id, threshold, d_id, o_id); - - if (LOG.isTraceEnabled()) { - String terminalMessage = "\n+-------------------------- STOCK-LEVEL --------------------------+" + - "\n Warehouse: " + - w_id + - "\n District: " + - d_id + - "\n\n Stock Level Threshold: " + - threshold + - "\n Low Stock Count: " + - stock_count + - "\n+-----------------------------------------------------------------+\n\n"; - LOG.trace(terminalMessage); - } - - + """ + .formatted(TPCCConstants.TABLENAME_ORDERLINE, TPCCConstants.TABLENAME_STOCK)); + + public void run( + Connection conn, + Random gen, + int w_id, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker w) + throws SQLException { + + int threshold = TPCCUtil.randomNumber(10, 20, gen); + int d_id = TPCCUtil.randomNumber(terminalDistrictLowerID, terminalDistrictUpperID, gen); + + int o_id = getOrderId(conn, w_id, d_id); + + int stock_count = getStockCount(conn, w_id, threshold, d_id, o_id); + + if (LOG.isTraceEnabled()) { + String terminalMessage = + "\n+-------------------------- STOCK-LEVEL --------------------------+" + + "\n Warehouse: " + + w_id + + "\n District: " + + d_id + + "\n\n Stock Level Threshold: " + + threshold + + "\n Low Stock Count: " + + stock_count + + "\n+-----------------------------------------------------------------+\n\n"; + LOG.trace(terminalMessage); } + } - private int getOrderId(Connection conn, int w_id, int d_id) throws SQLException { - try (PreparedStatement stockGetDistOrderId = this.getPreparedStatement(conn, stockGetDistOrderIdSQL)) { - stockGetDistOrderId.setInt(1, w_id); - stockGetDistOrderId.setInt(2, d_id); + private int getOrderId(Connection conn, int w_id, int d_id) throws SQLException { + try (PreparedStatement stockGetDistOrderId = + this.getPreparedStatement(conn, stockGetDistOrderIdSQL)) { + stockGetDistOrderId.setInt(1, w_id); + stockGetDistOrderId.setInt(2, d_id); - try (ResultSet rs = stockGetDistOrderId.executeQuery()) { + try (ResultSet rs = stockGetDistOrderId.executeQuery()) { - if (!rs.next()) { - throw new RuntimeException("D_W_ID=" + w_id + " D_ID=" + d_id + " not found!"); - } - return rs.getInt("D_NEXT_O_ID"); - } + if (!rs.next()) { + throw new RuntimeException("D_W_ID=" + w_id + " D_ID=" + d_id + " not found!"); } - + return rs.getInt("D_NEXT_O_ID"); + } } - - private int getStockCount(Connection conn, int w_id, int threshold, int d_id, int o_id) throws SQLException { - try (PreparedStatement stockGetCountStock = this.getPreparedStatement(conn, stockGetCountStockSQL)) { - stockGetCountStock.setInt(1, w_id); - stockGetCountStock.setInt(2, d_id); - stockGetCountStock.setInt(3, o_id); - stockGetCountStock.setInt(4, o_id - 20); - stockGetCountStock.setInt(5, w_id); - stockGetCountStock.setInt(6, threshold); - - try (ResultSet rs = stockGetCountStock.executeQuery()) { - if (!rs.next()) { - String msg = String.format("Failed to get StockLevel result for COUNT query [W_ID=%d, D_ID=%d, O_ID=%d]", w_id, d_id, o_id); - - throw new RuntimeException(msg); - } - - return rs.getInt("STOCK_COUNT"); - } + } + + private int getStockCount(Connection conn, int w_id, int threshold, int d_id, int o_id) + throws SQLException { + try (PreparedStatement stockGetCountStock = + this.getPreparedStatement(conn, stockGetCountStockSQL)) { + stockGetCountStock.setInt(1, w_id); + stockGetCountStock.setInt(2, d_id); + stockGetCountStock.setInt(3, o_id); + stockGetCountStock.setInt(4, o_id - 20); + stockGetCountStock.setInt(5, w_id); + stockGetCountStock.setInt(6, threshold); + + try (ResultSet rs = stockGetCountStock.executeQuery()) { + if (!rs.next()) { + String msg = + String.format( + "Failed to get StockLevel result for COUNT query [W_ID=%d, D_ID=%d, O_ID=%d]", + w_id, d_id, o_id); + + throw new RuntimeException(msg); } + + return rs.getInt("STOCK_COUNT"); + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/TPCCProcedure.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/TPCCProcedure.java index 1f51f203b..cdbd4e686 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/TPCCProcedure.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcc/procedures/TPCCProcedure.java @@ -19,13 +19,19 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.tpcc.TPCCWorker; - import java.sql.Connection; import java.sql.SQLException; import java.util.Random; public abstract class TPCCProcedure extends Procedure { - public abstract void run(Connection conn, Random gen, int terminalWarehouseID, int numWarehouses, int terminalDistrictLowerID, int terminalDistrictUpperID, TPCCWorker w) throws SQLException; - + public abstract void run( + Connection conn, + Random gen, + int terminalWarehouseID, + int numWarehouses, + int terminalDistrictLowerID, + int terminalDistrictUpperID, + TPCCWorker w) + throws SQLException; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSBenchmark.java index 66d3b1b26..a330f5ef3 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSBenchmark.java @@ -22,42 +22,43 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tpcds.procedures.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class TPCDSBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(TPCDSBenchmark.class); + private static final Logger LOG = LoggerFactory.getLogger(TPCDSBenchmark.class); - public TPCDSBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } + public TPCDSBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected Package getProcedurePackageImpl() { - return (Test.class.getPackage()); - } + @Override + protected Package getProcedurePackageImpl() { + return (Test.class.getPackage()); + } - @Override - protected List> makeWorkersImpl() { - LOG.debug(String.format("Initializing %d %s", this.workConf.getTerminals(), TPCDSWorker.class.getSimpleName())); - - List> workers = new ArrayList<>(); - try { - for (int i = 0; i < this.workConf.getTerminals(); ++i) { - TPCDSWorker worker = new TPCDSWorker(this, i); - workers.add(worker); - } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - } - return workers; - } + @Override + protected List> makeWorkersImpl() { + LOG.debug( + String.format( + "Initializing %d %s", this.workConf.getTerminals(), TPCDSWorker.class.getSimpleName())); - @Override - protected Loader makeLoaderImpl() { - return new TPCDSLoader(this); + List> workers = new ArrayList<>(); + try { + for (int i = 0; i < this.workConf.getTerminals(); ++i) { + TPCDSWorker worker = new TPCDSWorker(this, i); + workers.add(worker); + } + } catch (Exception e) { + LOG.error(e.getMessage(), e); } + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new TPCDSLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSConstants.java index b736e1fbe..0f05a7a10 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSConstants.java @@ -18,529 +18,533 @@ package com.oltpbenchmark.benchmarks.tpcds; public abstract class TPCDSConstants { - public static final String TABLENAME_CALLCENTER = "call_center"; - public static final String TABLENAME_CATALOGPAGE = "catalog_page"; - public static final String TABLENAME_CATALOGRETURNS = "catalog_returns"; - public static final String TABLENAME_CATALOGSALES = "catalog_sales"; - public static final String TABLENAME_CUSTOMER = "customer"; - public static final String TABLENAME_CUSTOMERADDRESS = "customer_address"; - public static final String TABLENAME_CUSTOMERDEM = "customer_demographics"; - public static final String TABLENAME_DATEDIM = "date_dim"; - public static final String TABLENAME_HOUSEHOLDDEM = "household_demographics"; - public static final String TABLENAME_INCOMEBAND = "income_band"; - public static final String TABLENAME_INVENTORY = "inventory"; - public static final String TABLENAME_ITEM = "item"; - public static final String TABLENAME_PROMOTION = "promotion"; - public static final String TABLENAME_REASON = "reason"; - public static final String TABLENAME_SHIPMODE = "ship_mode"; - public static final String TABLENAME_STORE = "store"; - public static final String TABLENAME_STORERETURNS = "store_returns"; - public static final String TABLENAME_STORESALES = "store_sales"; - public static final String TABLENAME_TIMEDIM = "time_dim"; - public static final String TABLENAME_WAREHOUSE = "warehouse"; - public static final String TABLENAME_WEBPAGE = "web_page"; - public static final String TABLENAME_WEBRETURNS = "web_returns"; - public static final String TABLENAME_WEBSALES = "web_sales"; - public static final String TABLENAME_WEBSITE = "web_site"; + public static final String TABLENAME_CALLCENTER = "call_center"; + public static final String TABLENAME_CATALOGPAGE = "catalog_page"; + public static final String TABLENAME_CATALOGRETURNS = "catalog_returns"; + public static final String TABLENAME_CATALOGSALES = "catalog_sales"; + public static final String TABLENAME_CUSTOMER = "customer"; + public static final String TABLENAME_CUSTOMERADDRESS = "customer_address"; + public static final String TABLENAME_CUSTOMERDEM = "customer_demographics"; + public static final String TABLENAME_DATEDIM = "date_dim"; + public static final String TABLENAME_HOUSEHOLDDEM = "household_demographics"; + public static final String TABLENAME_INCOMEBAND = "income_band"; + public static final String TABLENAME_INVENTORY = "inventory"; + public static final String TABLENAME_ITEM = "item"; + public static final String TABLENAME_PROMOTION = "promotion"; + public static final String TABLENAME_REASON = "reason"; + public static final String TABLENAME_SHIPMODE = "ship_mode"; + public static final String TABLENAME_STORE = "store"; + public static final String TABLENAME_STORERETURNS = "store_returns"; + public static final String TABLENAME_STORESALES = "store_sales"; + public static final String TABLENAME_TIMEDIM = "time_dim"; + public static final String TABLENAME_WAREHOUSE = "warehouse"; + public static final String TABLENAME_WEBPAGE = "web_page"; + public static final String TABLENAME_WEBRETURNS = "web_returns"; + public static final String TABLENAME_WEBSALES = "web_sales"; + public static final String TABLENAME_WEBSITE = "web_site"; - public enum CastTypes {LONG, DOUBLE, STRING, DATE} + public enum CastTypes { + LONG, + DOUBLE, + STRING, + DATE + } - public static final CastTypes[] callcenterTypes = { - CastTypes.LONG, // cc_call_center_sk - CastTypes.STRING, // cc_call_center_id - CastTypes.DATE, // cc_rec_start_date - CastTypes.DATE, // cc_rec_end_date - CastTypes.LONG, // cc_closed_date_sk - CastTypes.LONG, // cc_open_date_sk - CastTypes.STRING, // cc_name - CastTypes.STRING, // cc_class - CastTypes.LONG, // cc_employees - CastTypes.LONG, // cc_sq_ft - CastTypes.STRING, // cc_hours - CastTypes.STRING, // cc_manager - CastTypes.LONG, // cc_mkt_id - CastTypes.STRING, // cc_mkt_class - CastTypes.STRING, // cc_mkt_desc_text - CastTypes.STRING, // cc_market_manager - CastTypes.LONG, // cc_division - CastTypes.STRING, // cc_division_name - CastTypes.LONG, // cc_company - CastTypes.STRING, // cc_company_name - CastTypes.STRING, // cc_street_number - CastTypes.STRING, // cc_street_name - CastTypes.STRING, // cc_street_type - CastTypes.STRING, // cc_suite_number - CastTypes.STRING, // cc_city - CastTypes.STRING, // s_state - CastTypes.STRING, // cc_county - CastTypes.STRING, // cc_state - CastTypes.STRING, // cc_zip_text - CastTypes.STRING, // cc_country - CastTypes.DOUBLE, // cc_gmt_offset - CastTypes.DOUBLE // cc_tax_percentage - }; + public static final CastTypes[] callcenterTypes = { + CastTypes.LONG, // cc_call_center_sk + CastTypes.STRING, // cc_call_center_id + CastTypes.DATE, // cc_rec_start_date + CastTypes.DATE, // cc_rec_end_date + CastTypes.LONG, // cc_closed_date_sk + CastTypes.LONG, // cc_open_date_sk + CastTypes.STRING, // cc_name + CastTypes.STRING, // cc_class + CastTypes.LONG, // cc_employees + CastTypes.LONG, // cc_sq_ft + CastTypes.STRING, // cc_hours + CastTypes.STRING, // cc_manager + CastTypes.LONG, // cc_mkt_id + CastTypes.STRING, // cc_mkt_class + CastTypes.STRING, // cc_mkt_desc_text + CastTypes.STRING, // cc_market_manager + CastTypes.LONG, // cc_division + CastTypes.STRING, // cc_division_name + CastTypes.LONG, // cc_company + CastTypes.STRING, // cc_company_name + CastTypes.STRING, // cc_street_number + CastTypes.STRING, // cc_street_name + CastTypes.STRING, // cc_street_type + CastTypes.STRING, // cc_suite_number + CastTypes.STRING, // cc_city + CastTypes.STRING, // s_state + CastTypes.STRING, // cc_county + CastTypes.STRING, // cc_state + CastTypes.STRING, // cc_zip_text + CastTypes.STRING, // cc_country + CastTypes.DOUBLE, // cc_gmt_offset + CastTypes.DOUBLE // cc_tax_percentage + }; - public static final CastTypes[] catalogpageTypes = { - CastTypes.LONG, // cp_catalog_page_sk - CastTypes.STRING, // cp_catalog_page_id - CastTypes.LONG, // cp_start_date_sk - CastTypes.LONG, // cp_end_date_sk - CastTypes.STRING, // cp_department - CastTypes.LONG, // cp_catalog_number - CastTypes.LONG, // cp_catalog_page_number - CastTypes.STRING, // cp_description - CastTypes.STRING // cp_type - }; + public static final CastTypes[] catalogpageTypes = { + CastTypes.LONG, // cp_catalog_page_sk + CastTypes.STRING, // cp_catalog_page_id + CastTypes.LONG, // cp_start_date_sk + CastTypes.LONG, // cp_end_date_sk + CastTypes.STRING, // cp_department + CastTypes.LONG, // cp_catalog_number + CastTypes.LONG, // cp_catalog_page_number + CastTypes.STRING, // cp_description + CastTypes.STRING // cp_type + }; - public static final CastTypes[] catalogreturnsTypes = { - CastTypes.LONG, // cr_returned_date_sk - CastTypes.LONG, // cr_returned_time_sk - CastTypes.LONG, // cr_item_sk - CastTypes.LONG, // cr_refunded_customer_sk - CastTypes.LONG, // cr_refunded_cdemo_sk - CastTypes.LONG, // cr_refunded_hdemo_sk - CastTypes.LONG, // cr_refunded_addr_sk - CastTypes.LONG, // cr_returning_customer_sk - CastTypes.LONG, // cr_returning_cdemo_sk - CastTypes.LONG, // cr_returning_hdemo_sk - CastTypes.LONG, // cr_returning_addr_sk - CastTypes.LONG, // cr_call_center_sk - CastTypes.LONG, // cr_catalog_page_sk - CastTypes.LONG, // cr_ship_mode_sk - CastTypes.LONG, // cr_warehouse_sk - CastTypes.LONG, // cr_reason_sk - CastTypes.LONG, // cr_order_number - CastTypes.LONG, // cr_return_quantity - CastTypes.DOUBLE, // cr_return_amount - CastTypes.DOUBLE, // cr_return_tax - CastTypes.DOUBLE, // cr_return_amt_inc_tax - CastTypes.DOUBLE, // cr_fee - CastTypes.DOUBLE, // cr_return_ship_cost - CastTypes.DOUBLE, // cr_refunded_cash - CastTypes.DOUBLE, // cr_reversed_charge - CastTypes.DOUBLE, // cr_store_credit - CastTypes.DOUBLE // cr_net_loss - }; + public static final CastTypes[] catalogreturnsTypes = { + CastTypes.LONG, // cr_returned_date_sk + CastTypes.LONG, // cr_returned_time_sk + CastTypes.LONG, // cr_item_sk + CastTypes.LONG, // cr_refunded_customer_sk + CastTypes.LONG, // cr_refunded_cdemo_sk + CastTypes.LONG, // cr_refunded_hdemo_sk + CastTypes.LONG, // cr_refunded_addr_sk + CastTypes.LONG, // cr_returning_customer_sk + CastTypes.LONG, // cr_returning_cdemo_sk + CastTypes.LONG, // cr_returning_hdemo_sk + CastTypes.LONG, // cr_returning_addr_sk + CastTypes.LONG, // cr_call_center_sk + CastTypes.LONG, // cr_catalog_page_sk + CastTypes.LONG, // cr_ship_mode_sk + CastTypes.LONG, // cr_warehouse_sk + CastTypes.LONG, // cr_reason_sk + CastTypes.LONG, // cr_order_number + CastTypes.LONG, // cr_return_quantity + CastTypes.DOUBLE, // cr_return_amount + CastTypes.DOUBLE, // cr_return_tax + CastTypes.DOUBLE, // cr_return_amt_inc_tax + CastTypes.DOUBLE, // cr_fee + CastTypes.DOUBLE, // cr_return_ship_cost + CastTypes.DOUBLE, // cr_refunded_cash + CastTypes.DOUBLE, // cr_reversed_charge + CastTypes.DOUBLE, // cr_store_credit + CastTypes.DOUBLE // cr_net_loss + }; - public static final CastTypes[] catalogsalesTypes = { - CastTypes.LONG, // cs_sold_date_sk - CastTypes.LONG, // cs_sold_time_sk - CastTypes.LONG, // cs_ship_date_sk - CastTypes.LONG, // cs_bill_customer_sk - CastTypes.LONG, // cs_bill_cdemo_sk - CastTypes.LONG, // cs_bill_hdemo_sk - CastTypes.LONG, // cs_bill_addr_sk - CastTypes.LONG, // cs_ship_customer_sk - CastTypes.LONG, // cs_ship_cdemo_sk - CastTypes.LONG, // cs_ship_hdemo_sk - CastTypes.LONG, // cs_ship_addr_sk - CastTypes.LONG, // cs_call_center_sk - CastTypes.LONG, // cs_catalog_page_sk - CastTypes.LONG, // cs_ship_mode_sk - CastTypes.LONG, // cs_warehouse_sk - CastTypes.LONG, // cs_item_sk - CastTypes.LONG, // cs_promo_sk - CastTypes.LONG, // cs_order_number - CastTypes.LONG, // cs_quantity - CastTypes.DOUBLE, // cs_wholesale_cost - CastTypes.DOUBLE, // cs_list_price - CastTypes.DOUBLE, // cs_sales_price - CastTypes.DOUBLE, // cs_ext_discount_amt - CastTypes.DOUBLE, // cs_ext_sales_price - CastTypes.DOUBLE, // cs_ext_wholesale_cost - CastTypes.DOUBLE, // cs_ext_list_price - CastTypes.DOUBLE, // cs_ext_tax - CastTypes.DOUBLE, // cs_coupon_amt - CastTypes.DOUBLE, // cs_ext_ship_cost - CastTypes.DOUBLE, // cs_net_paid - CastTypes.DOUBLE, // cs_net_paid_inc_tax - CastTypes.DOUBLE, // cs_net_paid_inc_ship - CastTypes.DOUBLE, // cs_net_paid_inc_ship_tax - CastTypes.DOUBLE // cs_net_profit - }; + public static final CastTypes[] catalogsalesTypes = { + CastTypes.LONG, // cs_sold_date_sk + CastTypes.LONG, // cs_sold_time_sk + CastTypes.LONG, // cs_ship_date_sk + CastTypes.LONG, // cs_bill_customer_sk + CastTypes.LONG, // cs_bill_cdemo_sk + CastTypes.LONG, // cs_bill_hdemo_sk + CastTypes.LONG, // cs_bill_addr_sk + CastTypes.LONG, // cs_ship_customer_sk + CastTypes.LONG, // cs_ship_cdemo_sk + CastTypes.LONG, // cs_ship_hdemo_sk + CastTypes.LONG, // cs_ship_addr_sk + CastTypes.LONG, // cs_call_center_sk + CastTypes.LONG, // cs_catalog_page_sk + CastTypes.LONG, // cs_ship_mode_sk + CastTypes.LONG, // cs_warehouse_sk + CastTypes.LONG, // cs_item_sk + CastTypes.LONG, // cs_promo_sk + CastTypes.LONG, // cs_order_number + CastTypes.LONG, // cs_quantity + CastTypes.DOUBLE, // cs_wholesale_cost + CastTypes.DOUBLE, // cs_list_price + CastTypes.DOUBLE, // cs_sales_price + CastTypes.DOUBLE, // cs_ext_discount_amt + CastTypes.DOUBLE, // cs_ext_sales_price + CastTypes.DOUBLE, // cs_ext_wholesale_cost + CastTypes.DOUBLE, // cs_ext_list_price + CastTypes.DOUBLE, // cs_ext_tax + CastTypes.DOUBLE, // cs_coupon_amt + CastTypes.DOUBLE, // cs_ext_ship_cost + CastTypes.DOUBLE, // cs_net_paid + CastTypes.DOUBLE, // cs_net_paid_inc_tax + CastTypes.DOUBLE, // cs_net_paid_inc_ship + CastTypes.DOUBLE, // cs_net_paid_inc_ship_tax + CastTypes.DOUBLE // cs_net_profit + }; - public static final CastTypes[] customerTypes = { - CastTypes.LONG, // c_customer_sk - CastTypes.STRING, // c_customer_id - CastTypes.LONG, // c_current_cdemo_sk - CastTypes.LONG, // c_current_hdemo_sk - CastTypes.LONG, // c_current_addr_sk - CastTypes.LONG, // c_first_shipto_date_sk - CastTypes.LONG, // c_first_sales_date_sk - CastTypes.STRING, // c_salutation - CastTypes.STRING, // c_first_name - CastTypes.STRING, // c_last_name - CastTypes.STRING, // c_preferred_cust_flag text - CastTypes.LONG, // c_birth_day - CastTypes.LONG, // c_birth_month - CastTypes.LONG, // c_birth_year - CastTypes.STRING, // c_birth_country - CastTypes.STRING, // c_login - CastTypes.STRING, // c_email_address - CastTypes.LONG // c_last_review_date_sk - }; + public static final CastTypes[] customerTypes = { + CastTypes.LONG, // c_customer_sk + CastTypes.STRING, // c_customer_id + CastTypes.LONG, // c_current_cdemo_sk + CastTypes.LONG, // c_current_hdemo_sk + CastTypes.LONG, // c_current_addr_sk + CastTypes.LONG, // c_first_shipto_date_sk + CastTypes.LONG, // c_first_sales_date_sk + CastTypes.STRING, // c_salutation + CastTypes.STRING, // c_first_name + CastTypes.STRING, // c_last_name + CastTypes.STRING, // c_preferred_cust_flag text + CastTypes.LONG, // c_birth_day + CastTypes.LONG, // c_birth_month + CastTypes.LONG, // c_birth_year + CastTypes.STRING, // c_birth_country + CastTypes.STRING, // c_login + CastTypes.STRING, // c_email_address + CastTypes.LONG // c_last_review_date_sk + }; - public static final CastTypes[] customeraddressTypes = { - CastTypes.LONG, // ca_address_sk - CastTypes.STRING, // ca_address_id - CastTypes.STRING, // ca_street_number - CastTypes.STRING, // ca_street_name - CastTypes.STRING, // ca_street_type - CastTypes.STRING, // ca_suite_number - CastTypes.STRING, // ca_city - CastTypes.STRING, // ca_county - CastTypes.STRING, // ca_state - CastTypes.STRING, // ca_zip - CastTypes.STRING, // ca_country - CastTypes.DOUBLE, // ca_gmt_offset - CastTypes.STRING // ca_location_type - }; + public static final CastTypes[] customeraddressTypes = { + CastTypes.LONG, // ca_address_sk + CastTypes.STRING, // ca_address_id + CastTypes.STRING, // ca_street_number + CastTypes.STRING, // ca_street_name + CastTypes.STRING, // ca_street_type + CastTypes.STRING, // ca_suite_number + CastTypes.STRING, // ca_city + CastTypes.STRING, // ca_county + CastTypes.STRING, // ca_state + CastTypes.STRING, // ca_zip + CastTypes.STRING, // ca_country + CastTypes.DOUBLE, // ca_gmt_offset + CastTypes.STRING // ca_location_type + }; - public static final CastTypes[] customerdemTypes = { - CastTypes.LONG, // cd_demo_sk - CastTypes.STRING, // gender - CastTypes.STRING, // cd_marital_status - CastTypes.STRING, // cd_education_status - CastTypes.LONG, // cd_purchase_estimate - CastTypes.STRING, // cd_credit_rating - CastTypes.LONG, // cd_dep_count - CastTypes.LONG, // cd_dep_employed_count - CastTypes.LONG // cd_dep_college_count - }; + public static final CastTypes[] customerdemTypes = { + CastTypes.LONG, // cd_demo_sk + CastTypes.STRING, // gender + CastTypes.STRING, // cd_marital_status + CastTypes.STRING, // cd_education_status + CastTypes.LONG, // cd_purchase_estimate + CastTypes.STRING, // cd_credit_rating + CastTypes.LONG, // cd_dep_count + CastTypes.LONG, // cd_dep_employed_count + CastTypes.LONG // cd_dep_college_count + }; - public static final CastTypes[] datedimTypes = { - CastTypes.LONG, // d_date_sk - CastTypes.STRING, // d_date_id - CastTypes.DATE, // d_date - CastTypes.LONG, // d_month_seq - CastTypes.LONG, // d_week_seq - CastTypes.LONG, // d_quarter_seq - CastTypes.LONG, // d_year - CastTypes.LONG, // d_dow - CastTypes.LONG, // d_moy - CastTypes.LONG, // d_dom - CastTypes.LONG, // d_qoy - CastTypes.LONG, // d_fy_year - CastTypes.LONG, // d_fy_quarter_seq - CastTypes.LONG, // d_fy_week_seq - CastTypes.STRING, // d_day_name - CastTypes.STRING, // d_quarter_name - CastTypes.STRING, // d_holiday - CastTypes.STRING, // d_weekend - CastTypes.STRING, // d_following_holiday - CastTypes.LONG, // d_first_dom - CastTypes.LONG, // d_last_dom - CastTypes.LONG, // d_same_day_ly - CastTypes.LONG, // d_same_day_lq - CastTypes.STRING, // d_current_day - CastTypes.STRING, // d_quarter_week - CastTypes.STRING, // d_current_month - CastTypes.STRING, // d_current_quarter - CastTypes.STRING // d_current_year - }; + public static final CastTypes[] datedimTypes = { + CastTypes.LONG, // d_date_sk + CastTypes.STRING, // d_date_id + CastTypes.DATE, // d_date + CastTypes.LONG, // d_month_seq + CastTypes.LONG, // d_week_seq + CastTypes.LONG, // d_quarter_seq + CastTypes.LONG, // d_year + CastTypes.LONG, // d_dow + CastTypes.LONG, // d_moy + CastTypes.LONG, // d_dom + CastTypes.LONG, // d_qoy + CastTypes.LONG, // d_fy_year + CastTypes.LONG, // d_fy_quarter_seq + CastTypes.LONG, // d_fy_week_seq + CastTypes.STRING, // d_day_name + CastTypes.STRING, // d_quarter_name + CastTypes.STRING, // d_holiday + CastTypes.STRING, // d_weekend + CastTypes.STRING, // d_following_holiday + CastTypes.LONG, // d_first_dom + CastTypes.LONG, // d_last_dom + CastTypes.LONG, // d_same_day_ly + CastTypes.LONG, // d_same_day_lq + CastTypes.STRING, // d_current_day + CastTypes.STRING, // d_quarter_week + CastTypes.STRING, // d_current_month + CastTypes.STRING, // d_current_quarter + CastTypes.STRING // d_current_year + }; - public static final CastTypes[] householddemTypes = { - CastTypes.LONG, // hd_demo_sk - CastTypes.LONG, // hd_income_band_sk - CastTypes.STRING, // hd_buy_potential - CastTypes.LONG, // hd_dep_count - CastTypes.LONG, // hd_vehicle_count - }; + public static final CastTypes[] householddemTypes = { + CastTypes.LONG, // hd_demo_sk + CastTypes.LONG, // hd_income_band_sk + CastTypes.STRING, // hd_buy_potential + CastTypes.LONG, // hd_dep_count + CastTypes.LONG, // hd_vehicle_count + }; - public static final CastTypes[] incomebandTypes = { - CastTypes.LONG, // ib_income_band_sk - CastTypes.LONG, // ib_lower_bound - CastTypes.LONG // ib_upper_bound - }; + public static final CastTypes[] incomebandTypes = { + CastTypes.LONG, // ib_income_band_sk + CastTypes.LONG, // ib_lower_bound + CastTypes.LONG // ib_upper_bound + }; - public static final CastTypes[] inventoryTypes = { - CastTypes.LONG, // inv_date_sk - CastTypes.LONG, // inv_item_sk - CastTypes.LONG, // inv_warehouse_sk - CastTypes.LONG // inv_quantity_on_hand - }; + public static final CastTypes[] inventoryTypes = { + CastTypes.LONG, // inv_date_sk + CastTypes.LONG, // inv_item_sk + CastTypes.LONG, // inv_warehouse_sk + CastTypes.LONG // inv_quantity_on_hand + }; - public static final CastTypes[] itemTypes = { - CastTypes.LONG, // i_item_sk - CastTypes.STRING, // i_item_id - CastTypes.DATE, // i_rec_start_date - CastTypes.DATE, // i_rec_end_date - CastTypes.STRING, // i_item_desc - CastTypes.DOUBLE, // i_current_price - CastTypes.DOUBLE, // i_wholesale_cost - CastTypes.LONG, // i_brand_id - CastTypes.STRING, // i_brand - CastTypes.LONG, // i_class_id - CastTypes.STRING, // i_class - CastTypes.LONG, // i_category_id - CastTypes.STRING, // i_category - CastTypes.LONG, // i_manufact_id - CastTypes.STRING, // i_manufact - CastTypes.STRING, // i_size - CastTypes.STRING, // i_formulation - CastTypes.STRING, // i_color - CastTypes.STRING, // i_units - CastTypes.STRING, // i_container - CastTypes.LONG, // i_manager_id - CastTypes.STRING // i_product_name - }; + public static final CastTypes[] itemTypes = { + CastTypes.LONG, // i_item_sk + CastTypes.STRING, // i_item_id + CastTypes.DATE, // i_rec_start_date + CastTypes.DATE, // i_rec_end_date + CastTypes.STRING, // i_item_desc + CastTypes.DOUBLE, // i_current_price + CastTypes.DOUBLE, // i_wholesale_cost + CastTypes.LONG, // i_brand_id + CastTypes.STRING, // i_brand + CastTypes.LONG, // i_class_id + CastTypes.STRING, // i_class + CastTypes.LONG, // i_category_id + CastTypes.STRING, // i_category + CastTypes.LONG, // i_manufact_id + CastTypes.STRING, // i_manufact + CastTypes.STRING, // i_size + CastTypes.STRING, // i_formulation + CastTypes.STRING, // i_color + CastTypes.STRING, // i_units + CastTypes.STRING, // i_container + CastTypes.LONG, // i_manager_id + CastTypes.STRING // i_product_name + }; - public static final CastTypes[] promotionTypes = { - CastTypes.LONG, // p_promo_sk - CastTypes.STRING, // p_promo_id - CastTypes.LONG, // p_start_date_sk - CastTypes.LONG, // p_end_date_sk - CastTypes.LONG, // p_item_sk - CastTypes.DOUBLE, // p_cost - CastTypes.LONG, // p_response_target - CastTypes.STRING, // p_promo_name - CastTypes.STRING, // p_channel_dmail - CastTypes.STRING, // p_channel_email - CastTypes.STRING, // p_channel_catalog - CastTypes.STRING, // p_channel_tv - CastTypes.STRING, // p_channel_radio - CastTypes.STRING, // p_channel_press - CastTypes.STRING, // p_channel_event - CastTypes.STRING, // p_channel_demo - CastTypes.STRING, // p_channel_details - CastTypes.STRING, // p_purpose - CastTypes.STRING // p_discount_active - }; + public static final CastTypes[] promotionTypes = { + CastTypes.LONG, // p_promo_sk + CastTypes.STRING, // p_promo_id + CastTypes.LONG, // p_start_date_sk + CastTypes.LONG, // p_end_date_sk + CastTypes.LONG, // p_item_sk + CastTypes.DOUBLE, // p_cost + CastTypes.LONG, // p_response_target + CastTypes.STRING, // p_promo_name + CastTypes.STRING, // p_channel_dmail + CastTypes.STRING, // p_channel_email + CastTypes.STRING, // p_channel_catalog + CastTypes.STRING, // p_channel_tv + CastTypes.STRING, // p_channel_radio + CastTypes.STRING, // p_channel_press + CastTypes.STRING, // p_channel_event + CastTypes.STRING, // p_channel_demo + CastTypes.STRING, // p_channel_details + CastTypes.STRING, // p_purpose + CastTypes.STRING // p_discount_active + }; - public static final CastTypes[] reasonTypes = { - CastTypes.LONG, // r_reason_sk - CastTypes.STRING, // r_reason_id - CastTypes.STRING // r_reason_desc - }; + public static final CastTypes[] reasonTypes = { + CastTypes.LONG, // r_reason_sk + CastTypes.STRING, // r_reason_id + CastTypes.STRING // r_reason_desc + }; - public static final CastTypes[] shipmodeTypes = { - CastTypes.LONG, // sm_ship_mode_sk - CastTypes.STRING, // sm_ship_mode_id - CastTypes.STRING, // sm_type - CastTypes.STRING, // sm_code - CastTypes.STRING, // sm_carrier - CastTypes.STRING // sm_contract - }; + public static final CastTypes[] shipmodeTypes = { + CastTypes.LONG, // sm_ship_mode_sk + CastTypes.STRING, // sm_ship_mode_id + CastTypes.STRING, // sm_type + CastTypes.STRING, // sm_code + CastTypes.STRING, // sm_carrier + CastTypes.STRING // sm_contract + }; - public static final CastTypes[] storeTypes = { - CastTypes.LONG, // s_store_sk - CastTypes.STRING, // s_store_id - CastTypes.DATE, // s_rec_start_date - CastTypes.DATE, // s_rec_end_date - CastTypes.LONG, // s_closed_date_sk - CastTypes.STRING, // s_store_name - CastTypes.LONG, // s_number_employees - CastTypes.LONG, // s_floor_space - CastTypes.STRING, // s_hours - CastTypes.STRING, // s_manager - CastTypes.LONG, // s_market_id - CastTypes.STRING, // s_geography_class - CastTypes.STRING, // s_market_desc - CastTypes.STRING, // s_market_manager - CastTypes.LONG, // s_division_id - CastTypes.STRING, // s_division_name - CastTypes.LONG, // s_company_id - CastTypes.STRING, // s_company_name - CastTypes.STRING, // s_street_number - CastTypes.STRING, // s_street_name - CastTypes.STRING, // s_street_type - CastTypes.STRING, // s_suite_number - CastTypes.STRING, // s_city - CastTypes.STRING, // s_county - CastTypes.STRING, // s_state - CastTypes.STRING, // s_zip - CastTypes.STRING, // s_country - CastTypes.DOUBLE, // s_gmt_offset - CastTypes.DOUBLE // s_tax_percentage - }; + public static final CastTypes[] storeTypes = { + CastTypes.LONG, // s_store_sk + CastTypes.STRING, // s_store_id + CastTypes.DATE, // s_rec_start_date + CastTypes.DATE, // s_rec_end_date + CastTypes.LONG, // s_closed_date_sk + CastTypes.STRING, // s_store_name + CastTypes.LONG, // s_number_employees + CastTypes.LONG, // s_floor_space + CastTypes.STRING, // s_hours + CastTypes.STRING, // s_manager + CastTypes.LONG, // s_market_id + CastTypes.STRING, // s_geography_class + CastTypes.STRING, // s_market_desc + CastTypes.STRING, // s_market_manager + CastTypes.LONG, // s_division_id + CastTypes.STRING, // s_division_name + CastTypes.LONG, // s_company_id + CastTypes.STRING, // s_company_name + CastTypes.STRING, // s_street_number + CastTypes.STRING, // s_street_name + CastTypes.STRING, // s_street_type + CastTypes.STRING, // s_suite_number + CastTypes.STRING, // s_city + CastTypes.STRING, // s_county + CastTypes.STRING, // s_state + CastTypes.STRING, // s_zip + CastTypes.STRING, // s_country + CastTypes.DOUBLE, // s_gmt_offset + CastTypes.DOUBLE // s_tax_percentage + }; - public static final CastTypes[] storereturnsTypes = { - CastTypes.LONG, // sr_returned_date_sk - CastTypes.LONG, // sr_return_time_sk - CastTypes.LONG, // sr_item_sk - CastTypes.LONG, // sr_customer_sk - CastTypes.LONG, // sr_cdemo_sk - CastTypes.LONG, // sr_hdemo_sk - CastTypes.LONG, // sr_addr_sk - CastTypes.LONG, // sr_store_sk - CastTypes.LONG, // sr_reason_sk - CastTypes.LONG, // sr_ticket_number - CastTypes.LONG, // sr_return_quantity - CastTypes.DOUBLE, // sr_return_amt - CastTypes.DOUBLE, // sr_return_tax - CastTypes.DOUBLE, // sr_return_amt_inc_tax - CastTypes.DOUBLE, // sr_fee - CastTypes.DOUBLE, // sr_return_ship_cost - CastTypes.DOUBLE, // sr_refunded_cash - CastTypes.DOUBLE, // sr_reversed_charge - CastTypes.DOUBLE, // sr_store_credit - CastTypes.DOUBLE // sr_net_loss - }; + public static final CastTypes[] storereturnsTypes = { + CastTypes.LONG, // sr_returned_date_sk + CastTypes.LONG, // sr_return_time_sk + CastTypes.LONG, // sr_item_sk + CastTypes.LONG, // sr_customer_sk + CastTypes.LONG, // sr_cdemo_sk + CastTypes.LONG, // sr_hdemo_sk + CastTypes.LONG, // sr_addr_sk + CastTypes.LONG, // sr_store_sk + CastTypes.LONG, // sr_reason_sk + CastTypes.LONG, // sr_ticket_number + CastTypes.LONG, // sr_return_quantity + CastTypes.DOUBLE, // sr_return_amt + CastTypes.DOUBLE, // sr_return_tax + CastTypes.DOUBLE, // sr_return_amt_inc_tax + CastTypes.DOUBLE, // sr_fee + CastTypes.DOUBLE, // sr_return_ship_cost + CastTypes.DOUBLE, // sr_refunded_cash + CastTypes.DOUBLE, // sr_reversed_charge + CastTypes.DOUBLE, // sr_store_credit + CastTypes.DOUBLE // sr_net_loss + }; - public static final CastTypes[] storesalesTypes = { - CastTypes.LONG, // ss_sold_date_sk - CastTypes.LONG, // ss_sold_time_sk - CastTypes.LONG, // ss_item_sk - CastTypes.LONG, // ss_customer_sk - CastTypes.LONG, // ss_cdemo_sk - CastTypes.LONG, // ss_hdemo_sk - CastTypes.LONG, // ss_addr_sk - CastTypes.LONG, // ss_store_sk - CastTypes.LONG, // ss_promo_sk - CastTypes.LONG, // ss_ticket_number - CastTypes.LONG, // ss_quantity - CastTypes.DOUBLE, // ss_wholesale_cost - CastTypes.DOUBLE, // ss_list_price - CastTypes.DOUBLE, // ss_sales_price - CastTypes.DOUBLE, // ss_ext_discount_amt - CastTypes.DOUBLE, // ss_ext_sales_price - CastTypes.DOUBLE, // ss_ext_wholesale_cost - CastTypes.DOUBLE, // ss_ext_list_price - CastTypes.DOUBLE, // ss_ext_tax - CastTypes.DOUBLE, // ss_coupon_amt - CastTypes.DOUBLE, // ss_net_paid - CastTypes.DOUBLE, // ss_net_paid_inc_tax - CastTypes.DOUBLE // ss_net_profit - }; + public static final CastTypes[] storesalesTypes = { + CastTypes.LONG, // ss_sold_date_sk + CastTypes.LONG, // ss_sold_time_sk + CastTypes.LONG, // ss_item_sk + CastTypes.LONG, // ss_customer_sk + CastTypes.LONG, // ss_cdemo_sk + CastTypes.LONG, // ss_hdemo_sk + CastTypes.LONG, // ss_addr_sk + CastTypes.LONG, // ss_store_sk + CastTypes.LONG, // ss_promo_sk + CastTypes.LONG, // ss_ticket_number + CastTypes.LONG, // ss_quantity + CastTypes.DOUBLE, // ss_wholesale_cost + CastTypes.DOUBLE, // ss_list_price + CastTypes.DOUBLE, // ss_sales_price + CastTypes.DOUBLE, // ss_ext_discount_amt + CastTypes.DOUBLE, // ss_ext_sales_price + CastTypes.DOUBLE, // ss_ext_wholesale_cost + CastTypes.DOUBLE, // ss_ext_list_price + CastTypes.DOUBLE, // ss_ext_tax + CastTypes.DOUBLE, // ss_coupon_amt + CastTypes.DOUBLE, // ss_net_paid + CastTypes.DOUBLE, // ss_net_paid_inc_tax + CastTypes.DOUBLE // ss_net_profit + }; - public static final CastTypes[] timedimTypes = { - CastTypes.LONG, // t_time_sk - CastTypes.STRING, // t_time_id - CastTypes.LONG, // t_time - CastTypes.LONG, // t_hour - CastTypes.LONG, // t_minute - CastTypes.LONG, // t_second - CastTypes.STRING, // t_am_pm - CastTypes.STRING, // t_shift - CastTypes.STRING, // t_sub_shift - CastTypes.STRING // t_meal_time - }; + public static final CastTypes[] timedimTypes = { + CastTypes.LONG, // t_time_sk + CastTypes.STRING, // t_time_id + CastTypes.LONG, // t_time + CastTypes.LONG, // t_hour + CastTypes.LONG, // t_minute + CastTypes.LONG, // t_second + CastTypes.STRING, // t_am_pm + CastTypes.STRING, // t_shift + CastTypes.STRING, // t_sub_shift + CastTypes.STRING // t_meal_time + }; - public static final CastTypes[] warehouseTypes = { - CastTypes.LONG, // w_warehouse_sk - CastTypes.STRING, // w_warehouse_id - CastTypes.STRING, // w_warehouse_name - CastTypes.LONG, // w_warehouse_sq_ft - CastTypes.STRING, // w_street_number - CastTypes.STRING, // w_street_name - CastTypes.STRING, // w_street_type - CastTypes.STRING, // w_suite_number - CastTypes.STRING, // w_city - CastTypes.STRING, // w_county - CastTypes.STRING, // w_state - CastTypes.STRING, // w_zip - CastTypes.STRING, // w_country - CastTypes.DOUBLE // w_gmt_offset - }; + public static final CastTypes[] warehouseTypes = { + CastTypes.LONG, // w_warehouse_sk + CastTypes.STRING, // w_warehouse_id + CastTypes.STRING, // w_warehouse_name + CastTypes.LONG, // w_warehouse_sq_ft + CastTypes.STRING, // w_street_number + CastTypes.STRING, // w_street_name + CastTypes.STRING, // w_street_type + CastTypes.STRING, // w_suite_number + CastTypes.STRING, // w_city + CastTypes.STRING, // w_county + CastTypes.STRING, // w_state + CastTypes.STRING, // w_zip + CastTypes.STRING, // w_country + CastTypes.DOUBLE // w_gmt_offset + }; - public static final CastTypes[] webpageTypes = { - CastTypes.LONG, // wp_web_page_sk - CastTypes.STRING, // wp_web_page_id - CastTypes.DATE, // wp_rec_start_date - CastTypes.DATE, // wp_rec_end_date - CastTypes.LONG, // wp_creation_date_sk - CastTypes.LONG, // wp_access_date_sk - CastTypes.STRING, // wp_autogen_flag - CastTypes.LONG, // wp_customer_sk - CastTypes.STRING, // wp_url - CastTypes.STRING, // wp_type - CastTypes.LONG, // wp_char_count - CastTypes.LONG, // wp_link_count - CastTypes.LONG, // wp_image_count - CastTypes.LONG // wp_max_ad_count - }; + public static final CastTypes[] webpageTypes = { + CastTypes.LONG, // wp_web_page_sk + CastTypes.STRING, // wp_web_page_id + CastTypes.DATE, // wp_rec_start_date + CastTypes.DATE, // wp_rec_end_date + CastTypes.LONG, // wp_creation_date_sk + CastTypes.LONG, // wp_access_date_sk + CastTypes.STRING, // wp_autogen_flag + CastTypes.LONG, // wp_customer_sk + CastTypes.STRING, // wp_url + CastTypes.STRING, // wp_type + CastTypes.LONG, // wp_char_count + CastTypes.LONG, // wp_link_count + CastTypes.LONG, // wp_image_count + CastTypes.LONG // wp_max_ad_count + }; - public static final CastTypes[] webreturnsTypes = { - CastTypes.LONG, // wr_returned_date_sk - CastTypes.LONG, // wr_return_time_sk - CastTypes.LONG, // wr_item_sk - CastTypes.LONG, // wr_refunded_customer_sk - CastTypes.LONG, // wr_refunded_cdemo_sk - CastTypes.LONG, // wr_refunded_hdemo_sk - CastTypes.LONG, // wr_refunded_addr_sk - CastTypes.LONG, // wr_returning_customer_sk - CastTypes.LONG, // wr_returning_cdemo_sk - CastTypes.LONG, // wr_returning_hdemo_sk - CastTypes.LONG, // wr_returning_addr_sk - CastTypes.LONG, // wr_web_page_sk - CastTypes.LONG, // wr_reason_sk - CastTypes.LONG, // wr_order_number - CastTypes.LONG, // wr_return_quantity - CastTypes.DOUBLE, // wr_return_amt - CastTypes.DOUBLE, // wr_return_tax - CastTypes.DOUBLE, // wr_return_amt_inc_tax - CastTypes.DOUBLE, // wr_fee - CastTypes.DOUBLE, // wr_return_ship_cost - CastTypes.DOUBLE, // wr_refunded_cash - CastTypes.DOUBLE, // wr_reversed_charge - CastTypes.DOUBLE, // wr_store_credit - CastTypes.DOUBLE // wr_net_loss - }; + public static final CastTypes[] webreturnsTypes = { + CastTypes.LONG, // wr_returned_date_sk + CastTypes.LONG, // wr_return_time_sk + CastTypes.LONG, // wr_item_sk + CastTypes.LONG, // wr_refunded_customer_sk + CastTypes.LONG, // wr_refunded_cdemo_sk + CastTypes.LONG, // wr_refunded_hdemo_sk + CastTypes.LONG, // wr_refunded_addr_sk + CastTypes.LONG, // wr_returning_customer_sk + CastTypes.LONG, // wr_returning_cdemo_sk + CastTypes.LONG, // wr_returning_hdemo_sk + CastTypes.LONG, // wr_returning_addr_sk + CastTypes.LONG, // wr_web_page_sk + CastTypes.LONG, // wr_reason_sk + CastTypes.LONG, // wr_order_number + CastTypes.LONG, // wr_return_quantity + CastTypes.DOUBLE, // wr_return_amt + CastTypes.DOUBLE, // wr_return_tax + CastTypes.DOUBLE, // wr_return_amt_inc_tax + CastTypes.DOUBLE, // wr_fee + CastTypes.DOUBLE, // wr_return_ship_cost + CastTypes.DOUBLE, // wr_refunded_cash + CastTypes.DOUBLE, // wr_reversed_charge + CastTypes.DOUBLE, // wr_store_credit + CastTypes.DOUBLE // wr_net_loss + }; - public static final CastTypes[] websalesTypes = { - CastTypes.LONG, // ws_sold_date_sk - CastTypes.LONG, // ws_sold_time_sk - CastTypes.LONG, // ws_ship_date_sk - CastTypes.LONG, // ws_item_sk - CastTypes.LONG, // ws_bill_customer_sk - CastTypes.LONG, // ws_bill_cdemo_sk - CastTypes.LONG, // ws_bill_hdemo_sk - CastTypes.LONG, // ws_bill_addr_sk - CastTypes.LONG, // ws_ship_customer_sk - CastTypes.LONG, // ws_ship_cdemo_sk - CastTypes.LONG, // ws_ship_hdemo_sk - CastTypes.LONG, // ws_ship_addr_sk - CastTypes.LONG, // ws_web_page_sk - CastTypes.LONG, // ws_web_site_sk - CastTypes.LONG, // ws_ship_mode_sk - CastTypes.LONG, // ws_warehouse_sk - CastTypes.LONG, // ws_promo_sk - CastTypes.LONG, // ws_order_number - CastTypes.LONG, // ws_quantity - CastTypes.DOUBLE, // ws_wholesale_cost - CastTypes.DOUBLE, // ws_list_price - CastTypes.DOUBLE, // ws_sales_price - CastTypes.DOUBLE, // ws_ext_discount_amt - CastTypes.DOUBLE, // ws_ext_sales_price - CastTypes.DOUBLE, // ws_ext_wholesale_cost - CastTypes.DOUBLE, // ws_ext_list_price - CastTypes.DOUBLE, // ws_ext_tax - CastTypes.DOUBLE, // ws_coupon_amt - CastTypes.DOUBLE, // ws_ext_ship_cost - CastTypes.DOUBLE, // ws_net_paid - CastTypes.DOUBLE, // ws_net_paid_inc_tax - CastTypes.DOUBLE, // ws_net_paid_inc_ship - CastTypes.DOUBLE, // ws_net_paid_inc_ship_tax - CastTypes.DOUBLE // ws_net_profit - }; - - public static final CastTypes[] websiteTypes = { - CastTypes.LONG, // web_site_sk - CastTypes.STRING, // web_site_id - CastTypes.DATE, // web_rec_start_date - CastTypes.DATE, // web_rec_end_date - CastTypes.STRING, // web_name - CastTypes.LONG, // web_open_date_sk - CastTypes.LONG, // web_close_date_sk - CastTypes.STRING, // web_class - CastTypes.STRING, // web_manager - CastTypes.LONG, // web_mkt_id - CastTypes.STRING, // web_mkt_class - CastTypes.STRING, // web_mkt_desc - CastTypes.STRING, // web_market_manager - CastTypes.LONG, // web_company_id - CastTypes.STRING, // web_company_name - CastTypes.STRING, // web_street_number - CastTypes.STRING, // web_street_name - CastTypes.STRING, // web_street_type - CastTypes.STRING, // web_suite_number - CastTypes.STRING, // web_city - CastTypes.STRING, // web_county - CastTypes.STRING, // web_state - CastTypes.STRING, // web_zip - CastTypes.STRING, // web_country - CastTypes.DOUBLE, // web_gmt_offset - CastTypes.DOUBLE // web_tax_percentage - }; + public static final CastTypes[] websalesTypes = { + CastTypes.LONG, // ws_sold_date_sk + CastTypes.LONG, // ws_sold_time_sk + CastTypes.LONG, // ws_ship_date_sk + CastTypes.LONG, // ws_item_sk + CastTypes.LONG, // ws_bill_customer_sk + CastTypes.LONG, // ws_bill_cdemo_sk + CastTypes.LONG, // ws_bill_hdemo_sk + CastTypes.LONG, // ws_bill_addr_sk + CastTypes.LONG, // ws_ship_customer_sk + CastTypes.LONG, // ws_ship_cdemo_sk + CastTypes.LONG, // ws_ship_hdemo_sk + CastTypes.LONG, // ws_ship_addr_sk + CastTypes.LONG, // ws_web_page_sk + CastTypes.LONG, // ws_web_site_sk + CastTypes.LONG, // ws_ship_mode_sk + CastTypes.LONG, // ws_warehouse_sk + CastTypes.LONG, // ws_promo_sk + CastTypes.LONG, // ws_order_number + CastTypes.LONG, // ws_quantity + CastTypes.DOUBLE, // ws_wholesale_cost + CastTypes.DOUBLE, // ws_list_price + CastTypes.DOUBLE, // ws_sales_price + CastTypes.DOUBLE, // ws_ext_discount_amt + CastTypes.DOUBLE, // ws_ext_sales_price + CastTypes.DOUBLE, // ws_ext_wholesale_cost + CastTypes.DOUBLE, // ws_ext_list_price + CastTypes.DOUBLE, // ws_ext_tax + CastTypes.DOUBLE, // ws_coupon_amt + CastTypes.DOUBLE, // ws_ext_ship_cost + CastTypes.DOUBLE, // ws_net_paid + CastTypes.DOUBLE, // ws_net_paid_inc_tax + CastTypes.DOUBLE, // ws_net_paid_inc_ship + CastTypes.DOUBLE, // ws_net_paid_inc_ship_tax + CastTypes.DOUBLE // ws_net_profit + }; + public static final CastTypes[] websiteTypes = { + CastTypes.LONG, // web_site_sk + CastTypes.STRING, // web_site_id + CastTypes.DATE, // web_rec_start_date + CastTypes.DATE, // web_rec_end_date + CastTypes.STRING, // web_name + CastTypes.LONG, // web_open_date_sk + CastTypes.LONG, // web_close_date_sk + CastTypes.STRING, // web_class + CastTypes.STRING, // web_manager + CastTypes.LONG, // web_mkt_id + CastTypes.STRING, // web_mkt_class + CastTypes.STRING, // web_mkt_desc + CastTypes.STRING, // web_market_manager + CastTypes.LONG, // web_company_id + CastTypes.STRING, // web_company_name + CastTypes.STRING, // web_street_number + CastTypes.STRING, // web_street_name + CastTypes.STRING, // web_street_type + CastTypes.STRING, // web_suite_number + CastTypes.STRING, // web_city + CastTypes.STRING, // web_county + CastTypes.STRING, // web_state + CastTypes.STRING, // web_zip + CastTypes.STRING, // web_country + CastTypes.DOUBLE, // web_gmt_offset + CastTypes.DOUBLE // web_tax_percentage + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSLoader.java index 770469c39..017b23036 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSLoader.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.io.BufferedReader; import java.io.File; import java.io.FileReader; @@ -35,565 +34,566 @@ import java.util.regex.Pattern; public final class TPCDSLoader extends Loader { - public TPCDSLoader(TPCDSBenchmark benchmark) { - super(benchmark); - } - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final CountDownLatch custAddrLatch = new CountDownLatch(1); - final CountDownLatch custDemLatch = new CountDownLatch(1); - final CountDownLatch dateLatch = new CountDownLatch(1); - final CountDownLatch incomeLatch = new CountDownLatch(1); - final CountDownLatch itemLatch = new CountDownLatch(1); - final CountDownLatch reasonLatch = new CountDownLatch(1); - final CountDownLatch shipModeLatch = new CountDownLatch(1); - final CountDownLatch timeLatch = new CountDownLatch(1); - final CountDownLatch warehouseLatch = new CountDownLatch(1); - final CountDownLatch promoLatch = new CountDownLatch(1); - final CountDownLatch householdLatch = new CountDownLatch(1); - final CountDownLatch storeLatch = new CountDownLatch(1); - final CountDownLatch customerLatch = new CountDownLatch(1); - final CountDownLatch webPageLatch = new CountDownLatch(1); - final CountDownLatch webSiteLatch = new CountDownLatch(1); - final CountDownLatch callCenterLatch = new CountDownLatch(1); - final CountDownLatch catalogPageLatch = new CountDownLatch(1); - final CountDownLatch storeSalesLatch = new CountDownLatch(1); - final CountDownLatch catalogSalesLatch = new CountDownLatch(1); - final CountDownLatch webSalesLatch = new CountDownLatch(1); - - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_CALLCENTER, TPCDSConstants.callcenterTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - callCenterLatch.countDown(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } + public TPCDSLoader(TPCDSBenchmark benchmark) { + super(benchmark); + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final CountDownLatch custAddrLatch = new CountDownLatch(1); + final CountDownLatch custDemLatch = new CountDownLatch(1); + final CountDownLatch dateLatch = new CountDownLatch(1); + final CountDownLatch incomeLatch = new CountDownLatch(1); + final CountDownLatch itemLatch = new CountDownLatch(1); + final CountDownLatch reasonLatch = new CountDownLatch(1); + final CountDownLatch shipModeLatch = new CountDownLatch(1); + final CountDownLatch timeLatch = new CountDownLatch(1); + final CountDownLatch warehouseLatch = new CountDownLatch(1); + final CountDownLatch promoLatch = new CountDownLatch(1); + final CountDownLatch householdLatch = new CountDownLatch(1); + final CountDownLatch storeLatch = new CountDownLatch(1); + final CountDownLatch customerLatch = new CountDownLatch(1); + final CountDownLatch webPageLatch = new CountDownLatch(1); + final CountDownLatch webSiteLatch = new CountDownLatch(1); + final CountDownLatch callCenterLatch = new CountDownLatch(1); + final CountDownLatch catalogPageLatch = new CountDownLatch(1); + final CountDownLatch storeSalesLatch = new CountDownLatch(1); + final CountDownLatch catalogSalesLatch = new CountDownLatch(1); + final CountDownLatch webSalesLatch = new CountDownLatch(1); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_CALLCENTER, TPCDSConstants.callcenterTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + callCenterLatch.countDown(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, TPCDSConstants.TABLENAME_CATALOGPAGE, TPCDSConstants.catalogpageTypes); + } - loadTable(conn, TPCDSConstants.TABLENAME_CATALOGPAGE, TPCDSConstants.catalogpageTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - catalogPageLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + dateLatch.await(); + catalogPageLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, TPCDSConstants.TABLENAME_STORE, TPCDSConstants.storeTypes); + } - loadTable(conn, TPCDSConstants.TABLENAME_STORE, TPCDSConstants.storeTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - storeLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + dateLatch.await(); + storeLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable(conn, TPCDSConstants.TABLENAME_WEBSITE, TPCDSConstants.websiteTypes); + } - loadTable(conn, TPCDSConstants.TABLENAME_WEBSITE, TPCDSConstants.websiteTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - webSiteLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + dateLatch.await(); + webSiteLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_HOUSEHOLDDEM, TPCDSConstants.householddemTypes); - } - - @Override - public void beforeLoad() { - try { - incomeLatch.await(); - householdLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable( + conn, TPCDSConstants.TABLENAME_HOUSEHOLDDEM, TPCDSConstants.householddemTypes); + } + + @Override + public void beforeLoad() { + try { + incomeLatch.await(); + householdLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_PROMOTION, TPCDSConstants.promotionTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - itemLatch.await(); - promoLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_PROMOTION, TPCDSConstants.promotionTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + itemLatch.await(); + promoLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_INVENTORY, TPCDSConstants.inventoryTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - itemLatch.await(); - warehouseLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_INVENTORY, TPCDSConstants.inventoryTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + itemLatch.await(); + warehouseLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_CUSTOMER, TPCDSConstants.customerTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - householdLatch.await(); - customerLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_CUSTOMER, TPCDSConstants.customerTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + householdLatch.await(); + customerLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - loadTable(conn, TPCDSConstants.TABLENAME_WEBPAGE, TPCDSConstants.webpageTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - customerLatch.await(); - webPageLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_WEBPAGE, TPCDSConstants.webpageTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + customerLatch.await(); + webPageLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_STORESALES, TPCDSConstants.storesalesTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - householdLatch.await(); - itemLatch.await(); - promoLatch.await(); - timeLatch.await(); - storeLatch.await(); - storeSalesLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_STORESALES, TPCDSConstants.storesalesTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + householdLatch.await(); + itemLatch.await(); + promoLatch.await(); + timeLatch.await(); + storeLatch.await(); + storeSalesLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_STORERETURNS, TPCDSConstants.storereturnsTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - householdLatch.await(); - itemLatch.await(); - reasonLatch.await(); - timeLatch.await(); - storeLatch.await(); - storeSalesLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable( + conn, TPCDSConstants.TABLENAME_STORERETURNS, TPCDSConstants.storereturnsTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + householdLatch.await(); + itemLatch.await(); + reasonLatch.await(); + timeLatch.await(); + storeLatch.await(); + storeSalesLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_WEBSALES, TPCDSConstants.websalesTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - householdLatch.await(); - itemLatch.await(); - promoLatch.await(); - timeLatch.await(); - webPageLatch.await(); - shipModeLatch.await(); - warehouseLatch.await(); - webSiteLatch.await(); - webSalesLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_WEBSALES, TPCDSConstants.websalesTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + householdLatch.await(); + itemLatch.await(); + promoLatch.await(); + timeLatch.await(); + webPageLatch.await(); + shipModeLatch.await(); + warehouseLatch.await(); + webSiteLatch.await(); + webSalesLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTable(conn, TPCDSConstants.TABLENAME_WEBRETURNS, TPCDSConstants.webreturnsTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - householdLatch.await(); - itemLatch.await(); - reasonLatch.await(); - timeLatch.await(); - webPageLatch.await(); - webSalesLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + + loadTable(conn, TPCDSConstants.TABLENAME_WEBRETURNS, TPCDSConstants.webreturnsTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + householdLatch.await(); + itemLatch.await(); + reasonLatch.await(); + timeLatch.await(); + webPageLatch.await(); + webSalesLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, TPCDSConstants.TABLENAME_CATALOGSALES, TPCDSConstants.catalogsalesTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - callCenterLatch.await(); - householdLatch.await(); - itemLatch.await(); - promoLatch.await(); - timeLatch.await(); - shipModeLatch.await(); - warehouseLatch.await(); - catalogPageLatch.await(); - catalogSalesLatch.countDown(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable( + conn, TPCDSConstants.TABLENAME_CATALOGSALES, TPCDSConstants.catalogsalesTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + callCenterLatch.await(); + householdLatch.await(); + itemLatch.await(); + promoLatch.await(); + timeLatch.await(); + shipModeLatch.await(); + warehouseLatch.await(); + catalogPageLatch.await(); + catalogSalesLatch.countDown(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadTable(conn, TPCDSConstants.TABLENAME_CATALOGRETURNS, TPCDSConstants.catalogreturnsTypes); - } - - @Override - public void beforeLoad() { - try { - dateLatch.await(); - custAddrLatch.await(); - custDemLatch.await(); - customerLatch.await(); - callCenterLatch.await(); - householdLatch.await(); - itemLatch.await(); - reasonLatch.await(); - timeLatch.await(); - shipModeLatch.await(); - warehouseLatch.await(); - catalogPageLatch.await(); - catalogSalesLatch.await(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadTable( + conn, TPCDSConstants.TABLENAME_CATALOGRETURNS, TPCDSConstants.catalogreturnsTypes); + } + + @Override + public void beforeLoad() { + try { + dateLatch.await(); + custAddrLatch.await(); + custDemLatch.await(); + customerLatch.await(); + callCenterLatch.await(); + householdLatch.await(); + itemLatch.await(); + reasonLatch.await(); + timeLatch.await(); + shipModeLatch.await(); + warehouseLatch.await(); + catalogPageLatch.await(); + catalogSalesLatch.await(); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } }); - return threads; + return threads; + } + + private String getFileFormat() { + String format = workConf.getXmlConfig().getString("fileFormat"); + /* + Previouse configuration migh not have a fileFormat and assume + that the files are csv. + */ + if (format == null) { + return "csv"; } - private String getFileFormat() { - String format = workConf.getXmlConfig().getString("fileFormat"); - /* - Previouse configuration migh not have a fileFormat and assume - that the files are csv. - */ - if (format == null) { - return "csv"; - } - - if ((!"csv".equals(format) && !"tbl".equals(format) && !"dat".equals(format))) { - throw new IllegalArgumentException("Configuration doesent" - + " have a valid fileFormat"); - } - return format; + if ((!"csv".equals(format) && !"tbl".equals(format) && !"dat".equals(format))) { + throw new IllegalArgumentException("Configuration doesent" + " have a valid fileFormat"); } - - private Pattern getFormatPattern(String format) { - - if ("csv".equals(format)) { - // The following pattern parses the lines by commas, except for - // ones surrounded by double-quotes. Further, strings that are - // double-quoted have the quotes dropped (we don't need them). - return Pattern.compile("\\s*(\"[^\"]*\"|[^,]*)\\s*,?"); - } else { - return Pattern.compile("[^\\|]*\\|"); - } + return format; + } + + private Pattern getFormatPattern(String format) { + + if ("csv".equals(format)) { + // The following pattern parses the lines by commas, except for + // ones surrounded by double-quotes. Further, strings that are + // double-quoted have the quotes dropped (we don't need them). + return Pattern.compile("\\s*(\"[^\"]*\"|[^,]*)\\s*,?"); + } else { + return Pattern.compile("[^\\|]*\\|"); } + } - private int getFormatGroup(String format) { - if ("csv".equals(format)) { - return 1; - } else { - return 0; - } + private int getFormatGroup(String format) { + if ("csv".equals(format)) { + return 1; + } else { + return 0; } - - - private void loadData(Connection conn, String table, PreparedStatement ps, TPCDSConstants.CastTypes[] types) { - - int batchSize = 0; - String line = ""; - String field = ""; - String format = getFileFormat(); - File file = new File(workConf.getDataDir() - , table + "." - + format); - try (BufferedReader br = new BufferedReader(new FileReader(file))) { - Pattern pattern = getFormatPattern(format); - int group = getFormatGroup(format); - Matcher matcher; - while ((line = br.readLine()) != null) { - matcher = pattern.matcher(line); - try { - for (int i = 0; i < types.length; ++i) { - matcher.find(); - field = matcher.group(group); - if (field.charAt(0) == '\"') { - field = field.substring(1, field.length() - 1); - } - - if (group == 0) { - field = field.substring(0, field.length() - 1); - } - //LOG.error(field + " " + i); - switch (types[i]) { - case DOUBLE: - if ("".equals(field)) { - ps.setDouble(i + 1, Double.NaN); - } else { - ps.setDouble(i + 1, Double.parseDouble(field)); - } - break; - case LONG: - if ("".equals(field)) { - ps.setLong(i + 1, Long.MIN_VALUE); - } else { - ps.setLong(i + 1, Long.parseLong(field)); - } - break; - case STRING: - ps.setString(i + 1, field); - break; - case DATE: - // Four possible formats for date - // yyyy-mm-dd - Pattern isoFmt = Pattern.compile("^\\s*(\\d{4})-(\\d{2})-(\\d{2})\\s*$"); - Matcher isoMatcher = isoFmt.matcher(field); - // yyyymmdd - Pattern nondelimFmt = Pattern.compile("^\\s*(\\d{4})(\\d{2})(\\d{2})\\s*$"); - Matcher nondelimMatcher = nondelimFmt.matcher(field); - // mm/dd/yyyy - Pattern usaFmt = Pattern.compile("^\\s*(\\d{2})/(\\d{2})/(\\d{4})\\s*$"); - Matcher usaMatcher = usaFmt.matcher(field); - // dd.mm.yyyy - Pattern eurFmt = Pattern.compile("^\\s*(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s*$"); - Matcher eurMatcher = eurFmt.matcher(field); - - String isoFmtDate = ""; - java.sql.Date fieldAsDate; - if (isoMatcher.find()) { - isoFmtDate = field; - } else if (nondelimMatcher.find()) { - isoFmtDate = nondelimMatcher.group(1) + "-" - + nondelimMatcher.group(2) + "-" - + nondelimMatcher.group(3); - } else if (usaMatcher.find()) { - isoFmtDate = usaMatcher.group(3) + "-" - + usaMatcher.group(1) + "-" - + usaMatcher.group(2); - } else if (eurMatcher.find()) { - isoFmtDate = eurMatcher.group(3) + "-" - + eurMatcher.group(2) + "-" - + eurMatcher.group(1); - } else if (!"".equals(field)) { - throw new RuntimeException("Unrecognized date \"" - + field + "\" in file: " - + file.getPath()); - } - fieldAsDate = "".equals(field) ? null : java.sql.Date.valueOf(isoFmtDate); - ps.setDate(i + 1, fieldAsDate, null); - break; - default: - throw new RuntimeException("Unrecognized type for prepared statement"); - } - - } - - ps.addBatch(); - if (++batchSize % workConf.getBatchSize() == 0) { - ps.executeBatch(); - ps.clearBatch(); - this.addToTableCount(table, batchSize); - batchSize = 0; - } - - } catch (IllegalStateException e) { - // This happens if there wasn't a match against the regex. - LOG.error("Invalid file: {}", file.getPath()); + } + + private void loadData( + Connection conn, String table, PreparedStatement ps, TPCDSConstants.CastTypes[] types) { + + int batchSize = 0; + String line = ""; + String field = ""; + String format = getFileFormat(); + File file = new File(workConf.getDataDir(), table + "." + format); + try (BufferedReader br = new BufferedReader(new FileReader(file))) { + Pattern pattern = getFormatPattern(format); + int group = getFormatGroup(format); + Matcher matcher; + while ((line = br.readLine()) != null) { + matcher = pattern.matcher(line); + try { + for (int i = 0; i < types.length; ++i) { + matcher.find(); + field = matcher.group(group); + if (field.charAt(0) == '\"') { + field = field.substring(1, field.length() - 1); + } + + if (group == 0) { + field = field.substring(0, field.length() - 1); + } + // LOG.error(field + " " + i); + switch (types[i]) { + case DOUBLE: + if ("".equals(field)) { + ps.setDouble(i + 1, Double.NaN); + } else { + ps.setDouble(i + 1, Double.parseDouble(field)); } - } - - if (batchSize > 0) { - this.addToTableCount(table, batchSize); - ps.executeBatch(); - ps.clearBatch(); - } - ps.close(); - if (LOG.isDebugEnabled()) { - LOG.debug("{} loaded", table); - } - - } catch (SQLException se) { - LOG.error("Failed to load data for TPC-DS: {}, LINE {}", field, line, se); - se = se.getNextException(); - if (se != null) { - LOG.error("{} Cause => {}", se.getClass().getSimpleName(), se.getMessage()); - } - } catch (Exception e) { - LOG.error(e.getMessage(), e); + break; + case LONG: + if ("".equals(field)) { + ps.setLong(i + 1, Long.MIN_VALUE); + } else { + ps.setLong(i + 1, Long.parseLong(field)); + } + break; + case STRING: + ps.setString(i + 1, field); + break; + case DATE: + // Four possible formats for date + // yyyy-mm-dd + Pattern isoFmt = Pattern.compile("^\\s*(\\d{4})-(\\d{2})-(\\d{2})\\s*$"); + Matcher isoMatcher = isoFmt.matcher(field); + // yyyymmdd + Pattern nondelimFmt = Pattern.compile("^\\s*(\\d{4})(\\d{2})(\\d{2})\\s*$"); + Matcher nondelimMatcher = nondelimFmt.matcher(field); + // mm/dd/yyyy + Pattern usaFmt = Pattern.compile("^\\s*(\\d{2})/(\\d{2})/(\\d{4})\\s*$"); + Matcher usaMatcher = usaFmt.matcher(field); + // dd.mm.yyyy + Pattern eurFmt = Pattern.compile("^\\s*(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s*$"); + Matcher eurMatcher = eurFmt.matcher(field); + + String isoFmtDate = ""; + java.sql.Date fieldAsDate; + if (isoMatcher.find()) { + isoFmtDate = field; + } else if (nondelimMatcher.find()) { + isoFmtDate = + nondelimMatcher.group(1) + + "-" + + nondelimMatcher.group(2) + + "-" + + nondelimMatcher.group(3); + } else if (usaMatcher.find()) { + isoFmtDate = + usaMatcher.group(3) + "-" + usaMatcher.group(1) + "-" + usaMatcher.group(2); + } else if (eurMatcher.find()) { + isoFmtDate = + eurMatcher.group(3) + "-" + eurMatcher.group(2) + "-" + eurMatcher.group(1); + } else if (!"".equals(field)) { + throw new RuntimeException( + "Unrecognized date \"" + field + "\" in file: " + file.getPath()); + } + fieldAsDate = "".equals(field) ? null : java.sql.Date.valueOf(isoFmtDate); + ps.setDate(i + 1, fieldAsDate, null); + break; + default: + throw new RuntimeException("Unrecognized type for prepared statement"); + } + } + + ps.addBatch(); + if (++batchSize % workConf.getBatchSize() == 0) { + ps.executeBatch(); + ps.clearBatch(); + this.addToTableCount(table, batchSize); + batchSize = 0; + } + + } catch (IllegalStateException e) { + // This happens if there wasn't a match against the regex. + LOG.error("Invalid file: {}", file.getPath()); } + } + + if (batchSize > 0) { + this.addToTableCount(table, batchSize); + ps.executeBatch(); + ps.clearBatch(); + } + ps.close(); + if (LOG.isDebugEnabled()) { + LOG.debug("{} loaded", table); + } + + } catch (SQLException se) { + LOG.error("Failed to load data for TPC-DS: {}, LINE {}", field, line, se); + se = se.getNextException(); + if (se != null) { + LOG.error("{} Cause => {}", se.getClass().getSimpleName(), se.getMessage()); + } + } catch (Exception e) { + LOG.error(e.getMessage(), e); } + } - private void loadTable(Connection conn, String tableName, TPCDSConstants.CastTypes[] types) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - + private void loadTable(Connection conn, String tableName, TPCDSConstants.CastTypes[] types) + throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - PreparedStatement prepStmt = conn.prepareStatement(sql); - loadData(conn, tableName, prepStmt, types); - } + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + PreparedStatement prepStmt = conn.prepareStatement(sql); + loadData(conn, tableName, prepStmt, types); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSWorker.java index 6216e76f1..c16c61a91 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/TPCDSWorker.java @@ -21,16 +21,15 @@ import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.types.TransactionStatus; - import java.sql.Connection; - public final class TPCDSWorker extends Worker { - public TPCDSWorker(TPCDSBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - } + public TPCDSWorker(TPCDSBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + } - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws Procedure.UserAbortException { - return null; - } + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws Procedure.UserAbortException { + return null; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/procedures/Test.java b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/procedures/Test.java index 0ca91d16f..d12fd17ac 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpcds/procedures/Test.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpcds/procedures/Test.java @@ -17,13 +17,10 @@ package com.oltpbenchmark.benchmarks.tpcds.procedures; - import com.oltpbenchmark.api.Procedure; - import java.sql.Connection; public class Test extends Procedure { - public void run(Connection conn, long incomeID) { - } + public void run(Connection conn, long incomeID) {} } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHBenchmark.java index 36a680c44..285d13378 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHBenchmark.java @@ -30,39 +30,37 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.tpch.procedures.Q1; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class TPCHBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(TPCHBenchmark.class); + private static final Logger LOG = LoggerFactory.getLogger(TPCHBenchmark.class); - public TPCHBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } - - @Override - protected Package getProcedurePackageImpl() { - return (Q1.class.getPackage()); - } + public TPCHBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); + @Override + protected Package getProcedurePackageImpl() { + return (Q1.class.getPackage()); + } - int numTerminals = workConf.getTerminals(); - LOG.info(String.format("Creating %d workers for TPC-H", numTerminals)); - for (int i = 0; i < numTerminals; i++) { - workers.add(new TPCHWorker(this, i)); - } - return workers; - } + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); - @Override - protected Loader makeLoaderImpl() { - return new TPCHLoader(this); + int numTerminals = workConf.getTerminals(); + LOG.info(String.format("Creating %d workers for TPC-H", numTerminals)); + for (int i = 0; i < numTerminals; i++) { + workers.add(new TPCHWorker(this, i)); } + return workers; + } + @Override + protected Loader makeLoaderImpl() { + return new TPCHLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHConstants.java index 08245fdbd..4b75742db 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHConstants.java @@ -19,61 +19,167 @@ public class TPCHConstants { - public static final String TABLENAME_REGION = "region"; - public static final String TABLENAME_NATION = "nation"; - public static final String TABLENAME_SUPPLIER = "supplier"; - public static final String TABLENAME_CUSTOMER = "customer"; - public static final String TABLENAME_PART = "part"; - public static final String TABLENAME_ORDER = "orders"; - public static final String TABLENAME_PARTSUPP = "partsupp"; - public static final String TABLENAME_LINEITEM = "lineitem"; + public static final String TABLENAME_REGION = "region"; + public static final String TABLENAME_NATION = "nation"; + public static final String TABLENAME_SUPPLIER = "supplier"; + public static final String TABLENAME_CUSTOMER = "customer"; + public static final String TABLENAME_PART = "part"; + public static final String TABLENAME_ORDER = "orders"; + public static final String TABLENAME_PARTSUPP = "partsupp"; + public static final String TABLENAME_LINEITEM = "lineitem"; - // 4.2.2.13 CONTAINERS SYLLABLE 1 - public static final String[] CONTAINERS_S1 = { "SM", "LG", "MED", "JUMBO", "WRAP" }; + // 4.2.2.13 CONTAINERS SYLLABLE 1 + public static final String[] CONTAINERS_S1 = {"SM", "LG", "MED", "JUMBO", "WRAP"}; - // 4.2.2.13 CONTAINERS SYLLABLE 2 - public static final String[] CONTAINERS_S2 = { "CASE", "BOX", "BAG", "JAR", "PKG", "PACK", "CAN", "DRUM" }; + // 4.2.2.13 CONTAINERS SYLLABLE 2 + public static final String[] CONTAINERS_S2 = { + "CASE", "BOX", "BAG", "JAR", "PKG", "PACK", "CAN", "DRUM" + }; - // 4.2.2.13 MODES - public static final String[] MODES = { "REG AIR", "AIR", "RAIL", "SHIP", "TRUCK", "MAIL", "FOB" }; + // 4.2.2.13 MODES + public static final String[] MODES = {"REG AIR", "AIR", "RAIL", "SHIP", "TRUCK", "MAIL", "FOB"}; - // 4.2.2.13 SEGMENTS - public static final String[] SEGMENTS = { "AUTOMOBILE", "BUILDING", "FURNITURE", "MACHINERY", "HOUSEHOLD" }; + // 4.2.2.13 SEGMENTS + public static final String[] SEGMENTS = { + "AUTOMOBILE", "BUILDING", "FURNITURE", "MACHINERY", "HOUSEHOLD" + }; - // 4.2.2.13 TYPE SYLLABLE 1 - public static final String[] TYPE_S1 = { "STANDARD", "SMALL", "MEDIUM", "LARGE", "ECONOMY", "PROMO" }; + // 4.2.2.13 TYPE SYLLABLE 1 + public static final String[] TYPE_S1 = { + "STANDARD", "SMALL", "MEDIUM", "LARGE", "ECONOMY", "PROMO" + }; - // 4.2.2.13 TYPE SYLLABLE 2 - public static final String[] TYPE_S2 = { "ANODIZED", "BURNISHED", "PLATED", "POLISHED", "BRUSHED" }; + // 4.2.2.13 TYPE SYLLABLE 2 + public static final String[] TYPE_S2 = {"ANODIZED", "BURNISHED", "PLATED", "POLISHED", "BRUSHED"}; - // 4.2.2.13 TYPE SYLLABLE 3 - public static final String[] TYPE_S3 = { "TIN", "NICKEL", "BRASS", "STEEL", "COPPER" }; + // 4.2.2.13 TYPE SYLLABLE 3 + public static final String[] TYPE_S3 = {"TIN", "NICKEL", "BRASS", "STEEL", "COPPER"}; - // 4.2.3 N_NAME - public static final String[] N_NAME = { "ALGERIA", "ARGENTINA", "BRAZIL", "CANADA", "EGYPT", "ETHIOPIA", - "FRANCE", "GERMANY", "INDIA", "INDONESIA", "IRAN", "IRAQ", "JAPAN", "JORDAN", "KENYA", - "MOROCCO", - "MOZAMBIQUE", "PERU", "CHINA", "ROMANIA", "SAUDI ARABIA", "VIETNAM", "RUSSIA", "UNITED KINGDOM", - "UNITED STATES" }; + // 4.2.3 N_NAME + public static final String[] N_NAME = { + "ALGERIA", + "ARGENTINA", + "BRAZIL", + "CANADA", + "EGYPT", + "ETHIOPIA", + "FRANCE", + "GERMANY", + "INDIA", + "INDONESIA", + "IRAN", + "IRAQ", + "JAPAN", + "JORDAN", + "KENYA", + "MOROCCO", + "MOZAMBIQUE", + "PERU", + "CHINA", + "ROMANIA", + "SAUDI ARABIA", + "VIETNAM", + "RUSSIA", + "UNITED KINGDOM", + "UNITED STATES" + }; - // 4.2.3 P_NAME generated by concatenating five of these - public static final String[] P_NAME_GENERATOR = { "almond", "antique", "aquamarine", "azure", "beige", "bisque", - "black", "blanched", "blue", - "blush", "brown", "burlywood", "burnished", "chartreuse", "chiffon", "chocolate", "coral", - "cornflower", "cornsilk", "cream", "cyan", "dark", "deep", "dim", "dodger", "drab", "firebrick", - "floral", "forest", "frosted", "gainsboro", "ghost", "goldenrod", "green", "grey", "honeydew", - "hot", "indian", "ivory", "khaki", "lace", "lavender", "lawn", "lemon", "light", "lime", - "linen", - "magenta", "maroon", "medium", "metallic", "midnight", "mint", "misty", "moccasin", "navajo", - "navy", "olive", "orange", "orchid", "pale", "papaya", "peach", "peru", "pink", "plum", - "powder", - "puff", "purple", "red", "rose", "rosy", "royal", "saddle", "salmon", "sandy", "seashell", - "sienna", - "sky", "slate", "smoke", "snow", "spring", "steel", "tan", "thistle", "tomato", "turquoise", - "violet", - "wheat", "white", "yellow" }; - - // 4.2.3 R_NAME - public static final String[] R_NAME = { "AFRICA", "AMERICA", "ASIA", "EUROPE", "MIDDLE EAST" }; + // 4.2.3 P_NAME generated by concatenating five of these + public static final String[] P_NAME_GENERATOR = { + "almond", + "antique", + "aquamarine", + "azure", + "beige", + "bisque", + "black", + "blanched", + "blue", + "blush", + "brown", + "burlywood", + "burnished", + "chartreuse", + "chiffon", + "chocolate", + "coral", + "cornflower", + "cornsilk", + "cream", + "cyan", + "dark", + "deep", + "dim", + "dodger", + "drab", + "firebrick", + "floral", + "forest", + "frosted", + "gainsboro", + "ghost", + "goldenrod", + "green", + "grey", + "honeydew", + "hot", + "indian", + "ivory", + "khaki", + "lace", + "lavender", + "lawn", + "lemon", + "light", + "lime", + "linen", + "magenta", + "maroon", + "medium", + "metallic", + "midnight", + "mint", + "misty", + "moccasin", + "navajo", + "navy", + "olive", + "orange", + "orchid", + "pale", + "papaya", + "peach", + "peru", + "pink", + "plum", + "powder", + "puff", + "purple", + "red", + "rose", + "rosy", + "royal", + "saddle", + "salmon", + "sandy", + "seashell", + "sienna", + "sky", + "slate", + "smoke", + "snow", + "spring", + "steel", + "tan", + "thistle", + "tomato", + "turquoise", + "violet", + "wheat", + "white", + "yellow" + }; + // 4.2.3 R_NAME + public static final String[] R_NAME = {"AFRICA", "AMERICA", "ASIA", "EUROPE", "MIDDLE EAST"}; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHLoader.java index 81b64ea29..2a4ea45d9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHLoader.java @@ -25,362 +25,386 @@ package com.oltpbenchmark.benchmarks.tpch; +import static com.oltpbenchmark.benchmarks.tpch.TPCHConstants.*; + import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.LoaderThread; -import static com.oltpbenchmark.benchmarks.tpch.TPCHConstants.*; -import com.oltpbenchmark.benchmarks.tpch.util.RegionGenerator; +import com.oltpbenchmark.benchmarks.tpch.util.CustomerGenerator; +import com.oltpbenchmark.benchmarks.tpch.util.LineItemGenerator; import com.oltpbenchmark.benchmarks.tpch.util.NationGenerator; +import com.oltpbenchmark.benchmarks.tpch.util.OrderGenerator; import com.oltpbenchmark.benchmarks.tpch.util.PartGenerator; import com.oltpbenchmark.benchmarks.tpch.util.PartSupplierGenerator; -import com.oltpbenchmark.benchmarks.tpch.util.OrderGenerator; -import com.oltpbenchmark.benchmarks.tpch.util.CustomerGenerator; -import com.oltpbenchmark.benchmarks.tpch.util.LineItemGenerator; +import com.oltpbenchmark.benchmarks.tpch.util.RegionGenerator; import com.oltpbenchmark.benchmarks.tpch.util.SupplierGenerator; -import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.catalog.Table; - +import com.oltpbenchmark.util.SQLUtil; import java.sql.*; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; public final class TPCHLoader extends Loader { - public TPCHLoader(TPCHBenchmark benchmark) { - super(benchmark); - } - - private enum CastTypes { - LONG, DOUBLE, STRING, DATE - } - - private static final CastTypes[] customerTypes = { CastTypes.LONG, // c_custkey - CastTypes.STRING, // c_name - CastTypes.STRING, // c_address - CastTypes.LONG, // c_nationkey - CastTypes.STRING, // c_phone - CastTypes.DOUBLE, // c_acctbal - CastTypes.STRING, // c_mktsegment - CastTypes.STRING // c_comment - }; - - private static final CastTypes[] lineitemTypes = { CastTypes.LONG, // l_orderkey - CastTypes.LONG, // l_partkey - CastTypes.LONG, // l_suppkey - CastTypes.LONG, // l_linenumber - CastTypes.DOUBLE, // l_quantity - CastTypes.DOUBLE, // l_extendedprice - CastTypes.DOUBLE, // l_discount - CastTypes.DOUBLE, // l_tax - CastTypes.STRING, // l_returnflag - CastTypes.STRING, // l_linestatus - CastTypes.DATE, // l_shipdate - CastTypes.DATE, // l_commitdate - CastTypes.DATE, // l_receiptdate - CastTypes.STRING, // l_shipinstruct - CastTypes.STRING, // l_shipmode - CastTypes.STRING // l_comment - }; - - private static final CastTypes[] nationTypes = { CastTypes.LONG, // n_nationkey - CastTypes.STRING, // n_name - CastTypes.LONG, // n_regionkey - CastTypes.STRING // n_comment - }; - - private static final CastTypes[] ordersTypes = { CastTypes.LONG, // o_orderkey - CastTypes.LONG, // o_LONG, custkey - CastTypes.STRING, // o_orderstatus - CastTypes.DOUBLE, // o_totalprice - CastTypes.DATE, // o_orderdate - CastTypes.STRING, // o_orderpriority - CastTypes.STRING, // o_clerk - CastTypes.LONG, // o_shippriority - CastTypes.STRING // o_comment - }; - - private static final CastTypes[] partTypes = { CastTypes.LONG, // p_partkey - CastTypes.STRING, // p_name - CastTypes.STRING, // p_mfgr - CastTypes.STRING, // p_brand - CastTypes.STRING, // p_type - CastTypes.LONG, // p_size - CastTypes.STRING, // p_container - CastTypes.DOUBLE, // p_retailprice - CastTypes.STRING // p_comment - }; - - private static final CastTypes[] partsuppTypes = { CastTypes.LONG, // ps_partkey - CastTypes.LONG, // ps_suppkey - CastTypes.LONG, // ps_availqty - CastTypes.DOUBLE, // ps_supplycost - CastTypes.STRING // ps_comment - }; - - private static final CastTypes[] regionTypes = { CastTypes.LONG, // r_regionkey - CastTypes.STRING, // r_name - CastTypes.STRING // r_comment - }; - - private static final CastTypes[] supplierTypes = { CastTypes.LONG, // s_suppkey - CastTypes.STRING, // s_name - CastTypes.STRING, // s_address - CastTypes.LONG, // s_nationkey - CastTypes.STRING, // s_phone - CastTypes.DOUBLE, // s_acctbal - CastTypes.STRING, // s_comment - }; - - private PreparedStatement getInsertStatement(Connection conn, String tableName) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(tableName); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - return conn.prepareStatement(sql); - } - - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - - final CountDownLatch regionLatch = new CountDownLatch(1); - final CountDownLatch nationLatch = new CountDownLatch(1); - final CountDownLatch ordersLatch = new CountDownLatch(1); - final CountDownLatch customerLatch = new CountDownLatch(1); - final CountDownLatch partsLatch = new CountDownLatch(1); - final CountDownLatch supplierLatch = new CountDownLatch(1); - final CountDownLatch partsSuppLatch = new CountDownLatch(1); - - final double scaleFactor = this.workConf.getScaleFactor(); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_REGION)) { - List>> regionGenerators = new ArrayList<>(); - regionGenerators.add(new RegionGenerator()); - - genTable(conn, statement, regionGenerators, regionTypes, TABLENAME_REGION); - } + public TPCHLoader(TPCHBenchmark benchmark) { + super(benchmark); + } + + private enum CastTypes { + LONG, + DOUBLE, + STRING, + DATE + } + + private static final CastTypes[] customerTypes = { + CastTypes.LONG, // c_custkey + CastTypes.STRING, // c_name + CastTypes.STRING, // c_address + CastTypes.LONG, // c_nationkey + CastTypes.STRING, // c_phone + CastTypes.DOUBLE, // c_acctbal + CastTypes.STRING, // c_mktsegment + CastTypes.STRING // c_comment + }; + + private static final CastTypes[] lineitemTypes = { + CastTypes.LONG, // l_orderkey + CastTypes.LONG, // l_partkey + CastTypes.LONG, // l_suppkey + CastTypes.LONG, // l_linenumber + CastTypes.DOUBLE, // l_quantity + CastTypes.DOUBLE, // l_extendedprice + CastTypes.DOUBLE, // l_discount + CastTypes.DOUBLE, // l_tax + CastTypes.STRING, // l_returnflag + CastTypes.STRING, // l_linestatus + CastTypes.DATE, // l_shipdate + CastTypes.DATE, // l_commitdate + CastTypes.DATE, // l_receiptdate + CastTypes.STRING, // l_shipinstruct + CastTypes.STRING, // l_shipmode + CastTypes.STRING // l_comment + }; + + private static final CastTypes[] nationTypes = { + CastTypes.LONG, // n_nationkey + CastTypes.STRING, // n_name + CastTypes.LONG, // n_regionkey + CastTypes.STRING // n_comment + }; + + private static final CastTypes[] ordersTypes = { + CastTypes.LONG, // o_orderkey + CastTypes.LONG, // o_LONG, custkey + CastTypes.STRING, // o_orderstatus + CastTypes.DOUBLE, // o_totalprice + CastTypes.DATE, // o_orderdate + CastTypes.STRING, // o_orderpriority + CastTypes.STRING, // o_clerk + CastTypes.LONG, // o_shippriority + CastTypes.STRING // o_comment + }; + + private static final CastTypes[] partTypes = { + CastTypes.LONG, // p_partkey + CastTypes.STRING, // p_name + CastTypes.STRING, // p_mfgr + CastTypes.STRING, // p_brand + CastTypes.STRING, // p_type + CastTypes.LONG, // p_size + CastTypes.STRING, // p_container + CastTypes.DOUBLE, // p_retailprice + CastTypes.STRING // p_comment + }; + + private static final CastTypes[] partsuppTypes = { + CastTypes.LONG, // ps_partkey + CastTypes.LONG, // ps_suppkey + CastTypes.LONG, // ps_availqty + CastTypes.DOUBLE, // ps_supplycost + CastTypes.STRING // ps_comment + }; + + private static final CastTypes[] regionTypes = { + CastTypes.LONG, // r_regionkey + CastTypes.STRING, // r_name + CastTypes.STRING // r_comment + }; + + private static final CastTypes[] supplierTypes = { + CastTypes.LONG, // s_suppkey + CastTypes.STRING, // s_name + CastTypes.STRING, // s_address + CastTypes.LONG, // s_nationkey + CastTypes.STRING, // s_phone + CastTypes.DOUBLE, // s_acctbal + CastTypes.STRING, // s_comment + }; + + private PreparedStatement getInsertStatement(Connection conn, String tableName) + throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(tableName); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + return conn.prepareStatement(sql); + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + + final CountDownLatch regionLatch = new CountDownLatch(1); + final CountDownLatch nationLatch = new CountDownLatch(1); + final CountDownLatch ordersLatch = new CountDownLatch(1); + final CountDownLatch customerLatch = new CountDownLatch(1); + final CountDownLatch partsLatch = new CountDownLatch(1); + final CountDownLatch supplierLatch = new CountDownLatch(1); + final CountDownLatch partsSuppLatch = new CountDownLatch(1); + + final double scaleFactor = this.workConf.getScaleFactor(); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_REGION)) { + List>> regionGenerators = new ArrayList<>(); + regionGenerators.add(new RegionGenerator()); + + genTable(conn, statement, regionGenerators, regionTypes, TABLENAME_REGION); } + } - @Override - public void afterLoad() { - regionLatch.countDown(); - } + @Override + public void afterLoad() { + regionLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_PART)) { - List>> partGenerators = new ArrayList<>(); - partGenerators.add(new PartGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_PART)) { + List>> partGenerators = new ArrayList<>(); + partGenerators.add(new PartGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, partGenerators, partTypes, TABLENAME_PART); - } + genTable(conn, statement, partGenerators, partTypes, TABLENAME_PART); } + } - @Override - public void afterLoad() { - partsLatch.countDown(); - } + @Override + public void afterLoad() { + partsLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_NATION)) { - List>> nationGenerators = new ArrayList<>(); - nationGenerators.add(new NationGenerator()); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_NATION)) { + List>> nationGenerators = new ArrayList<>(); + nationGenerators.add(new NationGenerator()); - genTable(conn, statement, nationGenerators, nationTypes, TABLENAME_NATION); - } + genTable(conn, statement, nationGenerators, nationTypes, TABLENAME_NATION); } + } - @Override - public void beforeLoad() { - try { - regionLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + regionLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - nationLatch.countDown(); - } + @Override + public void afterLoad() { + nationLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_SUPPLIER)) { - List>> supplierGenerators = new ArrayList<>(); - supplierGenerators.add(new SupplierGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_SUPPLIER)) { + List>> supplierGenerators = new ArrayList<>(); + supplierGenerators.add(new SupplierGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, supplierGenerators, supplierTypes, TABLENAME_SUPPLIER); - } + genTable(conn, statement, supplierGenerators, supplierTypes, TABLENAME_SUPPLIER); } + } - @Override - public void beforeLoad() { - try { - nationLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + nationLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - supplierLatch.countDown(); - } + @Override + public void afterLoad() { + supplierLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_CUSTOMER)) { - List>> customerGenerators = new ArrayList<>(); - customerGenerators.add(new CustomerGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_CUSTOMER)) { + List>> customerGenerators = new ArrayList<>(); + customerGenerators.add(new CustomerGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, customerGenerators, customerTypes, TABLENAME_CUSTOMER); - } + genTable(conn, statement, customerGenerators, customerTypes, TABLENAME_CUSTOMER); } + } - @Override - public void beforeLoad() { - try { - nationLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + nationLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - customerLatch.countDown(); - } + @Override + public void afterLoad() { + customerLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_ORDER)) { - List>> orderGenerators = new ArrayList<>(); - orderGenerators.add(new OrderGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_ORDER)) { + List>> orderGenerators = new ArrayList<>(); + orderGenerators.add(new OrderGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, orderGenerators, ordersTypes, TABLENAME_ORDER); - } + genTable(conn, statement, orderGenerators, ordersTypes, TABLENAME_ORDER); } + } - @Override - public void beforeLoad() { - try { - customerLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + customerLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - ordersLatch.countDown(); - } + @Override + public void afterLoad() { + ordersLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_PARTSUPP)) { - List>> partSuppGenerators = new ArrayList<>(); - partSuppGenerators.add(new PartSupplierGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_PARTSUPP)) { + List>> partSuppGenerators = new ArrayList<>(); + partSuppGenerators.add(new PartSupplierGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, partSuppGenerators, partsuppTypes, TABLENAME_PARTSUPP); - } + genTable(conn, statement, partSuppGenerators, partsuppTypes, TABLENAME_PARTSUPP); } + } - @Override - public void beforeLoad() { - try { - partsLatch.await(); - supplierLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + partsLatch.await(); + supplierLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } - @Override - public void afterLoad() { - partsSuppLatch.countDown(); - } + @Override + public void afterLoad() { + partsSuppLatch.countDown(); + } }); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_LINEITEM)) { - List>> lineItemGenerators = new ArrayList<>(); - lineItemGenerators.add(new LineItemGenerator(scaleFactor, 1, 1)); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + try (PreparedStatement statement = getInsertStatement(conn, TABLENAME_LINEITEM)) { + List>> lineItemGenerators = new ArrayList<>(); + lineItemGenerators.add(new LineItemGenerator(scaleFactor, 1, 1)); - genTable(conn, statement, lineItemGenerators, lineitemTypes, TABLENAME_LINEITEM); - } + genTable(conn, statement, lineItemGenerators, lineitemTypes, TABLENAME_LINEITEM); } + } - @Override - public void beforeLoad() { - try { - ordersLatch.await(); - partsSuppLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + @Override + public void beforeLoad() { + try { + ordersLatch.await(); + partsSuppLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } }); - return threads; - } - - private void genTable(Connection conn, PreparedStatement prepStmt, List>> generators, - CastTypes[] types, String tableName) { - for (Iterable> generator : generators) { - try { - int recordsRead = 0; - for (List elems : generator) { - for (int idx = 0; idx < types.length; idx++) { - final CastTypes type = types[idx]; - switch (type) { - case DOUBLE: - prepStmt.setDouble(idx + 1, (Double) elems.get(idx)); - break; - case LONG: - prepStmt.setLong(idx + 1, (Long) elems.get(idx)); - break; - case STRING: - prepStmt.setString(idx + 1, (String) elems.get(idx)); - break; - case DATE: - prepStmt.setDate(idx + 1, (Date) elems.get(idx)); - break; - default: - throw new RuntimeException("Unrecognized type for prepared statement"); - } - } - - ++recordsRead; - prepStmt.addBatch(); - if ((recordsRead % workConf.getBatchSize()) == 0) { - - LOG.debug("writing batch {} for table {}", recordsRead, tableName); - - prepStmt.executeBatch(); - prepStmt.clearBatch(); - } - } - - prepStmt.executeBatch(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); + return threads; + } + + private void genTable( + Connection conn, + PreparedStatement prepStmt, + List>> generators, + CastTypes[] types, + String tableName) { + for (Iterable> generator : generators) { + try { + int recordsRead = 0; + for (List elems : generator) { + for (int idx = 0; idx < types.length; idx++) { + final CastTypes type = types[idx]; + switch (type) { + case DOUBLE: + prepStmt.setDouble(idx + 1, (Double) elems.get(idx)); + break; + case LONG: + prepStmt.setLong(idx + 1, (Long) elems.get(idx)); + break; + case STRING: + prepStmt.setString(idx + 1, (String) elems.get(idx)); + break; + case DATE: + prepStmt.setDate(idx + 1, (Date) elems.get(idx)); + break; + default: + throw new RuntimeException("Unrecognized type for prepared statement"); } + } + + ++recordsRead; + prepStmt.addBatch(); + if ((recordsRead % workConf.getBatchSize()) == 0) { + + LOG.debug("writing batch {} for table {}", recordsRead, tableName); + + prepStmt.executeBatch(); + prepStmt.clearBatch(); + } } + + prepStmt.executeBatch(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHUtil.java index cd6cbb73c..c72ce9f39 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHUtil.java @@ -21,97 +21,95 @@ public class TPCHUtil { - /** - * Returns a random element of the array - * - * @param array - * @param rand - * @param - * @return a random element of the array - */ - public static T choice(T[] array, RandomGenerator rand) { - return array[rand.number(1, array.length) - 1]; - } + /** + * Returns a random element of the array + * + * @param array + * @param rand + * @param + * @return a random element of the array + */ + public static T choice(T[] array, RandomGenerator rand) { + return array[rand.number(1, array.length) - 1]; + } - /** - * Returns the region key given the nation - * - * @param nation N_NAME - * @return region key - */ - public static int getRegionKeyFromNation(String nation) { - switch (nation) { - case "ALGERIA": - case "ETHIOPIA": - case "KENYA": - case "MOROCCO": - case "MOZAMBIQUE": - return 0; - case "ARGENTINA": - case "BRAZIL": - case "CANADA": - case "PERU": - case "UNITED STATES": - return 1; - case "INDIA": - case "INDONESIA": - case "JAPAN": - case "CHINA": - case "VIETNAM": - return 2; - case "FRANCE": - case "GERMANY": - case "ROMANIA": - case "RUSSIA": - case "UNITED KINGDOM": - return 3; - case "EGYPT": - case "IRAN": - case "IRAQ": - case "JORDAN": - case "SAUDI ARABIA": - return 4; - default: - throw new IllegalArgumentException(String.format("Invalid nation %s", nation)); - } + /** + * Returns the region key given the nation + * + * @param nation N_NAME + * @return region key + */ + public static int getRegionKeyFromNation(String nation) { + switch (nation) { + case "ALGERIA": + case "ETHIOPIA": + case "KENYA": + case "MOROCCO": + case "MOZAMBIQUE": + return 0; + case "ARGENTINA": + case "BRAZIL": + case "CANADA": + case "PERU": + case "UNITED STATES": + return 1; + case "INDIA": + case "INDONESIA": + case "JAPAN": + case "CHINA": + case "VIETNAM": + return 2; + case "FRANCE": + case "GERMANY": + case "ROMANIA": + case "RUSSIA": + case "UNITED KINGDOM": + return 3; + case "EGYPT": + case "IRAN": + case "IRAQ": + case "JORDAN": + case "SAUDI ARABIA": + return 4; + default: + throw new IllegalArgumentException(String.format("Invalid nation %s", nation)); } + } - /** - * Returns the region given the region key - * - * @param regionKey region key - * @return region - */ - public static String getRegionFromRegionKey(int regionKey) { - switch (regionKey) { - case 0: - return "AFRICA"; - case 1: - return "AMERICA"; - case 2: - return "ASIA"; - case 3: - return "EUROPE"; - case 4: - return "MIDDLE EAST"; - default: - throw new IllegalArgumentException(String.format("Invalid region key %s", regionKey)); - } + /** + * Returns the region given the region key + * + * @param regionKey region key + * @return region + */ + public static String getRegionFromRegionKey(int regionKey) { + switch (regionKey) { + case 0: + return "AFRICA"; + case 1: + return "AMERICA"; + case 2: + return "ASIA"; + case 3: + return "EUROPE"; + case 4: + return "MIDDLE EAST"; + default: + throw new IllegalArgumentException(String.format("Invalid region key %s", regionKey)); } + } - /** - * Generates a random brand string of the form 'Brand#MN' where M and N are - * two single character strings representing two numbers randomly and - * independently selected within [1 .. 5] - * - * @param rand Random generator to use - * @return A random brand conforming to the TPCH specification - */ - public static String randomBrand(RandomGenerator rand) { - int M = rand.number(1, 5); - int N = rand.number(1, 5); - - return String.format("Brand#%d%d", M, N); - } + /** + * Generates a random brand string of the form 'Brand#MN' where M and N are two single character + * strings representing two numbers randomly and independently selected within [1 .. 5] + * + * @param rand Random generator to use + * @return A random brand conforming to the TPCH specification + */ + public static String randomBrand(RandomGenerator rand) { + int M = rand.number(1, 5); + int N = rand.number(1, 5); + return String.format("Brand#%d%d", M, N); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHWorker.java index 9c115c93a..df7c45041 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/TPCHWorker.java @@ -23,31 +23,29 @@ import com.oltpbenchmark.benchmarks.tpch.procedures.GenericQuery; import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.SQLException; public final class TPCHWorker extends Worker { - private final RandomGenerator rand; - - public TPCHWorker(TPCHBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - this.rng().setSeed(15721); - rand = new RandomGenerator(this.rng().nextInt()); + private final RandomGenerator rand; + + public TPCHWorker(TPCHBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + this.rng().setSeed(15721); + rand = new RandomGenerator(this.rng().nextInt()); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) + throws UserAbortException, SQLException { + try { + GenericQuery proc = (GenericQuery) this.getProcedure(nextTransaction.getProcedureClass()); + proc.run(conn, rand, this.configuration.getScaleFactor()); + } catch (ClassCastException e) { + throw new RuntimeException(e); } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) throws UserAbortException, SQLException { - try { - GenericQuery proc = (GenericQuery) this.getProcedure(nextTransaction.getProcedureClass()); - proc.run(conn, rand, this.configuration.getScaleFactor()); - } catch (ClassCastException e) { - throw new RuntimeException(e); - } - - return (TransactionStatus.SUCCESS); - - } + return (TransactionStatus.SUCCESS); + } } - diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/GenericQuery.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/GenericQuery.java index 157d6c258..2599a59d9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/GenericQuery.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/GenericQuery.java @@ -19,34 +19,33 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.util.RandomGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLSyntaxErrorException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class GenericQuery extends Procedure { - protected static final Logger LOG = LoggerFactory.getLogger(GenericQuery.class); + protected static final Logger LOG = LoggerFactory.getLogger(GenericQuery.class); - protected abstract PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException; + protected abstract PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException; - public void run(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - try (PreparedStatement stmt = getStatement(conn, rand, scaleFactor)) { - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - //do nothing - } - } - catch (SQLSyntaxErrorException ex) { - if (LOG.isDebugEnabled()) { - LOG.debug(this.getClass().getName() + ": stmt: " + stmt.toString()); - } - throw ex; - } + public void run(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + try (PreparedStatement stmt = getStatement(conn, rand, scaleFactor)) { + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + // do nothing + } + } catch (SQLSyntaxErrorException ex) { + if (LOG.isDebugEnabled()) { + LOG.debug(this.getClass().getName() + ": stmt: " + stmt.toString()); } + throw ex; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q1.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q1.java index d6d901576..6c0428d06 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q1.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q1.java @@ -19,14 +19,15 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q1 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT l_returnflag, l_linestatus, @@ -48,15 +49,15 @@ public class Q1 extends GenericQuery { ORDER BY l_returnflag, l_linestatus - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - String delta = String.valueOf(rand.number(60, 120)); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + String delta = String.valueOf(rand.number(60, 120)); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, delta); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, delta); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q10.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q10.java index 4ecac97d8..fc3a98a80 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q10.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q10.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -27,7 +26,9 @@ public class Q10 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT c_custkey, c_name, @@ -59,19 +60,20 @@ public class Q10 extends GenericQuery { c_comment ORDER BY revenue DESC LIMIT 20 - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // DATE is the first day of a randomly selected month from the second month of 1993 to the first month of 1995 - int year = rand.number(1993, 1995); - int month = rand.number(year == 1993 ? 2 : 1, year == 1995 ? 1 : 12); - String date = String.format("%d-%02d-01", year, month); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // DATE is the first day of a randomly selected month from the second month of 1993 to the first + // month of 1995 + int year = rand.number(1993, 1995); + int month = rand.number(year == 1993 ? 2 : 1, year == 1995 ? 1 : 12); + String date = String.format("%d-%02d-01", year, month); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setDate(1, Date.valueOf(date)); - stmt.setDate(2, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setDate(1, Date.valueOf(date)); + stmt.setDate(2, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q11.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q11.java index 131c151f7..11efd5d89 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q11.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q11.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q11 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT ps_partkey, SUM(ps_supplycost * ps_availqty) AS VALUE @@ -54,21 +55,21 @@ public class Q11 extends GenericQuery { AND n_name = ? ) ORDER BY VALUE DESC - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - // FRACTION is chosen as 0.0001 / SF - double fraction = 0.0001 / scaleFactor; + // FRACTION is chosen as 0.0001 / SF + double fraction = 0.0001 / scaleFactor; - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, nation); - stmt.setDouble(2, fraction); - stmt.setString(3, nation); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, nation); + stmt.setDouble(2, fraction); + stmt.setString(3, nation); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q12.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q12.java index b394cd2b7..680fb27d9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q12.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q12.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -29,7 +28,9 @@ public class Q12 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT l_shipmode, SUM( @@ -66,30 +67,31 @@ AND l_shipmode IN (?, ?) l_shipmode ORDER BY l_shipmode - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // SHIPMODE1 is randomly selected within the list of values defined for Modes in Clause 4.2.2.13 - String shipMode1 = TPCHUtil.choice(TPCHConstants.MODES, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // SHIPMODE1 is randomly selected within the list of values defined for Modes in Clause 4.2.2.13 + String shipMode1 = TPCHUtil.choice(TPCHConstants.MODES, rand); - // SHIPMODE2 is randomly selected within the list of values defined for Modes in Clause 4.2.2.13 and must be - // different from the value selected for SHIPMODE1 in item 1 - String shipMode2 = shipMode1; - while (shipMode1.equals(shipMode2)) { - shipMode2 = TPCHUtil.choice(TPCHConstants.MODES, rand); - } + // SHIPMODE2 is randomly selected within the list of values defined for Modes in Clause 4.2.2.13 + // and must be + // different from the value selected for SHIPMODE1 in item 1 + String shipMode2 = shipMode1; + while (shipMode1.equals(shipMode2)) { + shipMode2 = TPCHUtil.choice(TPCHConstants.MODES, rand); + } - // DATE is the first of January of a randomly selected year within [1993 .. 1997] - int year = rand.number(1993, 1997); - String date = String.format("%d-01-01", year); + // DATE is the first of January of a randomly selected year within [1993 .. 1997] + int year = rand.number(1993, 1997); + String date = String.format("%d-01-01", year); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, shipMode1); - stmt.setString(2, shipMode2); - stmt.setDate(3, Date.valueOf(date)); - stmt.setDate(4, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, shipMode1); + stmt.setString(2, shipMode2); + stmt.setDate(3, Date.valueOf(date)); + stmt.setDate(4, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q13.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q13.java index 21e228cfd..15f3c4375 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q13.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q13.java @@ -20,14 +20,15 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q13 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT c_count, COUNT(*) AS custdist @@ -51,21 +52,22 @@ public class Q13 extends GenericQuery { ORDER BY custdist DESC, c_count DESC - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // WORD1 is randomly selected from 4 possible values: special, pending, unusual, express - String word1 = TPCHUtil.choice(new String[]{"special", "pending", "unusual", "express"}, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // WORD1 is randomly selected from 4 possible values: special, pending, unusual, express + String word1 = TPCHUtil.choice(new String[] {"special", "pending", "unusual", "express"}, rand); - // WORD2 is randomly selected from 4 possible values: packages, requests, accounts, deposits - String word2 = TPCHUtil.choice(new String[]{"packages", "requests", "accounts", "deposits"}, rand); + // WORD2 is randomly selected from 4 possible values: packages, requests, accounts, deposits + String word2 = + TPCHUtil.choice(new String[] {"packages", "requests", "accounts", "deposits"}, rand); - String filter = "%" + word1 + "%" + word2 + "%"; + String filter = "%" + word1 + "%" + word2 + "%"; - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, filter); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, filter); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q14.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q14.java index 9f32516ff..534b565f7 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q14.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q14.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -27,7 +26,9 @@ public class Q14 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT 100.00 * SUM( CASE @@ -45,19 +46,19 @@ public class Q14 extends GenericQuery { l_partkey = p_partkey AND l_shipdate >= DATE ? AND l_shipdate < DATE ? + INTERVAL '1' MONTH - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // DATE is the first day of a month randomly selected from a random year within [1993 .. 1997] - int year = rand.number(1993, 1997); - int month = rand.number(1, 12); - String date = String.format("%d-%02d-01", year, month); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // DATE is the first day of a month randomly selected from a random year within [1993 .. 1997] + int year = rand.number(1993, 1997); + int month = rand.number(1, 12); + String date = String.format("%d-%02d-01", year, month); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setDate(1, Date.valueOf(date)); - stmt.setDate(2, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setDate(1, Date.valueOf(date)); + stmt.setDate(2, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q15.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q15.java index 5aca587c1..972fde693 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q15.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q15.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -27,7 +26,9 @@ public class Q15 extends GenericQuery { - public final SQLStmt createview_stmt = new SQLStmt(""" + public final SQLStmt createview_stmt = + new SQLStmt( + """ CREATE view revenue0 (supplier_no, total_revenue) AS SELECT l_suppkey, @@ -39,10 +40,11 @@ CREATE view revenue0 (supplier_no, total_revenue) AS AND l_shipdate < DATE ? + INTERVAL '3' MONTH GROUP BY l_suppkey - """ - ); + """); - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT s_suppkey, s_name, @@ -62,40 +64,39 @@ CREATE view revenue0 (supplier_no, total_revenue) AS ) ORDER BY s_suppkey - """ - ); + """); - public final SQLStmt dropview_stmt = new SQLStmt(""" + public final SQLStmt dropview_stmt = + new SQLStmt(""" DROP VIEW revenue0 - """ - ); - - @Override - public void run(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // With this query, we have to set up a view before we execute the - // query, then drop it once we're done. - try (Statement stmt = conn.createStatement()) { - try { - // DATE is the first day of a randomly selected month between - // the first month of 1993 and the 10th month of 1997 - int year = rand.number(1993, 1997); - int month = rand.number(1, year == 1997 ? 10 : 12); - String date = String.format("%d-%02d-01", year, month); + """); - String sql = createview_stmt.getSQL(); - sql = sql.replace("?", String.format("'%s'", date)); - stmt.execute(sql); - super.run(conn, rand, scaleFactor); - } finally { - String sql = dropview_stmt.getSQL(); - stmt.execute(sql); - } - } + @Override + public void run(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // With this query, we have to set up a view before we execute the + // query, then drop it once we're done. + try (Statement stmt = conn.createStatement()) { + try { + // DATE is the first day of a randomly selected month between + // the first month of 1993 and the 10th month of 1997 + int year = rand.number(1993, 1997); + int month = rand.number(1, year == 1997 ? 10 : 12); + String date = String.format("%d-%02d-01", year, month); + String sql = createview_stmt.getSQL(); + sql = sql.replace("?", String.format("'%s'", date)); + stmt.execute(sql); + super.run(conn, rand, scaleFactor); + } finally { + String sql = dropview_stmt.getSQL(); + stmt.execute(sql); + } } + } - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - return this.getPreparedStatement(conn, query_stmt); - } + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + return this.getPreparedStatement(conn, query_stmt); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q16.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q16.java index 70487115f..32d1b8665 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q16.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q16.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -30,7 +29,9 @@ public class Q16 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT p_brand, p_type, @@ -62,42 +63,42 @@ AND p_size IN (?, ?, ?, ?, ?, ?, ?, ?) p_brand, p_type, p_size - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - String brand = TPCHUtil.randomBrand(rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + String brand = TPCHUtil.randomBrand(rand); - // TYPE is made of the first 2 syllables of a string randomly selected within the - // list of 3-syllable strings defined for Types in Clause 4.2.2.13 - String syllable1 = TPCHUtil.choice(TPCHConstants.TYPE_S1, rand); - String syllable2 = TPCHUtil.choice(TPCHConstants.TYPE_S2, rand); - String type = String.format("%s %s", syllable1, syllable2) + "%"; + // TYPE is made of the first 2 syllables of a string randomly selected within the + // list of 3-syllable strings defined for Types in Clause 4.2.2.13 + String syllable1 = TPCHUtil.choice(TPCHConstants.TYPE_S1, rand); + String syllable2 = TPCHUtil.choice(TPCHConstants.TYPE_S2, rand); + String type = String.format("%s %s", syllable1, syllable2) + "%"; - // SIZE_n is randomly selected as a set of eight different values within [1 .. 50] - // for n in [1,8] + // SIZE_n is randomly selected as a set of eight different values within [1 .. 50] + // for n in [1,8] - int[] sizes = new int[8]; - Set seen = new HashSet<>(8); + int[] sizes = new int[8]; + Set seen = new HashSet<>(8); - for (int i = 0; i < 8; i++) { - int num = rand.number(1, 50); + for (int i = 0; i < 8; i++) { + int num = rand.number(1, 50); - while (seen.contains(num)) { - num = rand.number(1, 50); - } + while (seen.contains(num)) { + num = rand.number(1, 50); + } - sizes[i] = num; - seen.add(num); - } + sizes[i] = num; + seen.add(num); + } - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, brand); - stmt.setString(2, type); - for (int i = 0; i < 8; i++) { - stmt.setInt(3 + i, sizes[i]); - } - return stmt; + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, brand); + stmt.setString(2, type); + for (int i = 0; i < 8; i++) { + stmt.setInt(3 + i, sizes[i]); } + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q17.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q17.java index c72fcb4ab..767e792be 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q17.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q17.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q17 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT SUM(l_extendedprice) / 7.0 AS avg_yearly FROM @@ -45,22 +46,23 @@ public class Q17 extends GenericQuery { lineitem WHERE l_partkey = p_partkey ) - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - String brand = TPCHUtil.randomBrand(rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + String brand = TPCHUtil.randomBrand(rand); - // CONTAINER is randomly selected within the list of 2-syllable strings defined for Containers in Clause - // 4.2.2.13 - String containerS1 = TPCHUtil.choice(TPCHConstants.CONTAINERS_S1, rand); - String containerS2 = TPCHUtil.choice(TPCHConstants.CONTAINERS_S2, rand); - String container = String.format("%s %s", containerS1, containerS2); + // CONTAINER is randomly selected within the list of 2-syllable strings defined for Containers + // in Clause + // 4.2.2.13 + String containerS1 = TPCHUtil.choice(TPCHConstants.CONTAINERS_S1, rand); + String containerS2 = TPCHUtil.choice(TPCHConstants.CONTAINERS_S2, rand); + String container = String.format("%s %s", containerS1, containerS2); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, brand); - stmt.setString(2, container); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, brand); + stmt.setString(2, container); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q18.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q18.java index 5ae8bc433..3e793498b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q18.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q18.java @@ -19,14 +19,15 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q18 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT c_name, c_custkey, @@ -61,16 +62,16 @@ public class Q18 extends GenericQuery { ORDER BY o_totalprice DESC, o_orderdate LIMIT 100 - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // QUANTITY is randomly selected within [312..315] - int quantity = rand.number(312, 315); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // QUANTITY is randomly selected within [312..315] + int quantity = rand.number(312, 315); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setInt(1, quantity); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setInt(1, quantity); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q19.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q19.java index fbb93e04d..250067619 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q19.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q19.java @@ -20,14 +20,15 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q19 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT SUM(l_extendedprice* (1 - l_discount)) AS revenue FROM @@ -66,36 +67,37 @@ AND p_container IN ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') AND l_shipmode IN ('AIR', 'AIR REG') AND l_shipinstruct = 'DELIVER IN PERSON' ) - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // QUANTITY1 is randomly selected within [1..10] - int quantity1 = rand.number(1, 10); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // QUANTITY1 is randomly selected within [1..10] + int quantity1 = rand.number(1, 10); - // QUANTITY2 is randomly selected within [10..20] - int quantity2 = rand.number(10, 20); + // QUANTITY2 is randomly selected within [10..20] + int quantity2 = rand.number(10, 20); - // QUANTITY3 is randomly selected within [20..30] - int quantity3 = rand.number(20, 30); + // QUANTITY3 is randomly selected within [20..30] + int quantity3 = rand.number(20, 30); - // BRAND1, BRAND2, BRAND3 = 'Brand#MN' where each MN is a two character string representing two numbers - // randomly and independently selected within [1 .. 5] - String brand1 = TPCHUtil.randomBrand(rand); - String brand2 = TPCHUtil.randomBrand(rand); - String brand3 = TPCHUtil.randomBrand(rand); + // BRAND1, BRAND2, BRAND3 = 'Brand#MN' where each MN is a two character string representing two + // numbers + // randomly and independently selected within [1 .. 5] + String brand1 = TPCHUtil.randomBrand(rand); + String brand2 = TPCHUtil.randomBrand(rand); + String brand3 = TPCHUtil.randomBrand(rand); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, brand1); - stmt.setInt(2, quantity1); - stmt.setInt(3, quantity1); - stmt.setString(4, brand2); - stmt.setInt(5, quantity2); - stmt.setInt(6, quantity2); - stmt.setString(7, brand3); - stmt.setInt(8, quantity3); - stmt.setInt(9, quantity3); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, brand1); + stmt.setInt(2, quantity1); + stmt.setInt(3, quantity1); + stmt.setString(4, brand2); + stmt.setInt(5, quantity2); + stmt.setInt(6, quantity2); + stmt.setString(7, brand3); + stmt.setInt(8, quantity3); + stmt.setInt(9, quantity3); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q2.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q2.java index ff3b55bda..c9a6369cb 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q2.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q2.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q2 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT s_acctbal, s_name, @@ -73,20 +74,20 @@ public class Q2 extends GenericQuery { n_name, s_name, p_partkey LIMIT 100 - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - int size = rand.number(1, 50); - String type = TPCHUtil.choice(TPCHConstants.TYPE_S3, rand); - String region = TPCHUtil.choice(TPCHConstants.R_NAME, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + int size = rand.number(1, 50); + String type = TPCHUtil.choice(TPCHConstants.TYPE_S3, rand); + String region = TPCHUtil.choice(TPCHConstants.R_NAME, rand); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setInt(1, size); - stmt.setString(2, "%" + type); - stmt.setString(3, region); - stmt.setString(4, region); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setInt(1, size); + stmt.setString(2, "%" + type); + stmt.setString(3, region); + stmt.setString(4, region); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q20.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q20.java index 5cb274589..dd348278d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q20.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q20.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -29,7 +28,9 @@ public class Q20 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT s_name, s_address @@ -68,26 +69,26 @@ public class Q20 extends GenericQuery { AND n_name = ? ORDER BY s_name - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // COLOR is randomly selected within the list of values defined for the generation of P_NAME - String color = TPCHUtil.choice(TPCHConstants.P_NAME_GENERATOR, rand) + "%"; + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // COLOR is randomly selected within the list of values defined for the generation of P_NAME + String color = TPCHUtil.choice(TPCHConstants.P_NAME_GENERATOR, rand) + "%"; - // DATE is the first of January of a randomly selected year within 1993..1997 - int year = rand.number(1993, 1997); - String date = String.format("%d-01-01", year); + // DATE is the first of January of a randomly selected year within 1993..1997 + int year = rand.number(1993, 1997); + String date = String.format("%d-01-01", year); - // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); + // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, color); - stmt.setDate(2, Date.valueOf(date)); - stmt.setDate(3, Date.valueOf(date)); - stmt.setString(4, nation); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, color); + stmt.setDate(2, Date.valueOf(date)); + stmt.setDate(3, Date.valueOf(date)); + stmt.setString(4, nation); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q21.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q21.java index eeacb04ac..5f7544ffa 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q21.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q21.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q21 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT s_name, COUNT(*) AS numwait @@ -70,16 +71,16 @@ public class Q21 extends GenericQuery { ORDER BY numwait DESC, s_name LIMIT 100 - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, nation); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, nation); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q22.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q22.java index 6b29285df..adafc4d1e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q22.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q22.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -28,7 +27,9 @@ public class Q22 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT cntrycode, COUNT(*) AS numcust, @@ -67,40 +68,39 @@ AND SUBSTRING(c_phone FROM 1 FOR 2) IN (?, ?, ?, ?, ?, ?, ?) cntrycode ORDER BY cntrycode - """ - ); - - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // I1 - I7 are randomly selected without repetition from the possible values + """); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // I1 - I7 are randomly selected without repetition from the possible values - // We are given - // Let i be an index into the list of strings Nations - // (i.e., ALGERIA is 0, ARGENTINA is 1, etc., see Clause 4.2.3), - // Let country_code be the sub-string representation of the number (i + 10) - // There are 25 nations, hence country_code ranges from [10, 34] + // We are given + // Let i be an index into the list of strings Nations + // (i.e., ALGERIA is 0, ARGENTINA is 1, etc., see Clause 4.2.3), + // Let country_code be the sub-string representation of the number (i + 10) + // There are 25 nations, hence country_code ranges from [10, 34] - Set seen = new HashSet<>(7); - int[] codes = new int[7]; - for (int i = 0; i < 7; i++) { - int num = rand.number(10, 34); + Set seen = new HashSet<>(7); + int[] codes = new int[7]; + for (int i = 0; i < 7; i++) { + int num = rand.number(10, 34); - while (seen.contains(num)) { - num = rand.number(10, 34); - } + while (seen.contains(num)) { + num = rand.number(10, 34); + } - codes[i] = num; - seen.add(num); - } + codes[i] = num; + seen.add(num); + } - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - for (int i = 0; i < 7; i++) { - stmt.setString(1 + i, String.valueOf(codes[i])); - } - for (int i = 0; i < 7; i++) { - stmt.setString(8 + i, String.valueOf(codes[i])); - } - return stmt; + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + for (int i = 0; i < 7; i++) { + stmt.setString(1 + i, String.valueOf(codes[i])); + } + for (int i = 0; i < 7; i++) { + stmt.setString(8 + i, String.valueOf(codes[i])); } + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q3.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q3.java index bc8fc3afc..d5188246b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q3.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q3.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -29,7 +28,9 @@ public class Q3 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT l_orderkey, SUM(l_extendedprice * (1 - l_discount)) AS revenue, @@ -52,21 +53,21 @@ public class Q3 extends GenericQuery { ORDER BY revenue DESC, o_orderdate LIMIT 10 - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - String segment = TPCHUtil.choice(TPCHConstants.SEGMENTS, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + String segment = TPCHUtil.choice(TPCHConstants.SEGMENTS, rand); - // date must be randomly selected between [1995-03-01, 1995-03-31] - int day = rand.number(1, 31); - String date = String.format("1995-03-%02d", day); + // date must be randomly selected between [1995-03-01, 1995-03-31] + int day = rand.number(1, 31); + String date = String.format("1995-03-%02d", day); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, segment); - stmt.setDate(2, Date.valueOf(date)); - stmt.setDate(3, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, segment); + stmt.setDate(2, Date.valueOf(date)); + stmt.setDate(3, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q4.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q4.java index 46081bfb8..30e5d6236 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q4.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q4.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -27,7 +26,9 @@ public class Q4 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT o_orderpriority, COUNT(*) AS order_count @@ -50,18 +51,18 @@ public class Q4 extends GenericQuery { o_orderpriority ORDER BY o_orderpriority - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - int year = rand.number(1993, 1997); - int month = rand.number(1, 10); - String date = String.format("%d-%02d-01", year, month); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + int year = rand.number(1993, 1997); + int month = rand.number(1, 10); + String date = String.format("%d-%02d-01", year, month); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setDate(1, Date.valueOf(date)); - stmt.setDate(2, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setDate(1, Date.valueOf(date)); + stmt.setDate(2, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q5.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q5.java index 1bd7932bf..3254b25b4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q5.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q5.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -29,7 +28,9 @@ public class Q5 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT n_name, SUM(l_extendedprice * (1 - l_discount)) AS revenue @@ -54,20 +55,20 @@ public class Q5 extends GenericQuery { n_name ORDER BY revenue DESC - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - String region = TPCHUtil.choice(TPCHConstants.R_NAME, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + String region = TPCHUtil.choice(TPCHConstants.R_NAME, rand); - int year = rand.number(1993, 1997); - String date = String.format("%d-01-01", year); + int year = rand.number(1993, 1997); + String date = String.format("%d-01-01", year); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, region); - stmt.setDate(2, Date.valueOf(date)); - stmt.setDate(3, Date.valueOf(date)); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, region); + stmt.setDate(2, Date.valueOf(date)); + stmt.setDate(3, Date.valueOf(date)); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q6.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q6.java index 40e1cd414..c6bf0b943 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q6.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q6.java @@ -19,7 +19,6 @@ import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.Date; import java.sql.PreparedStatement; @@ -27,7 +26,9 @@ public class Q6 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT SUM(l_extendedprice * l_discount) AS revenue FROM @@ -37,27 +38,27 @@ public class Q6 extends GenericQuery { AND l_shipdate < DATE ? + INTERVAL '1' YEAR AND l_discount BETWEEN ? - 0.01 AND ? + 0.01 AND l_quantity < ? - """ - ); - - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // DATE is the first of January of a randomly selected year within [1993 .. 1997] - int year = rand.number(1993, 1997); - String date = String.format("%d-01-01", year); - - // DISCOUNT is randomly selected within [0.02 .. 0.09] - String discount = String.format("0.0%d", rand.number(2, 9)); - - // QUANTITY is randomly selected within [24 .. 25] - int quantity = rand.number(24, 25); - - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setDate(1, Date.valueOf(date)); - stmt.setDate(2, Date.valueOf(date)); - stmt.setString(3, discount); - stmt.setString(4, discount); - stmt.setInt(5, quantity); - return stmt; - } + """); + + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // DATE is the first of January of a randomly selected year within [1993 .. 1997] + int year = rand.number(1993, 1997); + String date = String.format("%d-01-01", year); + + // DISCOUNT is randomly selected within [0.02 .. 0.09] + String discount = String.format("0.0%d", rand.number(2, 9)); + + // QUANTITY is randomly selected within [24 .. 25] + int quantity = rand.number(24, 25); + + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setDate(1, Date.valueOf(date)); + stmt.setDate(2, Date.valueOf(date)); + stmt.setString(3, discount); + stmt.setString(4, discount); + stmt.setInt(5, quantity); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q7.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q7.java index c4f09e761..94267a330 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q7.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q7.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q7 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT supp_nation, cust_nation, @@ -73,26 +74,26 @@ public class Q7 extends GenericQuery { supp_nation, cust_nation, l_year - """ - ); - - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // NATION1 is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - String nation1 = TPCHUtil.choice(TPCHConstants.N_NAME, rand); + """); - // NATION2 is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - // and must be different from the value selected for NATION1 in item 1 above - String nation2 = nation1; - while (nation2.equals(nation1)) { - nation2 = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - } + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // NATION1 is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + String nation1 = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, nation1); - stmt.setString(2, nation2); - stmt.setString(3, nation2); - stmt.setString(4, nation1); - return stmt; + // NATION2 is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + // and must be different from the value selected for NATION1 in item 1 above + String nation2 = nation1; + while (nation2.equals(nation1)) { + nation2 = TPCHUtil.choice(TPCHConstants.N_NAME, rand); } + + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, nation1); + stmt.setString(2, nation2); + stmt.setString(3, nation2); + stmt.setString(4, nation1); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q8.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q8.java index ae2366852..7d8807185 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q8.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q8.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q8 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT o_year, SUM( @@ -75,29 +76,30 @@ public class Q8 extends GenericQuery { o_year ORDER BY o_year - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 - String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // NATION is randomly selected within the list of values defined for N_NAME in Clause 4.2.3 + String nation = TPCHUtil.choice(TPCHConstants.N_NAME, rand); - // REGION is the value defined in Clause 4.2.3 for R_NAME where R_REGIONKEY corresponds to - // N_REGIONKEY for the selected NATION in item 1 above - int n_regionkey = TPCHUtil.getRegionKeyFromNation(nation); - String region = TPCHUtil.getRegionFromRegionKey(n_regionkey); + // REGION is the value defined in Clause 4.2.3 for R_NAME where R_REGIONKEY corresponds to + // N_REGIONKEY for the selected NATION in item 1 above + int n_regionkey = TPCHUtil.getRegionKeyFromNation(nation); + String region = TPCHUtil.getRegionFromRegionKey(n_regionkey); - // TYPE is randomly selected within the list of 3-syllable strings defined for Types in Clause 4.2.2.13 - String syllable1 = TPCHUtil.choice(TPCHConstants.TYPE_S1, rand); - String syllable2 = TPCHUtil.choice(TPCHConstants.TYPE_S2, rand); - String syllable3 = TPCHUtil.choice(TPCHConstants.TYPE_S3, rand); - String type = String.format("%s %s %s", syllable1, syllable2, syllable3); + // TYPE is randomly selected within the list of 3-syllable strings defined for Types in Clause + // 4.2.2.13 + String syllable1 = TPCHUtil.choice(TPCHConstants.TYPE_S1, rand); + String syllable2 = TPCHUtil.choice(TPCHConstants.TYPE_S2, rand); + String syllable3 = TPCHUtil.choice(TPCHConstants.TYPE_S3, rand); + String type = String.format("%s %s %s", syllable1, syllable2, syllable3); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, nation); - stmt.setString(2, region); - stmt.setString(3, type); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, nation); + stmt.setString(2, region); + stmt.setString(3, type); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q9.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q9.java index 7de35a9bf..2c0a63d0a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q9.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/procedures/Q9.java @@ -21,14 +21,15 @@ import com.oltpbenchmark.benchmarks.tpch.TPCHConstants; import com.oltpbenchmark.benchmarks.tpch.TPCHUtil; import com.oltpbenchmark.util.RandomGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class Q9 extends GenericQuery { - public final SQLStmt query_stmt = new SQLStmt(""" + public final SQLStmt query_stmt = + new SQLStmt( + """ SELECT nation, o_year, @@ -64,18 +65,19 @@ public class Q9 extends GenericQuery { ORDER BY nation, o_year DESC - """ - ); + """); - @Override - protected PreparedStatement getStatement(Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { - // COLOR is randomly selected within the list of values defined for the generation of P_NAME in Clause 4.2.3 - String color = "%" + TPCHUtil.choice(TPCHConstants.P_NAME_GENERATOR, rand) + "%"; + @Override + protected PreparedStatement getStatement( + Connection conn, RandomGenerator rand, double scaleFactor) throws SQLException { + // COLOR is randomly selected within the list of values defined for the generation of P_NAME in + // Clause 4.2.3 + String color = "%" + TPCHUtil.choice(TPCHConstants.P_NAME_GENERATOR, rand) + "%"; - LOG.debug("attempting to execute sql [{}] for color [{}]", query_stmt.getSQL(), color); + LOG.debug("attempting to execute sql [{}] for color [{}]", query_stmt.getSQL(), color); - PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); - stmt.setString(1, color); - return stmt; - } + PreparedStatement stmt = this.getPreparedStatement(conn, query_stmt); + stmt.setString(1, color); + return stmt; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/CustomerGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/CustomerGenerator.java index 5bff00552..1c89714e1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/CustomerGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/CustomerGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,123 +15,127 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; - -import com.oltpbenchmark.util.RowRandomBoundedInt; - import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; import static java.util.Locale.ENGLISH; import static java.util.Objects.requireNonNull; +import com.oltpbenchmark.util.RowRandomBoundedInt; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + public class CustomerGenerator implements Iterable> { - public static final int SCALE_BASE = 150_000; - private static final int ACCOUNT_BALANCE_MIN = -99999; - private static final int ACCOUNT_BALANCE_MAX = 999999; - private static final int ADDRESS_AVERAGE_LENGTH = 25; - private static final int COMMENT_AVERAGE_LENGTH = 73; + public static final int SCALE_BASE = 150_000; + private static final int ACCOUNT_BALANCE_MIN = -99999; + private static final int ACCOUNT_BALANCE_MAX = 999999; + private static final int ADDRESS_AVERAGE_LENGTH = 25; + private static final int COMMENT_AVERAGE_LENGTH = 73; + + private final double scaleFactor; + private final int part; + private final int partCount; + + private final Distributions distributions; + private final TextPool textPool; + + public CustomerGenerator(double scaleFactor, int part, int partCount) { + this( + scaleFactor, + part, + partCount, + Distributions.getDefaultDistributions(), + TextPool.getDefaultTestPool()); + } + + public CustomerGenerator( + double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; + + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } + + @Override + public Iterator> iterator() { + return new CustomerGeneratorIterator( + distributions, + textPool, + calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + } + + private static class CustomerGeneratorIterator implements Iterator> { + private final TPCHRandomAlphaNumeric addressRandom = + new TPCHRandomAlphaNumeric(881155353L, ADDRESS_AVERAGE_LENGTH); + private final RowRandomBoundedInt nationKeyRandom; + private final TPCHRandomPhoneNumber phoneRandom = new TPCHRandomPhoneNumber(1521138112L); + private final RowRandomBoundedInt accountBalanceRandom = + new RowRandomBoundedInt(298370230L, ACCOUNT_BALANCE_MIN, ACCOUNT_BALANCE_MAX); + private final TPCHRandomString marketSegmentRandom; + private final TPCHRandomText commentRandom; + + private final long startIndex; + private final long rowCount; + + private long index; + + private CustomerGeneratorIterator( + Distributions distributions, TextPool textPool, long startIndex, long rowCount) { + this.startIndex = startIndex; + this.rowCount = rowCount; + + nationKeyRandom = + new RowRandomBoundedInt(1489529863L, 0, distributions.getNations().size() - 1); + marketSegmentRandom = new TPCHRandomString(1140279430L, distributions.getMarketSegments()); + commentRandom = new TPCHRandomText(1335826707L, textPool, COMMENT_AVERAGE_LENGTH); + + addressRandom.advanceRows(startIndex); + nationKeyRandom.advanceRows(startIndex); + phoneRandom.advanceRows(startIndex); + accountBalanceRandom.advanceRows(startIndex); + marketSegmentRandom.advanceRows(startIndex); + commentRandom.advanceRows(startIndex); + } + + @Override + public boolean hasNext() { + return index < rowCount; + } - private final double scaleFactor; - private final int part; - private final int partCount; + @Override + public List next() { + List customer = makeCustomer(startIndex + index + 1); + + addressRandom.rowFinished(); + nationKeyRandom.rowFinished(); + phoneRandom.rowFinished(); + accountBalanceRandom.rowFinished(); + marketSegmentRandom.rowFinished(); + commentRandom.rowFinished(); - private final Distributions distributions; - private final TextPool textPool; + index++; - public CustomerGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); + return customer; } - public CustomerGenerator(double scaleFactor, int part, int partCount, Distributions distributions, - TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; + private List makeCustomer(long customerKey) { + long nationKey = nationKeyRandom.nextValue(); - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); - } + List customer = new ArrayList<>(); - @Override - public Iterator> iterator() { - return new CustomerGeneratorIterator( - distributions, - textPool, - calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); - } + customer.add(customerKey); + customer.add(String.format(ENGLISH, "Customer#%09d", customerKey)); + customer.add(addressRandom.nextValue()); + customer.add(nationKey); + customer.add(phoneRandom.nextValue(nationKey)); + customer.add((double) accountBalanceRandom.nextValue() / 100.); + customer.add(marketSegmentRandom.nextValue()); + customer.add(commentRandom.nextValue()); - private static class CustomerGeneratorIterator - implements Iterator> { - private final TPCHRandomAlphaNumeric addressRandom = new TPCHRandomAlphaNumeric(881155353L, - ADDRESS_AVERAGE_LENGTH); - private final RowRandomBoundedInt nationKeyRandom; - private final TPCHRandomPhoneNumber phoneRandom = new TPCHRandomPhoneNumber(1521138112L); - private final RowRandomBoundedInt accountBalanceRandom = new RowRandomBoundedInt(298370230L, - ACCOUNT_BALANCE_MIN, ACCOUNT_BALANCE_MAX); - private final TPCHRandomString marketSegmentRandom; - private final TPCHRandomText commentRandom; - - private final long startIndex; - private final long rowCount; - - private long index; - - private CustomerGeneratorIterator(Distributions distributions, TextPool textPool, long startIndex, - long rowCount) { - this.startIndex = startIndex; - this.rowCount = rowCount; - - nationKeyRandom = new RowRandomBoundedInt(1489529863L, 0, distributions.getNations().size() - 1); - marketSegmentRandom = new TPCHRandomString(1140279430L, distributions.getMarketSegments()); - commentRandom = new TPCHRandomText(1335826707L, textPool, COMMENT_AVERAGE_LENGTH); - - addressRandom.advanceRows(startIndex); - nationKeyRandom.advanceRows(startIndex); - phoneRandom.advanceRows(startIndex); - accountBalanceRandom.advanceRows(startIndex); - marketSegmentRandom.advanceRows(startIndex); - commentRandom.advanceRows(startIndex); - } - - @Override - public boolean hasNext() { - return index < rowCount; - } - - @Override - public List next() { - List customer = makeCustomer(startIndex + index + 1); - - addressRandom.rowFinished(); - nationKeyRandom.rowFinished(); - phoneRandom.rowFinished(); - accountBalanceRandom.rowFinished(); - marketSegmentRandom.rowFinished(); - commentRandom.rowFinished(); - - index++; - - return customer; - } - - private List makeCustomer(long customerKey) { - long nationKey = nationKeyRandom.nextValue(); - - List customer = new ArrayList<>(); - - customer.add(customerKey); - customer.add(String.format(ENGLISH, "Customer#%09d", customerKey)); - customer.add(addressRandom.nextValue()); - customer.add(nationKey); - customer.add(phoneRandom.nextValue(nationKey)); - customer.add((double) accountBalanceRandom.nextValue() / 100.); - customer.add(marketSegmentRandom.nextValue()); - customer.add(commentRandom.nextValue()); - - return customer; - } + return customer; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java index 6f89a721a..d7ad97423 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distribution.java @@ -15,83 +15,82 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.List; +import static java.util.Objects.requireNonNull; + +import com.oltpbenchmark.util.RowRandomInt; import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.Map.Entry; -import com.oltpbenchmark.util.RowRandomInt; - -import static java.util.Objects.requireNonNull; - public class Distribution { - @SuppressWarnings("unused") // never read - private final String name; + @SuppressWarnings("unused") // never read + private final String name; - private final List values; - private final int[] weights; - private final String[] distribution; - private final int maxWeight; + private final List values; + private final int[] weights; + private final String[] distribution; + private final int maxWeight; - public Distribution(String name, Map distribution) { - this.name = requireNonNull(name, "name is null"); - requireNonNull(distribution, "distribution is null"); + public Distribution(String name, Map distribution) { + this.name = requireNonNull(name, "name is null"); + requireNonNull(distribution, "distribution is null"); - List values = new ArrayList<>(); - this.weights = new int[distribution.size()]; + List values = new ArrayList<>(); + this.weights = new int[distribution.size()]; - int runningWeight = 0; - int index = 0; - boolean isValidDistribution = true; - for (Entry entry : distribution.entrySet()) { - values.add(entry.getKey()); + int runningWeight = 0; + int index = 0; + boolean isValidDistribution = true; + for (Entry entry : distribution.entrySet()) { + values.add(entry.getKey()); - runningWeight += entry.getValue(); - weights[index] = runningWeight; + runningWeight += entry.getValue(); + weights[index] = runningWeight; - isValidDistribution &= entry.getValue() > 0; + isValidDistribution &= entry.getValue() > 0; - index++; - } - this.values = values; - - // "nations" is hack and not a valid distribution so we need to skip it - if (isValidDistribution) { - this.maxWeight = weights[weights.length - 1]; - this.distribution = new String[maxWeight]; - - index = 0; - for (String value : this.values) { - int count = distribution.get(value); - for (int i = 0; i < count; i++) { - this.distribution[index] = value; - index++; - } - } - } else { - this.maxWeight = -1; - this.distribution = null; + index++; + } + this.values = values; + + // "nations" is hack and not a valid distribution so we need to skip it + if (isValidDistribution) { + this.maxWeight = weights[weights.length - 1]; + this.distribution = new String[maxWeight]; + + index = 0; + for (String value : this.values) { + int count = distribution.get(value); + for (int i = 0; i < count; i++) { + this.distribution[index] = value; + index++; } + } + } else { + this.maxWeight = -1; + this.distribution = null; } + } - public String getValue(int index) { - return values.get(index); - } + public String getValue(int index) { + return values.get(index); + } - public List getValues() { - return values; - } + public List getValues() { + return values; + } - public int getWeight(int index) { - return weights[index]; - } + public int getWeight(int index) { + return weights[index]; + } - public int size() { - return values.size(); - } + public int size() { + return values.size(); + } - public String randomValue(RowRandomInt randomInt) { - int randomValue = randomInt.nextInt(0, maxWeight - 1); - return distribution[randomValue]; - } + public String randomValue(RowRandomInt randomInt) { + int randomValue = randomInt.nextInt(0, maxWeight - 1); + return distribution[randomValue]; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/DistributionLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/DistributionLoader.java index 2a56cefbf..8a2408551 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/DistributionLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/DistributionLoader.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,82 +16,82 @@ package com.oltpbenchmark.benchmarks.tpch.util; import com.oltpbenchmark.util.StringUtil; - import java.io.Closeable; import java.io.IOException; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.LinkedHashMap; -import java.util.stream.Stream; import java.util.regex.Pattern; +import java.util.stream.Stream; public final class DistributionLoader { - private DistributionLoader() { - } + private DistributionLoader() {} - public static Map loadDistribution(Stream lines) - throws IOException { - return loadDistributions(lines - .map(String::trim) - .filter(line -> !line.isEmpty() && !line.startsWith("#")) - .iterator()); - } + public static Map loadDistribution( + Stream lines) throws IOException { + return loadDistributions( + lines + .map(String::trim) + .filter(line -> !line.isEmpty() && !line.startsWith("#")) + .iterator()); + } - private static Distribution loadDistribution(Iterator lines, String name) { - int count = -1; - Map members = new LinkedHashMap<>(); - while (lines.hasNext()) { - // advance to "begin" - String line = lines.next(); - if (isEnd(name, line)) { - return new Distribution(name, members); - } + private static Distribution loadDistribution(Iterator lines, String name) { + int count = -1; + Map members = new LinkedHashMap<>(); + while (lines.hasNext()) { + // advance to "begin" + String line = lines.next(); + if (isEnd(name, line)) { + return new Distribution(name, members); + } - List parts = StringUtil.splitToList(Pattern.compile("\\|"), line); + List parts = StringUtil.splitToList(Pattern.compile("\\|"), line); - String value = parts.get(0); - int weight; - try { - weight = Integer.parseInt(parts.get(1)); - } catch (NumberFormatException e) { - throw new IllegalStateException( - String.format("Invalid distribution %s: invalid weight on line %s", name, line)); - } + String value = parts.get(0); + int weight; + try { + weight = Integer.parseInt(parts.get(1)); + } catch (NumberFormatException e) { + throw new IllegalStateException( + String.format("Invalid distribution %s: invalid weight on line %s", name, line)); + } - if (value.equalsIgnoreCase("count")) { - count = weight; - } else { - members.put(value, weight); - } - } - throw new IllegalStateException(String.format("Invalid distribution %s: no end statement", name)); + if (value.equalsIgnoreCase("count")) { + count = weight; + } else { + members.put(value, weight); + } } + throw new IllegalStateException( + String.format("Invalid distribution %s: no end statement", name)); + } - private static boolean isEnd(String name, String line) { - List parts = StringUtil.splitToList(StringUtil.WHITESPACE, line); - if (parts.get(0).equalsIgnoreCase("END")) { - return true; - } - return false; + private static boolean isEnd(String name, String line) { + List parts = StringUtil.splitToList(StringUtil.WHITESPACE, line); + if (parts.get(0).equalsIgnoreCase("END")) { + return true; } + return false; + } - private static Map loadDistributions(Iterator lines) { - Map distributions = new LinkedHashMap<>(); - while (lines.hasNext()) { - // advance to "begin" - String line = lines.next(); - List parts = StringUtil.splitToList(StringUtil.WHITESPACE, line); - if (parts.size() != 2) { - continue; - } + private static Map loadDistributions(Iterator lines) { + Map distributions = new LinkedHashMap<>(); + while (lines.hasNext()) { + // advance to "begin" + String line = lines.next(); + List parts = StringUtil.splitToList(StringUtil.WHITESPACE, line); + if (parts.size() != 2) { + continue; + } - if (parts.get(0).equalsIgnoreCase("BEGIN")) { - String name = parts.get(1); - Distribution distribution = loadDistribution(lines, name); - distributions.put(name.toLowerCase(), distribution); - } - } - return distributions; + if (parts.get(0).equalsIgnoreCase("BEGIN")) { + String name = parts.get(1); + Distribution distribution = loadDistribution(lines, name); + distributions.put(name.toLowerCase(), distribution); + } } + return distributions; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distributions.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distributions.java index c9e4bf1b8..0763fdef8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distributions.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/Distributions.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,164 +15,166 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; +import static com.oltpbenchmark.benchmarks.tpch.util.DistributionLoader.loadDistribution; +import static java.nio.charset.StandardCharsets.UTF_8; + +import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.UncheckedIOException; import java.io.InputStreamReader; -import java.io.BufferedReader; +import java.io.UncheckedIOException; import java.util.Map; -import static com.oltpbenchmark.benchmarks.tpch.util.DistributionLoader.loadDistribution; -import static java.nio.charset.StandardCharsets.UTF_8; - public class Distributions { - private static final Distributions DEFAULT_DISTRIBUTIONS = loadDefaults(); - - private static Distributions loadDefaults() { - try (InputStream resource = Distributions.class.getResourceAsStream("/benchmarks/tpch/dists.dss")) { - BufferedReader distReader = new BufferedReader(new InputStreamReader(resource, UTF_8)); - return new Distributions(loadDistribution(distReader.lines())); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static Distributions getDefaultDistributions() { - return DEFAULT_DISTRIBUTIONS; - } - - private final Distribution grammars; - private final Distribution nounPhrase; - private final Distribution verbPhrase; - private final Distribution prepositions; - private final Distribution nouns; - private final Distribution verbs; - private final Distribution articles; - private final Distribution adjectives; - private final Distribution adverbs; - private final Distribution auxiliaries; - private final Distribution terminators; - private final Distribution orderPriorities; - private final Distribution shipInstructions; - private final Distribution shipModes; - private final Distribution returnFlags; - private final Distribution partContainers; - private final Distribution partColors; - private final Distribution partTypes; - private final Distribution marketSegments; - private final Distribution nations; - private final Distribution regions; - - public Distributions(Map distributions) { - this.grammars = getDistribution(distributions, "grammar"); - this.nounPhrase = getDistribution(distributions, "np"); - this.verbPhrase = getDistribution(distributions, "vp"); - this.prepositions = getDistribution(distributions, "prepositions"); - this.nouns = getDistribution(distributions, "nouns"); - this.verbs = getDistribution(distributions, "verbs"); - this.articles = getDistribution(distributions, "articles"); - this.adjectives = getDistribution(distributions, "adjectives"); - this.adverbs = getDistribution(distributions, "adverbs"); - this.auxiliaries = getDistribution(distributions, "auxillaries"); - this.terminators = getDistribution(distributions, "terminators"); - this.orderPriorities = getDistribution(distributions, "o_oprio"); - this.shipInstructions = getDistribution(distributions, "instruct"); - this.shipModes = getDistribution(distributions, "smode"); - this.returnFlags = getDistribution(distributions, "rflag"); - this.partContainers = getDistribution(distributions, "p_cntr"); - this.partColors = getDistribution(distributions, "colors"); - this.partTypes = getDistribution(distributions, "p_types"); - this.marketSegments = getDistribution(distributions, "msegmnt"); - this.nations = getDistribution(distributions, "nations"); - this.regions = getDistribution(distributions, "regions"); - } - - public Distribution getAdjectives() { - return adjectives; - } - - public Distribution getAdverbs() { - return adverbs; - } - - public Distribution getArticles() { - return articles; - } - - public Distribution getAuxiliaries() { - return auxiliaries; - } - - public Distribution getGrammars() { - return grammars; - } - - public Distribution getMarketSegments() { - return marketSegments; - } - - public Distribution getNations() { - return nations; - } - - public Distribution getNounPhrase() { - return nounPhrase; - } - - public Distribution getNouns() { - return nouns; - } - - public Distribution getOrderPriorities() { - return orderPriorities; - } - - public Distribution getPartColors() { - return partColors; - } - - public Distribution getPartContainers() { - return partContainers; - } - - public Distribution getPartTypes() { - return partTypes; - } - - public Distribution getPrepositions() { - return prepositions; - } - - public Distribution getRegions() { - return regions; - } - - public Distribution getReturnFlags() { - return returnFlags; - } - - public Distribution getShipInstructions() { - return shipInstructions; - } - - public Distribution getShipModes() { - return shipModes; - } - - public Distribution getTerminators() { - return terminators; - } - - public Distribution getVerbPhrase() { - return verbPhrase; - } - - public Distribution getVerbs() { - return verbs; - } - - private static Distribution getDistribution(Map distributions, String name) { - Distribution distribution = distributions.get(name); - return distribution; - } + private static final Distributions DEFAULT_DISTRIBUTIONS = loadDefaults(); + + private static Distributions loadDefaults() { + try (InputStream resource = + Distributions.class.getResourceAsStream("/benchmarks/tpch/dists.dss")) { + BufferedReader distReader = new BufferedReader(new InputStreamReader(resource, UTF_8)); + return new Distributions(loadDistribution(distReader.lines())); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + public static Distributions getDefaultDistributions() { + return DEFAULT_DISTRIBUTIONS; + } + + private final Distribution grammars; + private final Distribution nounPhrase; + private final Distribution verbPhrase; + private final Distribution prepositions; + private final Distribution nouns; + private final Distribution verbs; + private final Distribution articles; + private final Distribution adjectives; + private final Distribution adverbs; + private final Distribution auxiliaries; + private final Distribution terminators; + private final Distribution orderPriorities; + private final Distribution shipInstructions; + private final Distribution shipModes; + private final Distribution returnFlags; + private final Distribution partContainers; + private final Distribution partColors; + private final Distribution partTypes; + private final Distribution marketSegments; + private final Distribution nations; + private final Distribution regions; + + public Distributions(Map distributions) { + this.grammars = getDistribution(distributions, "grammar"); + this.nounPhrase = getDistribution(distributions, "np"); + this.verbPhrase = getDistribution(distributions, "vp"); + this.prepositions = getDistribution(distributions, "prepositions"); + this.nouns = getDistribution(distributions, "nouns"); + this.verbs = getDistribution(distributions, "verbs"); + this.articles = getDistribution(distributions, "articles"); + this.adjectives = getDistribution(distributions, "adjectives"); + this.adverbs = getDistribution(distributions, "adverbs"); + this.auxiliaries = getDistribution(distributions, "auxillaries"); + this.terminators = getDistribution(distributions, "terminators"); + this.orderPriorities = getDistribution(distributions, "o_oprio"); + this.shipInstructions = getDistribution(distributions, "instruct"); + this.shipModes = getDistribution(distributions, "smode"); + this.returnFlags = getDistribution(distributions, "rflag"); + this.partContainers = getDistribution(distributions, "p_cntr"); + this.partColors = getDistribution(distributions, "colors"); + this.partTypes = getDistribution(distributions, "p_types"); + this.marketSegments = getDistribution(distributions, "msegmnt"); + this.nations = getDistribution(distributions, "nations"); + this.regions = getDistribution(distributions, "regions"); + } + + public Distribution getAdjectives() { + return adjectives; + } + + public Distribution getAdverbs() { + return adverbs; + } + + public Distribution getArticles() { + return articles; + } + + public Distribution getAuxiliaries() { + return auxiliaries; + } + + public Distribution getGrammars() { + return grammars; + } + + public Distribution getMarketSegments() { + return marketSegments; + } + + public Distribution getNations() { + return nations; + } + + public Distribution getNounPhrase() { + return nounPhrase; + } + + public Distribution getNouns() { + return nouns; + } + + public Distribution getOrderPriorities() { + return orderPriorities; + } + + public Distribution getPartColors() { + return partColors; + } + + public Distribution getPartContainers() { + return partContainers; + } + + public Distribution getPartTypes() { + return partTypes; + } + + public Distribution getPrepositions() { + return prepositions; + } + + public Distribution getRegions() { + return regions; + } + + public Distribution getReturnFlags() { + return returnFlags; + } + + public Distribution getShipInstructions() { + return shipInstructions; + } + + public Distribution getShipModes() { + return shipModes; + } + + public Distribution getTerminators() { + return terminators; + } + + public Distribution getVerbPhrase() { + return verbPhrase; + } + + public Distribution getVerbs() { + return verbs; + } + + private static Distribution getDistribution( + Map distributions, String name) { + Distribution distribution = distributions.get(name); + return distribution; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java index 4aa209165..798d8458f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/GenerateUtils.java @@ -16,136 +16,121 @@ package com.oltpbenchmark.benchmarks.tpch.util; import java.math.BigDecimal; -import java.util.List; +import java.sql.Date; import java.util.ArrayList; import java.util.Calendar; -import java.sql.Date; - +import java.util.List; public final class GenerateUtils { - private GenerateUtils() { + private GenerateUtils() {} + + // + // Partitioning Utils + // + + public static long calculateRowCount(int scaleBase, double scaleFactor, int part, int partCount) { + long totalRowCount = (long) (scaleBase * scaleFactor); + long rowCount = totalRowCount / partCount; + if (part == partCount) { + // for the last part, add the remainder rows + rowCount += totalRowCount % partCount; } + return rowCount; + } - // - // Partitioning Utils - // - - public static long calculateRowCount(int scaleBase, double scaleFactor, int part, int partCount) { - long totalRowCount = (long) (scaleBase * scaleFactor); - long rowCount = totalRowCount / partCount; - if (part == partCount) { - // for the last part, add the remainder rows - rowCount += totalRowCount % partCount; - } - return rowCount; - } + public static long calculateStartIndex( + int scaleBase, double scaleFactor, int part, int partCount) { + long totalRowCount = (long) (scaleBase * scaleFactor); - public static long calculateStartIndex(int scaleBase, double scaleFactor, int part, int partCount) { - long totalRowCount = (long) (scaleBase * scaleFactor); + long rowsPerPart = totalRowCount / partCount; + return rowsPerPart * (part - 1); + } - long rowsPerPart = totalRowCount / partCount; - return rowsPerPart * (part - 1); - } + // + // Date Utils + // - // - // Date Utils - // - - /** - * The value of 1970-01-01 in the date generator system - */ - public static final int GENERATED_DATE_EPOCH_OFFSET = 83966; - - public static final int MIN_GENERATE_DATE = 92001; - private static final int CURRENT_DATE = 95168; - public static final int TOTAL_DATE_RANGE = 2557; - - private static final int[] MONTH_YEAR_DAY_START = { - 0, - 31, - 59, - 90, - 120, - 151, - 181, - 212, - 243, - 273, - 304, - 334, - 365, - }; - - private static final List DATE_INDEX = makeDateIndex(); - - public static Date toEpochDate(int generatedDate) { - return formatDate(generatedDate - GENERATED_DATE_EPOCH_OFFSET); - } + /** The value of 1970-01-01 in the date generator system */ + public static final int GENERATED_DATE_EPOCH_OFFSET = 83966; + + public static final int MIN_GENERATE_DATE = 92001; + private static final int CURRENT_DATE = 95168; + public static final int TOTAL_DATE_RANGE = 2557; + + private static final int[] MONTH_YEAR_DAY_START = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, + }; - public static Date formatDate(int epochDate) { - return DATE_INDEX.get(epochDate - (MIN_GENERATE_DATE - GENERATED_DATE_EPOCH_OFFSET)); + private static final List DATE_INDEX = makeDateIndex(); + + public static Date toEpochDate(int generatedDate) { + return formatDate(generatedDate - GENERATED_DATE_EPOCH_OFFSET); + } + + public static Date formatDate(int epochDate) { + return DATE_INDEX.get(epochDate - (MIN_GENERATE_DATE - GENERATED_DATE_EPOCH_OFFSET)); + } + + private static List makeDateIndex() { + List dates = new ArrayList<>(); + for (int i = 0; i < TOTAL_DATE_RANGE; i++) { + dates.add(makeDate(i + 1)); } - private static List makeDateIndex() { - List dates = new ArrayList<>(); - for (int i = 0; i < TOTAL_DATE_RANGE; i++) { - dates.add(makeDate(i + 1)); - } + return dates; + } - return dates; + private static Date makeDate(int index) { + int y = julian(index + MIN_GENERATE_DATE - 1) / 1000; + int d = julian(index + MIN_GENERATE_DATE - 1) % 1000; + + int m = 0; + while (d > MONTH_YEAR_DAY_START[m] + leapYearAdjustment(y, m)) { + m++; } + int dy = d - MONTH_YEAR_DAY_START[m - 1] - ((isLeapYear(y) && m > 2) ? 1 : 0); - private static Date makeDate(int index) { - int y = julian(index + MIN_GENERATE_DATE - 1) / 1000; - int d = julian(index + MIN_GENERATE_DATE - 1) % 1000; + Calendar cal = Calendar.getInstance(); + cal.set(1900 + y, m - 1, dy, 0, 0, 0); - int m = 0; - while (d > MONTH_YEAR_DAY_START[m] + leapYearAdjustment(y, m)) { - m++; - } - int dy = d - MONTH_YEAR_DAY_START[m - 1] - ((isLeapYear(y) && m > 2) ? 1 : 0); + return new Date(cal.getTimeInMillis()); + } - Calendar cal = Calendar.getInstance(); - cal.set(1900 + y, m - 1, dy, 0, 0, 0); + private static int leapYearAdjustment(int year, int month) { + return ((isLeapYear(year) && (month) >= 2) ? 1 : 0); + } - return new Date(cal.getTimeInMillis()); - } + public static boolean isInPast(int date) { + return julian(date) <= CURRENT_DATE; + } - private static int leapYearAdjustment(int year, int month) { - return ((isLeapYear(year) && (month) >= 2) ? 1 : 0); - } + private static int julian(int date) { + int offset = date - MIN_GENERATE_DATE; + int result = MIN_GENERATE_DATE; - public static boolean isInPast(int date) { - return julian(date) <= CURRENT_DATE; - } + while (true) { + int year = result / 1000; + int yearEnd = year * 1000 + 365 + (isLeapYear(year) ? 1 : 0); + if (result + offset <= yearEnd) { + break; + } - private static int julian(int date) { - int offset = date - MIN_GENERATE_DATE; - int result = MIN_GENERATE_DATE; - - while (true) { - int year = result / 1000; - int yearEnd = year * 1000 + 365 + (isLeapYear(year) ? 1 : 0); - if (result + offset <= yearEnd) { - break; - } - - offset -= yearEnd - result + 1; - result += 1000; - } - return (result + offset); + offset -= yearEnd - result + 1; + result += 1000; } + return (result + offset); + } - private static boolean isLeapYear(int year) { - return year % 4 == 0 && year % 100 != 0; - } + private static boolean isLeapYear(int year) { + return year % 4 == 0 && year % 100 != 0; + } - // - // Format utils - // + // + // Format utils + // - public static String formatMoney(long value) { - // todo there must be a better way to do this - return new BigDecimal(value).divide(new BigDecimal(100)).setScale(2).toString(); - } + public static String formatMoney(long value) { + // todo there must be a better way to do this + return new BigDecimal(value).divide(new BigDecimal(100)).setScale(2).toString(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/LineItemGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/LineItemGenerator.java index 7aa545087..94e81466e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/LineItemGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/LineItemGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,13 +15,6 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; - -import com.oltpbenchmark.util.RowRandomBoundedInt; -import com.oltpbenchmark.util.RowRandomBoundedLong; - import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.toEpochDate; @@ -32,258 +25,278 @@ import static com.oltpbenchmark.benchmarks.tpch.util.PartSupplierGenerator.selectPartSupplier; import static java.util.Objects.requireNonNull; -public class LineItemGenerator - implements Iterable> { - private static final int QUANTITY_MIN = 1; - private static final int QUANTITY_MAX = 50; - private static final int TAX_MIN = 0; - private static final int TAX_MAX = 8; - private static final int DISCOUNT_MIN = 0; - private static final int DISCOUNT_MAX = 10; - private static final int PART_KEY_MIN = 1; - - private static final int SHIP_DATE_MIN = 1; - private static final int SHIP_DATE_MAX = 121; - private static final int COMMIT_DATE_MIN = 30; - private static final int COMMIT_DATE_MAX = 90; - private static final int RECEIPT_DATE_MIN = 1; - private static final int RECEIPT_DATE_MAX = 30; - - static final int ITEM_SHIP_DAYS = SHIP_DATE_MAX + RECEIPT_DATE_MAX; +import com.oltpbenchmark.util.RowRandomBoundedInt; +import com.oltpbenchmark.util.RowRandomBoundedLong; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; - private static final int COMMENT_AVERAGE_LENGTH = 27; +public class LineItemGenerator implements Iterable> { + private static final int QUANTITY_MIN = 1; + private static final int QUANTITY_MAX = 50; + private static final int TAX_MIN = 0; + private static final int TAX_MAX = 8; + private static final int DISCOUNT_MIN = 0; + private static final int DISCOUNT_MAX = 10; + private static final int PART_KEY_MIN = 1; + + private static final int SHIP_DATE_MIN = 1; + private static final int SHIP_DATE_MAX = 121; + private static final int COMMIT_DATE_MIN = 30; + private static final int COMMIT_DATE_MAX = 90; + private static final int RECEIPT_DATE_MIN = 1; + private static final int RECEIPT_DATE_MAX = 30; + + static final int ITEM_SHIP_DAYS = SHIP_DATE_MAX + RECEIPT_DATE_MAX; + + private static final int COMMENT_AVERAGE_LENGTH = 27; + + private final double scaleFactor; + private final int part; + private final int partCount; + + private final Distributions distributions; + private final TextPool textPool; + + public LineItemGenerator(double scaleFactor, int part, int partCount) { + this( + scaleFactor, + part, + partCount, + Distributions.getDefaultDistributions(), + TextPool.getDefaultTestPool()); + } + + public LineItemGenerator( + double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; + + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } + + @Override + public Iterator> iterator() { + return new LineItemGeneratorIterator( + distributions, + textPool, + scaleFactor, + calculateStartIndex(OrderGenerator.SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(OrderGenerator.SCALE_BASE, scaleFactor, part, partCount)); + } + + private static class LineItemGeneratorIterator implements Iterator> { + private final RowRandomBoundedInt orderDateRandom = createOrderDateRandom(); + private final RowRandomBoundedInt lineCountRandom = createLineCountRandom(); + + private final RowRandomBoundedInt quantityRandom = createQuantityRandom(); + private final RowRandomBoundedInt discountRandom = createDiscountRandom(); + private final RowRandomBoundedInt taxRandom = createTaxRandom(); + + private final RowRandomBoundedLong linePartKeyRandom; + + private final RowRandomBoundedInt supplierNumberRandom = + new RowRandomBoundedInt(2095021727L, 0, 3, LINE_COUNT_MAX); + + private final RowRandomBoundedInt shipDateRandom = createShipDateRandom(); + private final RowRandomBoundedInt commitDateRandom = + new RowRandomBoundedInt(904914315L, COMMIT_DATE_MIN, COMMIT_DATE_MAX, LINE_COUNT_MAX); + private final RowRandomBoundedInt receiptDateRandom = + new RowRandomBoundedInt(373135028L, RECEIPT_DATE_MIN, RECEIPT_DATE_MAX, LINE_COUNT_MAX); + + private final TPCHRandomString returnedFlagRandom; + private final TPCHRandomString shipInstructionsRandom; + private final TPCHRandomString shipModeRandom; + + private final TPCHRandomText commentRandom; private final double scaleFactor; - private final int part; - private final int partCount; - - private final Distributions distributions; - private final TextPool textPool; + private final long startIndex; - public LineItemGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); - } - - public LineItemGenerator(double scaleFactor, int part, int partCount, Distributions distributions, - TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; - - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); - } - - @Override - public Iterator> iterator() { - return new LineItemGeneratorIterator( - distributions, - textPool, - scaleFactor, - calculateStartIndex(OrderGenerator.SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(OrderGenerator.SCALE_BASE, scaleFactor, part, partCount)); - } - - private static class LineItemGeneratorIterator - implements Iterator> { - private final RowRandomBoundedInt orderDateRandom = createOrderDateRandom(); - private final RowRandomBoundedInt lineCountRandom = createLineCountRandom(); + private final long rowCount; - private final RowRandomBoundedInt quantityRandom = createQuantityRandom(); - private final RowRandomBoundedInt discountRandom = createDiscountRandom(); - private final RowRandomBoundedInt taxRandom = createTaxRandom(); + private long index; + private int orderDate; + private int lineCount; + private int lineNumber; - private final RowRandomBoundedLong linePartKeyRandom; + private LineItemGeneratorIterator( + Distributions distributions, + TextPool textPool, + double scaleFactor, + long startIndex, + long rowCount) { + this.scaleFactor = scaleFactor; + this.startIndex = startIndex; + this.rowCount = rowCount; - private final RowRandomBoundedInt supplierNumberRandom = new RowRandomBoundedInt(2095021727L, 0, 3, - LINE_COUNT_MAX); + returnedFlagRandom = + new TPCHRandomString(717419739L, distributions.getReturnFlags(), LINE_COUNT_MAX); + shipInstructionsRandom = + new TPCHRandomString(1371272478L, distributions.getShipInstructions(), LINE_COUNT_MAX); + shipModeRandom = + new TPCHRandomString(675466456L, distributions.getShipModes(), LINE_COUNT_MAX); + commentRandom = + new TPCHRandomText(1095462486L, textPool, COMMENT_AVERAGE_LENGTH, LINE_COUNT_MAX); - private final RowRandomBoundedInt shipDateRandom = createShipDateRandom(); - private final RowRandomBoundedInt commitDateRandom = new RowRandomBoundedInt(904914315L, COMMIT_DATE_MIN, - COMMIT_DATE_MAX, LINE_COUNT_MAX); - private final RowRandomBoundedInt receiptDateRandom = new RowRandomBoundedInt(373135028L, RECEIPT_DATE_MIN, - RECEIPT_DATE_MAX, LINE_COUNT_MAX); + linePartKeyRandom = createPartKeyRandom(scaleFactor); - private final TPCHRandomString returnedFlagRandom; - private final TPCHRandomString shipInstructionsRandom; - private final TPCHRandomString shipModeRandom; + orderDateRandom.advanceRows(startIndex); + lineCountRandom.advanceRows(startIndex); - private final TPCHRandomText commentRandom; + quantityRandom.advanceRows(startIndex); + discountRandom.advanceRows(startIndex); + taxRandom.advanceRows(startIndex); - private final double scaleFactor; - private final long startIndex; + linePartKeyRandom.advanceRows(startIndex); - private final long rowCount; + supplierNumberRandom.advanceRows(startIndex); - private long index; - private int orderDate; - private int lineCount; - private int lineNumber; + shipDateRandom.advanceRows(startIndex); + commitDateRandom.advanceRows(startIndex); + receiptDateRandom.advanceRows(startIndex); - private LineItemGeneratorIterator(Distributions distributions, TextPool textPool, double scaleFactor, - long startIndex, long rowCount) { - this.scaleFactor = scaleFactor; - this.startIndex = startIndex; - this.rowCount = rowCount; + returnedFlagRandom.advanceRows(startIndex); + shipInstructionsRandom.advanceRows(startIndex); + shipModeRandom.advanceRows(startIndex); - returnedFlagRandom = new TPCHRandomString(717419739L, distributions.getReturnFlags(), LINE_COUNT_MAX); - shipInstructionsRandom = new TPCHRandomString(1371272478L, distributions.getShipInstructions(), - LINE_COUNT_MAX); - shipModeRandom = new TPCHRandomString(675466456L, distributions.getShipModes(), LINE_COUNT_MAX); - commentRandom = new TPCHRandomText(1095462486L, textPool, COMMENT_AVERAGE_LENGTH, LINE_COUNT_MAX); + commentRandom.advanceRows(startIndex); - linePartKeyRandom = createPartKeyRandom(scaleFactor); + // generate information for initial order + orderDate = orderDateRandom.nextValue(); + lineCount = lineCountRandom.nextValue() - 1; + } - orderDateRandom.advanceRows(startIndex); - lineCountRandom.advanceRows(startIndex); + @Override + public boolean hasNext() { + return index < rowCount; + } - quantityRandom.advanceRows(startIndex); - discountRandom.advanceRows(startIndex); - taxRandom.advanceRows(startIndex); + @Override + public List next() { + List lineitem = makeLineitem(startIndex + index + 1); + lineNumber++; - linePartKeyRandom.advanceRows(startIndex); + // advance next row only when all lines for the order have been produced + if (lineNumber > lineCount) { + orderDateRandom.rowFinished(); - supplierNumberRandom.advanceRows(startIndex); + lineCountRandom.rowFinished(); + quantityRandom.rowFinished(); + discountRandom.rowFinished(); + taxRandom.rowFinished(); - shipDateRandom.advanceRows(startIndex); - commitDateRandom.advanceRows(startIndex); - receiptDateRandom.advanceRows(startIndex); + linePartKeyRandom.rowFinished(); - returnedFlagRandom.advanceRows(startIndex); - shipInstructionsRandom.advanceRows(startIndex); - shipModeRandom.advanceRows(startIndex); + supplierNumberRandom.rowFinished(); - commentRandom.advanceRows(startIndex); + shipDateRandom.rowFinished(); + commitDateRandom.rowFinished(); + receiptDateRandom.rowFinished(); - // generate information for initial order - orderDate = orderDateRandom.nextValue(); - lineCount = lineCountRandom.nextValue() - 1; - } - - @Override - public boolean hasNext() { - return index < rowCount; - } - - @Override - public List next() { - List lineitem = makeLineitem(startIndex + index + 1); - lineNumber++; - - // advance next row only when all lines for the order have been produced - if (lineNumber > lineCount) { - orderDateRandom.rowFinished(); - - lineCountRandom.rowFinished(); - quantityRandom.rowFinished(); - discountRandom.rowFinished(); - taxRandom.rowFinished(); - - linePartKeyRandom.rowFinished(); - - supplierNumberRandom.rowFinished(); - - shipDateRandom.rowFinished(); - commitDateRandom.rowFinished(); - receiptDateRandom.rowFinished(); - - returnedFlagRandom.rowFinished(); - shipInstructionsRandom.rowFinished(); - shipModeRandom.rowFinished(); - - commentRandom.rowFinished(); - - index++; - - // generate information for next order - lineCount = lineCountRandom.nextValue() - 1; - orderDate = orderDateRandom.nextValue(); - lineNumber = 0; - } - - return lineitem; - } - - private List makeLineitem(long orderIndex) { - long orderKey = makeOrderKey(orderIndex); - - int quantity = quantityRandom.nextValue(); - int discount = discountRandom.nextValue(); - int tax = taxRandom.nextValue(); - - long partKey = linePartKeyRandom.nextValue(); - - int supplierNumber = supplierNumberRandom.nextValue(); - long supplierKey = selectPartSupplier(partKey, supplierNumber, scaleFactor); - - long partPrice = PartGenerator.calculatePartPrice(partKey); - long extendedPrice = partPrice * quantity; - - int shipDate = shipDateRandom.nextValue(); - shipDate += orderDate; - int commitDate = commitDateRandom.nextValue(); - commitDate += orderDate; - int receiptDate = receiptDateRandom.nextValue(); - receiptDate += shipDate; - - String returnedFlag; - if (GenerateUtils.isInPast(receiptDate)) { - returnedFlag = returnedFlagRandom.nextValue(); - } else { - returnedFlag = "N"; - } - - String status; - if (GenerateUtils.isInPast(shipDate)) { - status = "F"; - } else { - status = "O"; - } - - String shipInstructions = shipInstructionsRandom.nextValue(); - String shipMode = shipModeRandom.nextValue(); - String comment = commentRandom.nextValue(); - - List lineItem = new ArrayList<>(); - lineItem.add(orderKey); - lineItem.add(partKey); - lineItem.add(supplierKey); - lineItem.add((long) (lineNumber + 1)); - lineItem.add((double) quantity); - lineItem.add((double) extendedPrice / 100.); - lineItem.add((double) discount / 100.); - lineItem.add((double) tax / 100.); - lineItem.add(returnedFlag); - lineItem.add(status); - lineItem.add(toEpochDate(shipDate)); - lineItem.add(toEpochDate(commitDate)); - lineItem.add(toEpochDate(receiptDate)); - lineItem.add(shipInstructions); - lineItem.add(shipMode); - lineItem.add(comment); - - return lineItem; - } - } + returnedFlagRandom.rowFinished(); + shipInstructionsRandom.rowFinished(); + shipModeRandom.rowFinished(); - static RowRandomBoundedInt createQuantityRandom() { - return new RowRandomBoundedInt(209208115L, QUANTITY_MIN, QUANTITY_MAX, LINE_COUNT_MAX); - } + commentRandom.rowFinished(); - static RowRandomBoundedInt createDiscountRandom() { - return new RowRandomBoundedInt(554590007L, DISCOUNT_MIN, DISCOUNT_MAX, LINE_COUNT_MAX); - } + index++; - static RowRandomBoundedInt createTaxRandom() { - return new RowRandomBoundedInt(721958466L, TAX_MIN, TAX_MAX, LINE_COUNT_MAX); - } + // generate information for next order + lineCount = lineCountRandom.nextValue() - 1; + orderDate = orderDateRandom.nextValue(); + lineNumber = 0; + } - static RowRandomBoundedLong createPartKeyRandom(double scaleFactor) { - return new RowRandomBoundedLong(1808217256L, scaleFactor >= 30000, PART_KEY_MIN, - (long) (PartGenerator.SCALE_BASE * scaleFactor), LINE_COUNT_MAX); + return lineitem; } - static RowRandomBoundedInt createShipDateRandom() { - return new RowRandomBoundedInt(1769349045L, SHIP_DATE_MIN, SHIP_DATE_MAX, LINE_COUNT_MAX); + private List makeLineitem(long orderIndex) { + long orderKey = makeOrderKey(orderIndex); + + int quantity = quantityRandom.nextValue(); + int discount = discountRandom.nextValue(); + int tax = taxRandom.nextValue(); + + long partKey = linePartKeyRandom.nextValue(); + + int supplierNumber = supplierNumberRandom.nextValue(); + long supplierKey = selectPartSupplier(partKey, supplierNumber, scaleFactor); + + long partPrice = PartGenerator.calculatePartPrice(partKey); + long extendedPrice = partPrice * quantity; + + int shipDate = shipDateRandom.nextValue(); + shipDate += orderDate; + int commitDate = commitDateRandom.nextValue(); + commitDate += orderDate; + int receiptDate = receiptDateRandom.nextValue(); + receiptDate += shipDate; + + String returnedFlag; + if (GenerateUtils.isInPast(receiptDate)) { + returnedFlag = returnedFlagRandom.nextValue(); + } else { + returnedFlag = "N"; + } + + String status; + if (GenerateUtils.isInPast(shipDate)) { + status = "F"; + } else { + status = "O"; + } + + String shipInstructions = shipInstructionsRandom.nextValue(); + String shipMode = shipModeRandom.nextValue(); + String comment = commentRandom.nextValue(); + + List lineItem = new ArrayList<>(); + lineItem.add(orderKey); + lineItem.add(partKey); + lineItem.add(supplierKey); + lineItem.add((long) (lineNumber + 1)); + lineItem.add((double) quantity); + lineItem.add((double) extendedPrice / 100.); + lineItem.add((double) discount / 100.); + lineItem.add((double) tax / 100.); + lineItem.add(returnedFlag); + lineItem.add(status); + lineItem.add(toEpochDate(shipDate)); + lineItem.add(toEpochDate(commitDate)); + lineItem.add(toEpochDate(receiptDate)); + lineItem.add(shipInstructions); + lineItem.add(shipMode); + lineItem.add(comment); + + return lineItem; } + } + + static RowRandomBoundedInt createQuantityRandom() { + return new RowRandomBoundedInt(209208115L, QUANTITY_MIN, QUANTITY_MAX, LINE_COUNT_MAX); + } + + static RowRandomBoundedInt createDiscountRandom() { + return new RowRandomBoundedInt(554590007L, DISCOUNT_MIN, DISCOUNT_MAX, LINE_COUNT_MAX); + } + + static RowRandomBoundedInt createTaxRandom() { + return new RowRandomBoundedInt(721958466L, TAX_MIN, TAX_MAX, LINE_COUNT_MAX); + } + + static RowRandomBoundedLong createPartKeyRandom(double scaleFactor) { + return new RowRandomBoundedLong( + 1808217256L, + scaleFactor >= 30000, + PART_KEY_MIN, + (long) (PartGenerator.SCALE_BASE * scaleFactor), + LINE_COUNT_MAX); + } + + static RowRandomBoundedInt createShipDateRandom() { + return new RowRandomBoundedInt(1769349045L, SHIP_DATE_MIN, SHIP_DATE_MAX, LINE_COUNT_MAX); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/NationGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/NationGenerator.java index 12a5c97d8..bf909896f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/NationGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/NationGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,62 +15,60 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import static java.util.Objects.requireNonNull; +public class NationGenerator implements Iterable> { + private static final int COMMENT_AVERAGE_LENGTH = 72; -public class NationGenerator - implements Iterable> { - private static final int COMMENT_AVERAGE_LENGTH = 72; + private final Distributions distributions; + private final TextPool textPool; - private final Distributions distributions; - private final TextPool textPool; + public NationGenerator() { + this(Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); + } - public NationGenerator() { - this(Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); - } + public NationGenerator(Distributions distributions, TextPool textPool) { + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } - public NationGenerator(Distributions distributions, TextPool textPool) { - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); - } + @Override + public Iterator> iterator() { + return new NationGeneratorIterator(distributions.getNations(), textPool); + } - @Override - public Iterator> iterator() { - return new NationGeneratorIterator(distributions.getNations(), textPool); - } + private static class NationGeneratorIterator implements Iterator> { + private final Distribution nations; + private final TPCHRandomText commentRandom; - private static class NationGeneratorIterator - implements Iterator> { - private final Distribution nations; - private final TPCHRandomText commentRandom; + private int index; - private int index; - - private NationGeneratorIterator(Distribution nations, TextPool textPool) { - this.nations = nations; - this.commentRandom = new TPCHRandomText(606179079L, textPool, COMMENT_AVERAGE_LENGTH); - } + private NationGeneratorIterator(Distribution nations, TextPool textPool) { + this.nations = nations; + this.commentRandom = new TPCHRandomText(606179079L, textPool, COMMENT_AVERAGE_LENGTH); + } - @Override - public boolean hasNext() { - return index < nations.size(); - } + @Override + public boolean hasNext() { + return index < nations.size(); + } - @Override - public List next() { - List nation = new ArrayList<>(); - nation.add((long) index); - nation.add(nations.getValue(index)); - nation.add((long) nations.getWeight(index)); - nation.add(commentRandom.nextValue()); + @Override + public List next() { + List nation = new ArrayList<>(); + nation.add((long) index); + nation.add(nations.getValue(index)); + nation.add((long) nations.getWeight(index)); + nation.add(commentRandom.nextValue()); - commentRandom.rowFinished(); - index++; + commentRandom.rowFinished(); + index++; - return nation; - } + return nation; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/OrderGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/OrderGenerator.java index 428dcf044..393f03c81 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/OrderGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/OrderGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,13 +15,6 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; - -import com.oltpbenchmark.util.RowRandomBoundedInt; -import com.oltpbenchmark.util.RowRandomBoundedLong; - import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.MIN_GENERATE_DATE; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.TOTAL_DATE_RANGE; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; @@ -37,212 +30,229 @@ import static java.util.Locale.ENGLISH; import static java.util.Objects.requireNonNull; -public class OrderGenerator - implements Iterable> { - public static final int SCALE_BASE = 1_500_000; - - // portion with have no orders - public static final int CUSTOMER_MORTALITY = 3; - - private static final int ORDER_DATE_MIN = MIN_GENERATE_DATE; - private static final int ORDER_DATE_MAX = ORDER_DATE_MIN + (TOTAL_DATE_RANGE - ITEM_SHIP_DAYS - 1); - private static final int CLERK_SCALE_BASE = 1000; - - private static final int LINE_COUNT_MIN = 1; - static final int LINE_COUNT_MAX = 7; - - private static final int COMMENT_AVERAGE_LENGTH = 49; - - private static final int ORDER_KEY_SPARSE_BITS = 2; - private static final int ORDER_KEY_SPARSE_KEEP = 3; - - private final double scaleFactor; - private final int part; - private final int partCount; - - private final Distributions distributions; - private final TextPool textPool; - - public OrderGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); - } - - public OrderGenerator(double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; +import com.oltpbenchmark.util.RowRandomBoundedInt; +import com.oltpbenchmark.util.RowRandomBoundedLong; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); +public class OrderGenerator implements Iterable> { + public static final int SCALE_BASE = 1_500_000; + + // portion with have no orders + public static final int CUSTOMER_MORTALITY = 3; + + private static final int ORDER_DATE_MIN = MIN_GENERATE_DATE; + private static final int ORDER_DATE_MAX = + ORDER_DATE_MIN + (TOTAL_DATE_RANGE - ITEM_SHIP_DAYS - 1); + private static final int CLERK_SCALE_BASE = 1000; + + private static final int LINE_COUNT_MIN = 1; + static final int LINE_COUNT_MAX = 7; + + private static final int COMMENT_AVERAGE_LENGTH = 49; + + private static final int ORDER_KEY_SPARSE_BITS = 2; + private static final int ORDER_KEY_SPARSE_KEEP = 3; + + private final double scaleFactor; + private final int part; + private final int partCount; + + private final Distributions distributions; + private final TextPool textPool; + + public OrderGenerator(double scaleFactor, int part, int partCount) { + this( + scaleFactor, + part, + partCount, + Distributions.getDefaultDistributions(), + TextPool.getDefaultTestPool()); + } + + public OrderGenerator( + double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; + + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } + + @Override + public Iterator> iterator() { + return new OrderGeneratorIterator( + distributions, + textPool, + scaleFactor, + calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + } + + private static class OrderGeneratorIterator implements Iterator> { + private final RowRandomBoundedInt orderDateRandom = createOrderDateRandom(); + private final RowRandomBoundedInt lineCountRandom = createLineCountRandom(); + private final RowRandomBoundedLong customerKeyRandom; + private final TPCHRandomString orderPriorityRandom; + private final RowRandomBoundedInt clerkRandom; + private final TPCHRandomText commentRandom; + + private final RowRandomBoundedInt lineQuantityRandom = createQuantityRandom(); + private final RowRandomBoundedInt lineDiscountRandom = createDiscountRandom(); + private final RowRandomBoundedInt lineTaxRandom = createTaxRandom(); + private final RowRandomBoundedLong linePartKeyRandom; + private final RowRandomBoundedInt lineShipDateRandom = createShipDateRandom(); + + private final long startIndex; + private final long rowCount; + + private final long maxCustomerKey; + + private long index; + + private OrderGeneratorIterator( + Distributions distributions, + TextPool textPool, + double scaleFactor, + long startIndex, + long rowCount) { + this.startIndex = startIndex; + this.rowCount = rowCount; + + clerkRandom = + new RowRandomBoundedInt( + 1171034773L, 1, Math.max((int) (scaleFactor * CLERK_SCALE_BASE), CLERK_SCALE_BASE)); + + maxCustomerKey = (long) (CustomerGenerator.SCALE_BASE * scaleFactor); + customerKeyRandom = + new RowRandomBoundedLong(851767375L, scaleFactor >= 30000, 1, maxCustomerKey); + + orderPriorityRandom = new TPCHRandomString(591449447L, distributions.getOrderPriorities()); + commentRandom = new TPCHRandomText(276090261L, textPool, COMMENT_AVERAGE_LENGTH); + + linePartKeyRandom = createPartKeyRandom(scaleFactor); + + orderDateRandom.advanceRows(startIndex); + lineCountRandom.advanceRows(startIndex); + customerKeyRandom.advanceRows(startIndex); + orderPriorityRandom.advanceRows(startIndex); + clerkRandom.advanceRows(startIndex); + commentRandom.advanceRows(startIndex); + + lineQuantityRandom.advanceRows(startIndex); + lineDiscountRandom.advanceRows(startIndex); + lineShipDateRandom.advanceRows(startIndex); + lineTaxRandom.advanceRows(startIndex); + linePartKeyRandom.advanceRows(startIndex); } @Override - public Iterator> iterator() { - return new OrderGeneratorIterator( - distributions, - textPool, - scaleFactor, - calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + public boolean hasNext() { + return index < rowCount; } - private static class OrderGeneratorIterator - implements Iterator> { - private final RowRandomBoundedInt orderDateRandom = createOrderDateRandom(); - private final RowRandomBoundedInt lineCountRandom = createLineCountRandom(); - private final RowRandomBoundedLong customerKeyRandom; - private final TPCHRandomString orderPriorityRandom; - private final RowRandomBoundedInt clerkRandom; - private final TPCHRandomText commentRandom; - - private final RowRandomBoundedInt lineQuantityRandom = createQuantityRandom(); - private final RowRandomBoundedInt lineDiscountRandom = createDiscountRandom(); - private final RowRandomBoundedInt lineTaxRandom = createTaxRandom(); - private final RowRandomBoundedLong linePartKeyRandom; - private final RowRandomBoundedInt lineShipDateRandom = createShipDateRandom(); - - private final long startIndex; - private final long rowCount; - - private final long maxCustomerKey; - - private long index; - - private OrderGeneratorIterator(Distributions distributions, TextPool textPool, double scaleFactor, - long startIndex, long rowCount) { - this.startIndex = startIndex; - this.rowCount = rowCount; + @Override + public List next() { + List order = makeOrder(startIndex + index + 1); - clerkRandom = new RowRandomBoundedInt(1171034773L, 1, - Math.max((int) (scaleFactor * CLERK_SCALE_BASE), CLERK_SCALE_BASE)); + orderDateRandom.rowFinished(); + lineCountRandom.rowFinished(); + customerKeyRandom.rowFinished(); + orderPriorityRandom.rowFinished(); + clerkRandom.rowFinished(); + commentRandom.rowFinished(); - maxCustomerKey = (long) (CustomerGenerator.SCALE_BASE * scaleFactor); - customerKeyRandom = new RowRandomBoundedLong(851767375L, scaleFactor >= 30000, 1, maxCustomerKey); + lineQuantityRandom.rowFinished(); + lineDiscountRandom.rowFinished(); + lineShipDateRandom.rowFinished(); + lineTaxRandom.rowFinished(); + linePartKeyRandom.rowFinished(); - orderPriorityRandom = new TPCHRandomString(591449447L, distributions.getOrderPriorities()); - commentRandom = new TPCHRandomText(276090261L, textPool, COMMENT_AVERAGE_LENGTH); + index++; - linePartKeyRandom = createPartKeyRandom(scaleFactor); + return order; + } - orderDateRandom.advanceRows(startIndex); - lineCountRandom.advanceRows(startIndex); - customerKeyRandom.advanceRows(startIndex); - orderPriorityRandom.advanceRows(startIndex); - clerkRandom.advanceRows(startIndex); - commentRandom.advanceRows(startIndex); + private List makeOrder(long index) { + long orderKey = makeOrderKey(index); - lineQuantityRandom.advanceRows(startIndex); - lineDiscountRandom.advanceRows(startIndex); - lineShipDateRandom.advanceRows(startIndex); - lineTaxRandom.advanceRows(startIndex); - linePartKeyRandom.advanceRows(startIndex); - } + int orderDate = orderDateRandom.nextValue(); - @Override - public boolean hasNext() { - return index < rowCount; - } + // generate customer key, taking into account customer mortality rate + long customerKey = customerKeyRandom.nextValue(); + int delta = 1; + while (customerKey % CUSTOMER_MORTALITY == 0) { + customerKey += delta; + customerKey = Math.min(customerKey, maxCustomerKey); + delta *= -1; + } - @Override - public List next() { - List order = makeOrder(startIndex + index + 1); + long totalPrice = 0; + int shippedCount = 0; - orderDateRandom.rowFinished(); - lineCountRandom.rowFinished(); - customerKeyRandom.rowFinished(); - orderPriorityRandom.rowFinished(); - clerkRandom.rowFinished(); - commentRandom.rowFinished(); + int lineCount = lineCountRandom.nextValue(); + for (long lineNumber = 0; lineNumber < lineCount; lineNumber++) { + int quantity = lineQuantityRandom.nextValue(); + int discount = lineDiscountRandom.nextValue(); + int tax = lineTaxRandom.nextValue(); - lineQuantityRandom.rowFinished(); - lineDiscountRandom.rowFinished(); - lineShipDateRandom.rowFinished(); - lineTaxRandom.rowFinished(); - linePartKeyRandom.rowFinished(); + long partKey = linePartKeyRandom.nextValue(); - index++; + long partPrice = calculatePartPrice(partKey); + long extendedPrice = partPrice * quantity; + long discountedPrice = extendedPrice * (100 - discount); + totalPrice += ((discountedPrice / 100) * (100 + tax)) / 100; - return order; - } - - private List makeOrder(long index) { - long orderKey = makeOrderKey(index); - - int orderDate = orderDateRandom.nextValue(); - - // generate customer key, taking into account customer mortality rate - long customerKey = customerKeyRandom.nextValue(); - int delta = 1; - while (customerKey % CUSTOMER_MORTALITY == 0) { - customerKey += delta; - customerKey = Math.min(customerKey, maxCustomerKey); - delta *= -1; - } - - long totalPrice = 0; - int shippedCount = 0; - - int lineCount = lineCountRandom.nextValue(); - for (long lineNumber = 0; lineNumber < lineCount; lineNumber++) { - int quantity = lineQuantityRandom.nextValue(); - int discount = lineDiscountRandom.nextValue(); - int tax = lineTaxRandom.nextValue(); - - long partKey = linePartKeyRandom.nextValue(); - - long partPrice = calculatePartPrice(partKey); - long extendedPrice = partPrice * quantity; - long discountedPrice = extendedPrice * (100 - discount); - totalPrice += ((discountedPrice / 100) * (100 + tax)) / 100; - - int shipDate = lineShipDateRandom.nextValue(); - shipDate += orderDate; - if (GenerateUtils.isInPast(shipDate)) { - shippedCount++; - } - } - - char orderStatus; - if (shippedCount == lineCount) { - orderStatus = 'F'; - } else if (shippedCount > 0) { - orderStatus = 'P'; - } else { - orderStatus = 'O'; - } - - List order = new ArrayList<>(); - order.add(orderKey); - order.add(customerKey); - order.add(Character.valueOf(orderStatus).toString()); - order.add((double) totalPrice / 100.); - order.add(toEpochDate(orderDate)); - order.add(orderPriorityRandom.nextValue()); - order.add(String.format(ENGLISH, "Clerk#%09d", clerkRandom.nextValue())); - order.add(0L); - order.add(commentRandom.nextValue()); - - return order; + int shipDate = lineShipDateRandom.nextValue(); + shipDate += orderDate; + if (GenerateUtils.isInPast(shipDate)) { + shippedCount++; } + } + + char orderStatus; + if (shippedCount == lineCount) { + orderStatus = 'F'; + } else if (shippedCount > 0) { + orderStatus = 'P'; + } else { + orderStatus = 'O'; + } + + List order = new ArrayList<>(); + order.add(orderKey); + order.add(customerKey); + order.add(Character.valueOf(orderStatus).toString()); + order.add((double) totalPrice / 100.); + order.add(toEpochDate(orderDate)); + order.add(orderPriorityRandom.nextValue()); + order.add(String.format(ENGLISH, "Clerk#%09d", clerkRandom.nextValue())); + order.add(0L); + order.add(commentRandom.nextValue()); + + return order; } + } - static RowRandomBoundedInt createLineCountRandom() { - return new RowRandomBoundedInt(1434868289L, LINE_COUNT_MIN, LINE_COUNT_MAX); - } + static RowRandomBoundedInt createLineCountRandom() { + return new RowRandomBoundedInt(1434868289L, LINE_COUNT_MIN, LINE_COUNT_MAX); + } - static RowRandomBoundedInt createOrderDateRandom() { - return new RowRandomBoundedInt(1066728069L, ORDER_DATE_MIN, ORDER_DATE_MAX); - } + static RowRandomBoundedInt createOrderDateRandom() { + return new RowRandomBoundedInt(1066728069L, ORDER_DATE_MIN, ORDER_DATE_MAX); + } - static long makeOrderKey(long orderIndex) { - long lowBits = orderIndex & ((1 << ORDER_KEY_SPARSE_KEEP) - 1); + static long makeOrderKey(long orderIndex) { + long lowBits = orderIndex & ((1 << ORDER_KEY_SPARSE_KEEP) - 1); - long ok = orderIndex; - ok >>= ORDER_KEY_SPARSE_KEEP; - ok <<= ORDER_KEY_SPARSE_BITS; - ok <<= ORDER_KEY_SPARSE_KEEP; - ok += lowBits; + long ok = orderIndex; + ok >>= ORDER_KEY_SPARSE_KEEP; + ok <<= ORDER_KEY_SPARSE_BITS; + ok <<= ORDER_KEY_SPARSE_KEEP; + ok += lowBits; - return ok; - } + return ok; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartGenerator.java index fda0886d4..a08956754 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,145 +15,150 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; - -import com.oltpbenchmark.util.RowRandomBoundedInt; - import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; import static java.util.Locale.ENGLISH; import static java.util.Objects.requireNonNull; -public class PartGenerator - implements Iterable> { - public static final int SCALE_BASE = 200_000; +import com.oltpbenchmark.util.RowRandomBoundedInt; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; - private static final int NAME_WORDS = 5; - private static final int MANUFACTURER_MIN = 1; - private static final int MANUFACTURER_MAX = 5; - private static final int BRAND_MIN = 1; - private static final int BRAND_MAX = 5; - private static final int SIZE_MIN = 1; - private static final int SIZE_MAX = 50; - private static final int COMMENT_AVERAGE_LENGTH = 14; +public class PartGenerator implements Iterable> { + public static final int SCALE_BASE = 200_000; + + private static final int NAME_WORDS = 5; + private static final int MANUFACTURER_MIN = 1; + private static final int MANUFACTURER_MAX = 5; + private static final int BRAND_MIN = 1; + private static final int BRAND_MAX = 5; + private static final int SIZE_MIN = 1; + private static final int SIZE_MAX = 50; + private static final int COMMENT_AVERAGE_LENGTH = 14; + + private final double scaleFactor; + private final int part; + private final int partCount; + + private final Distributions distributions; + private final TextPool textPool; + + public PartGenerator(double scaleFactor, int part, int partCount) { + this( + scaleFactor, + part, + partCount, + Distributions.getDefaultDistributions(), + TextPool.getDefaultTestPool()); + } + + public PartGenerator( + double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; + + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } + + @Override + public Iterator> iterator() { + return new PartGeneratorIterator( + distributions, + textPool, + calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + } + + private static class PartGeneratorIterator implements Iterator> { + private final TPCHRandomStringSequence nameRandom; + private final RowRandomBoundedInt manufacturerRandom; + private final RowRandomBoundedInt brandRandom; + private final TPCHRandomString typeRandom; + private final RowRandomBoundedInt sizeRandom; + private final TPCHRandomString containerRandom; + private final TPCHRandomText commentRandom; + + private final long startIndex; + private final long rowCount; + + private long index; + + private PartGeneratorIterator( + Distributions distributions, TextPool textPool, long startIndex, long rowCount) { + this.startIndex = startIndex; + this.rowCount = rowCount; + + nameRandom = + new TPCHRandomStringSequence(709314158L, NAME_WORDS, distributions.getPartColors()); + manufacturerRandom = new RowRandomBoundedInt(1L, MANUFACTURER_MIN, MANUFACTURER_MAX); + brandRandom = new RowRandomBoundedInt(46831694L, BRAND_MIN, BRAND_MAX); + typeRandom = new TPCHRandomString(1841581359L, distributions.getPartTypes()); + sizeRandom = new RowRandomBoundedInt(1193163244L, SIZE_MIN, SIZE_MAX); + containerRandom = new TPCHRandomString(727633698L, distributions.getPartContainers()); + commentRandom = new TPCHRandomText(804159733L, textPool, COMMENT_AVERAGE_LENGTH); + + nameRandom.advanceRows(startIndex); + manufacturerRandom.advanceRows(startIndex); + brandRandom.advanceRows(startIndex); + typeRandom.advanceRows(startIndex); + sizeRandom.advanceRows(startIndex); + containerRandom.advanceRows(startIndex); + commentRandom.advanceRows(startIndex); + } - private final double scaleFactor; - private final int part; - private final int partCount; + @Override + public boolean hasNext() { + return index < rowCount; + } - private final Distributions distributions; - private final TextPool textPool; + @Override + public List next() { + List part = makePart(startIndex + index + 1); - public PartGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); - } + nameRandom.rowFinished(); + manufacturerRandom.rowFinished(); + brandRandom.rowFinished(); + typeRandom.rowFinished(); + sizeRandom.rowFinished(); + containerRandom.rowFinished(); + commentRandom.rowFinished(); - public PartGenerator(double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; + index++; - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); + return part; } - @Override - public Iterator> iterator() { - return new PartGeneratorIterator( - distributions, - textPool, - calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); - } + private List makePart(long partKey) { + String name = nameRandom.nextValue(); + + int manufacturer = manufacturerRandom.nextValue(); + int brand = manufacturer * 10 + brandRandom.nextValue(); - private static class PartGeneratorIterator - implements Iterator> { - private final TPCHRandomStringSequence nameRandom; - private final RowRandomBoundedInt manufacturerRandom; - private final RowRandomBoundedInt brandRandom; - private final TPCHRandomString typeRandom; - private final RowRandomBoundedInt sizeRandom; - private final TPCHRandomString containerRandom; - private final TPCHRandomText commentRandom; - - private final long startIndex; - private final long rowCount; - - private long index; - - private PartGeneratorIterator(Distributions distributions, TextPool textPool, long startIndex, long rowCount) { - this.startIndex = startIndex; - this.rowCount = rowCount; - - nameRandom = new TPCHRandomStringSequence(709314158L, NAME_WORDS, distributions.getPartColors()); - manufacturerRandom = new RowRandomBoundedInt(1L, MANUFACTURER_MIN, MANUFACTURER_MAX); - brandRandom = new RowRandomBoundedInt(46831694L, BRAND_MIN, BRAND_MAX); - typeRandom = new TPCHRandomString(1841581359L, distributions.getPartTypes()); - sizeRandom = new RowRandomBoundedInt(1193163244L, SIZE_MIN, SIZE_MAX); - containerRandom = new TPCHRandomString(727633698L, distributions.getPartContainers()); - commentRandom = new TPCHRandomText(804159733L, textPool, COMMENT_AVERAGE_LENGTH); - - nameRandom.advanceRows(startIndex); - manufacturerRandom.advanceRows(startIndex); - brandRandom.advanceRows(startIndex); - typeRandom.advanceRows(startIndex); - sizeRandom.advanceRows(startIndex); - containerRandom.advanceRows(startIndex); - commentRandom.advanceRows(startIndex); - } - - @Override - public boolean hasNext() { - return index < rowCount; - } - - @Override - public List next() { - List part = makePart(startIndex + index + 1); - - nameRandom.rowFinished(); - manufacturerRandom.rowFinished(); - brandRandom.rowFinished(); - typeRandom.rowFinished(); - sizeRandom.rowFinished(); - containerRandom.rowFinished(); - commentRandom.rowFinished(); - - index++; - - return part; - } - - private List makePart(long partKey) { - String name = nameRandom.nextValue(); - - int manufacturer = manufacturerRandom.nextValue(); - int brand = manufacturer * 10 + brandRandom.nextValue(); - - List part = new ArrayList(); - part.add(partKey); - part.add(name); - part.add(String.format(ENGLISH, "Manufacturer#%d", manufacturer)); - part.add(String.format(ENGLISH, "Brand#%d", brand)); - part.add(typeRandom.nextValue()); - part.add((long) sizeRandom.nextValue()); - part.add(containerRandom.nextValue()); - part.add((double) calculatePartPrice(partKey) / 100.); - part.add(commentRandom.nextValue()); - - return part; - } + List part = new ArrayList(); + part.add(partKey); + part.add(name); + part.add(String.format(ENGLISH, "Manufacturer#%d", manufacturer)); + part.add(String.format(ENGLISH, "Brand#%d", brand)); + part.add(typeRandom.nextValue()); + part.add((long) sizeRandom.nextValue()); + part.add(containerRandom.nextValue()); + part.add((double) calculatePartPrice(partKey) / 100.); + part.add(commentRandom.nextValue()); + + return part; } + } - static long calculatePartPrice(long p) { - long price = 90000; + static long calculatePartPrice(long p) { + long price = 90000; - // limit contribution to $200 - price += (p / 10) % 20001; - price += (p % 1000) * 100; + // limit contribution to $200 + price += (p / 10) % 20001; + price += (p % 1000) * 100; - return (price); - } + return (price); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartSupplierGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartSupplierGenerator.java index 12a087e46..d690ed2c8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartSupplierGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/PartSupplierGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,121 +15,125 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; +import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; +import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; +import static java.util.Objects.requireNonNull; + +import com.oltpbenchmark.util.RowRandomBoundedInt; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import com.oltpbenchmark.util.RowRandomBoundedInt; +public class PartSupplierGenerator implements Iterable> { + private static final int SUPPLIERS_PER_PART = 4; -import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; -import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; -import static java.util.Objects.requireNonNull; + private static final int AVAILABLE_QUANTITY_MIN = 1; + private static final int AVAILABLE_QUANTITY_MAX = 9999; -public class PartSupplierGenerator - implements Iterable> { - private static final int SUPPLIERS_PER_PART = 4; + private static final int SUPPLY_COST_MIN = 100; + private static final int SUPPLY_COST_MAX = 100000; - private static final int AVAILABLE_QUANTITY_MIN = 1; - private static final int AVAILABLE_QUANTITY_MAX = 9999; + private static final int COMMENT_AVERAGE_LENGTH = 124; - private static final int SUPPLY_COST_MIN = 100; - private static final int SUPPLY_COST_MAX = 100000; + private final double scaleFactor; + private final int part; + private final int partCount; - private static final int COMMENT_AVERAGE_LENGTH = 124; + private final TextPool textPool; - private final double scaleFactor; - private final int part; - private final int partCount; + public PartSupplierGenerator(double scaleFactor, int part, int partCount) { + this(scaleFactor, part, partCount, TextPool.getDefaultTestPool()); + } - private final TextPool textPool; + public PartSupplierGenerator(double scaleFactor, int part, int partCount, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; - public PartSupplierGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, TextPool.getDefaultTestPool()); - } + this.textPool = requireNonNull(textPool, "textPool is null"); + } - public PartSupplierGenerator(double scaleFactor, int part, int partCount, TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; + @Override + public Iterator> iterator() { + return new PartSupplierGeneratorIterator( + textPool, + scaleFactor, + calculateStartIndex(PartGenerator.SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(PartGenerator.SCALE_BASE, scaleFactor, part, partCount)); + } - this.textPool = requireNonNull(textPool, "textPool is null"); + private static class PartSupplierGeneratorIterator implements Iterator> { + private final double scaleFactor; + private final long startIndex; + private final long rowCount; + + private final RowRandomBoundedInt availableQuantityRandom; + private final RowRandomBoundedInt supplyCostRandom; + private final TPCHRandomText commentRandom; + + private long index; + private int partSupplierNumber; + + private PartSupplierGeneratorIterator( + TextPool textPool, double scaleFactor, long startIndex, long rowCount) { + this.scaleFactor = scaleFactor; + this.startIndex = startIndex; + this.rowCount = rowCount; + + availableQuantityRandom = + new RowRandomBoundedInt( + 1671059989L, AVAILABLE_QUANTITY_MIN, AVAILABLE_QUANTITY_MAX, SUPPLIERS_PER_PART); + supplyCostRandom = + new RowRandomBoundedInt( + 1051288424L, SUPPLY_COST_MIN, SUPPLY_COST_MAX, SUPPLIERS_PER_PART); + commentRandom = + new TPCHRandomText(1961692154L, textPool, COMMENT_AVERAGE_LENGTH, SUPPLIERS_PER_PART); + + availableQuantityRandom.advanceRows(startIndex); + supplyCostRandom.advanceRows(startIndex); + commentRandom.advanceRows(startIndex); } @Override - public Iterator> iterator() { - return new PartSupplierGeneratorIterator( - textPool, - scaleFactor, - calculateStartIndex(PartGenerator.SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(PartGenerator.SCALE_BASE, scaleFactor, part, partCount)); + public boolean hasNext() { + return index < rowCount; } - private static class PartSupplierGeneratorIterator - implements Iterator> { - private final double scaleFactor; - private final long startIndex; - private final long rowCount; - - private final RowRandomBoundedInt availableQuantityRandom; - private final RowRandomBoundedInt supplyCostRandom; - private final TPCHRandomText commentRandom; - - private long index; - private int partSupplierNumber; - - private PartSupplierGeneratorIterator(TextPool textPool, double scaleFactor, long startIndex, long rowCount) { - this.scaleFactor = scaleFactor; - this.startIndex = startIndex; - this.rowCount = rowCount; - - availableQuantityRandom = new RowRandomBoundedInt(1671059989L, AVAILABLE_QUANTITY_MIN, - AVAILABLE_QUANTITY_MAX, SUPPLIERS_PER_PART); - supplyCostRandom = new RowRandomBoundedInt(1051288424L, SUPPLY_COST_MIN, SUPPLY_COST_MAX, - SUPPLIERS_PER_PART); - commentRandom = new TPCHRandomText(1961692154L, textPool, COMMENT_AVERAGE_LENGTH, SUPPLIERS_PER_PART); - - availableQuantityRandom.advanceRows(startIndex); - supplyCostRandom.advanceRows(startIndex); - commentRandom.advanceRows(startIndex); - } - - @Override - public boolean hasNext() { - return index < rowCount; - } - - @Override - public List next() { - List partSupplier = makePartSupplier(startIndex + index + 1); - partSupplierNumber++; - - // advance next row only when all lines for the order have been produced - if (partSupplierNumber >= SUPPLIERS_PER_PART) { - availableQuantityRandom.rowFinished(); - supplyCostRandom.rowFinished(); - commentRandom.rowFinished(); - - index++; - partSupplierNumber = 0; - } - - return partSupplier; - } - - private List makePartSupplier(long partKey) { - List partSupplier = new ArrayList<>(); - partSupplier.add(partKey); - partSupplier.add(selectPartSupplier(partKey, partSupplierNumber, scaleFactor)); - partSupplier.add((long) availableQuantityRandom.nextValue()); - partSupplier.add((double) supplyCostRandom.nextValue() / 100.); - partSupplier.add(commentRandom.nextValue()); - return partSupplier; - } + @Override + public List next() { + List partSupplier = makePartSupplier(startIndex + index + 1); + partSupplierNumber++; + + // advance next row only when all lines for the order have been produced + if (partSupplierNumber >= SUPPLIERS_PER_PART) { + availableQuantityRandom.rowFinished(); + supplyCostRandom.rowFinished(); + commentRandom.rowFinished(); + + index++; + partSupplierNumber = 0; + } + + return partSupplier; } - static long selectPartSupplier(long partKey, long supplierNumber, double scaleFactor) { - long supplierCount = (long) (SupplierGenerator.SCALE_BASE * scaleFactor); - return ((partKey + (supplierNumber * ((supplierCount / SUPPLIERS_PER_PART) + ((partKey - 1) / supplierCount)))) - % supplierCount) + 1; + private List makePartSupplier(long partKey) { + List partSupplier = new ArrayList<>(); + partSupplier.add(partKey); + partSupplier.add(selectPartSupplier(partKey, partSupplierNumber, scaleFactor)); + partSupplier.add((long) availableQuantityRandom.nextValue()); + partSupplier.add((double) supplyCostRandom.nextValue() / 100.); + partSupplier.add(commentRandom.nextValue()); + return partSupplier; } + } + + static long selectPartSupplier(long partKey, long supplierNumber, double scaleFactor) { + long supplierCount = (long) (SupplierGenerator.SCALE_BASE * scaleFactor); + return ((partKey + + (supplierNumber + * ((supplierCount / SUPPLIERS_PER_PART) + ((partKey - 1) / supplierCount)))) + % supplierCount) + + 1; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/RegionGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/RegionGenerator.java index 1f56b1abf..c132f3f43 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/RegionGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/RegionGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,61 +15,59 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; +import static java.util.Objects.requireNonNull; + +import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.ArrayList; -import static java.util.Objects.requireNonNull; +public class RegionGenerator implements Iterable> { + private static final int COMMENT_AVERAGE_LENGTH = 72; -public class RegionGenerator - implements Iterable> { - private static final int COMMENT_AVERAGE_LENGTH = 72; + private final Distributions distributions; + private final TextPool textPool; - private final Distributions distributions; - private final TextPool textPool; + public RegionGenerator() { + this(Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); + } - public RegionGenerator() { - this(Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); - } + public RegionGenerator(Distributions distributions, TextPool textPool) { + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } - public RegionGenerator(Distributions distributions, TextPool textPool) { - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); - } + @Override + public Iterator> iterator() { + return new RegionGeneratorIterator(distributions.getRegions(), textPool); + } - @Override - public Iterator> iterator() { - return new RegionGeneratorIterator(distributions.getRegions(), textPool); - } + private static class RegionGeneratorIterator implements Iterator> { + private final Distribution regions; + private final TPCHRandomText commentRandom; - private static class RegionGeneratorIterator - implements Iterator> { - private final Distribution regions; - private final TPCHRandomText commentRandom; + private int index; - private int index; - - private RegionGeneratorIterator(Distribution regions, TextPool textPool) { - this.regions = regions; - this.commentRandom = new TPCHRandomText(1500869201L, textPool, COMMENT_AVERAGE_LENGTH); - } + private RegionGeneratorIterator(Distribution regions, TextPool textPool) { + this.regions = regions; + this.commentRandom = new TPCHRandomText(1500869201L, textPool, COMMENT_AVERAGE_LENGTH); + } - @Override - public boolean hasNext() { - return index < regions.size(); - } + @Override + public boolean hasNext() { + return index < regions.size(); + } - @Override - public List next() { - List region = new ArrayList<>(); - region.add((long) index); - region.add(regions.getValue(index)); - region.add(commentRandom.nextValue()); + @Override + public List next() { + List region = new ArrayList<>(); + region.add((long) index); + region.add(regions.getValue(index)); + region.add(commentRandom.nextValue()); - commentRandom.rowFinished(); - index++; + commentRandom.rowFinished(); + index++; - return region; - } + return region; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/SupplierGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/SupplierGenerator.java index 38297bad2..b6abfd511 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/SupplierGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/SupplierGenerator.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,170 +15,174 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import java.util.Iterator; -import java.util.List; -import java.util.ArrayList; - -import com.oltpbenchmark.util.RowRandomBoundedInt; -import com.oltpbenchmark.util.RowRandomInt; - import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateRowCount; import static com.oltpbenchmark.benchmarks.tpch.util.GenerateUtils.calculateStartIndex; import static java.util.Locale.ENGLISH; import static java.util.Objects.requireNonNull; -public class SupplierGenerator - implements Iterable> { - public static final int SCALE_BASE = 10_000; - - private static final int ACCOUNT_BALANCE_MIN = -99999; - private static final int ACCOUNT_BALANCE_MAX = 999999; - private static final int ADDRESS_AVERAGE_LENGTH = 25; - private static final int COMMENT_AVERAGE_LENGTH = 63; - - public static final String BBB_BASE_TEXT = "Customer "; - public static final String BBB_COMPLAINT_TEXT = "Complaints"; - public static final String BBB_RECOMMEND_TEXT = "Recommends"; - public static final int BBB_COMMENT_LENGTH = BBB_BASE_TEXT.length() + BBB_COMPLAINT_TEXT.length(); - public static final int BBB_COMMENTS_PER_SCALE_BASE = 10; - public static final int BBB_COMPLAINT_PERCENT = 50; - - private final double scaleFactor; - private final int part; - private final int partCount; - - private final Distributions distributions; - private final TextPool textPool; +import com.oltpbenchmark.util.RowRandomBoundedInt; +import com.oltpbenchmark.util.RowRandomInt; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; - public SupplierGenerator(double scaleFactor, int part, int partCount) { - this(scaleFactor, part, partCount, Distributions.getDefaultDistributions(), TextPool.getDefaultTestPool()); +public class SupplierGenerator implements Iterable> { + public static final int SCALE_BASE = 10_000; + + private static final int ACCOUNT_BALANCE_MIN = -99999; + private static final int ACCOUNT_BALANCE_MAX = 999999; + private static final int ADDRESS_AVERAGE_LENGTH = 25; + private static final int COMMENT_AVERAGE_LENGTH = 63; + + public static final String BBB_BASE_TEXT = "Customer "; + public static final String BBB_COMPLAINT_TEXT = "Complaints"; + public static final String BBB_RECOMMEND_TEXT = "Recommends"; + public static final int BBB_COMMENT_LENGTH = BBB_BASE_TEXT.length() + BBB_COMPLAINT_TEXT.length(); + public static final int BBB_COMMENTS_PER_SCALE_BASE = 10; + public static final int BBB_COMPLAINT_PERCENT = 50; + + private final double scaleFactor; + private final int part; + private final int partCount; + + private final Distributions distributions; + private final TextPool textPool; + + public SupplierGenerator(double scaleFactor, int part, int partCount) { + this( + scaleFactor, + part, + partCount, + Distributions.getDefaultDistributions(), + TextPool.getDefaultTestPool()); + } + + public SupplierGenerator( + double scaleFactor, int part, int partCount, Distributions distributions, TextPool textPool) { + this.scaleFactor = scaleFactor; + this.part = part; + this.partCount = partCount; + + this.distributions = requireNonNull(distributions, "distributions is null"); + this.textPool = requireNonNull(textPool, "textPool is null"); + } + + @Override + public Iterator> iterator() { + return new SupplierGeneratorIterator( + distributions, + textPool, + calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), + calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + } + + private static class SupplierGeneratorIterator implements Iterator> { + private final TPCHRandomAlphaNumeric addressRandom = + new TPCHRandomAlphaNumeric(706178559L, ADDRESS_AVERAGE_LENGTH); + private final RowRandomBoundedInt nationKeyRandom; + private final TPCHRandomPhoneNumber phoneRandom = new TPCHRandomPhoneNumber(884434366L); + private final RowRandomBoundedInt accountBalanceRandom = + new RowRandomBoundedInt(962338209L, ACCOUNT_BALANCE_MIN, ACCOUNT_BALANCE_MAX); + private final TPCHRandomText commentRandom; + private final RowRandomBoundedInt bbbCommentRandom = + new RowRandomBoundedInt(202794285L, 1, SCALE_BASE); + private final RowRandomInt bbbJunkRandom = new RowRandomInt(263032577L, 1); + private final RowRandomInt bbbOffsetRandom = new RowRandomInt(715851524L, 1); + private final RowRandomBoundedInt bbbTypeRandom = new RowRandomBoundedInt(753643799L, 0, 100); + + private final long startIndex; + private final long rowCount; + + private long index; + + private SupplierGeneratorIterator( + Distributions distributions, TextPool textPool, long startIndex, long rowCount) { + this.startIndex = startIndex; + this.rowCount = rowCount; + + nationKeyRandom = + new RowRandomBoundedInt(110356601L, 0, distributions.getNations().size() - 1); + commentRandom = new TPCHRandomText(1341315363L, textPool, COMMENT_AVERAGE_LENGTH); + + addressRandom.advanceRows(startIndex); + nationKeyRandom.advanceRows(startIndex); + phoneRandom.advanceRows(startIndex); + accountBalanceRandom.advanceRows(startIndex); + commentRandom.advanceRows(startIndex); + bbbCommentRandom.advanceRows(startIndex); + bbbJunkRandom.advanceRows(startIndex); + bbbOffsetRandom.advanceRows(startIndex); + bbbTypeRandom.advanceRows(startIndex); } - public SupplierGenerator(double scaleFactor, int part, int partCount, Distributions distributions, - TextPool textPool) { - this.scaleFactor = scaleFactor; - this.part = part; - this.partCount = partCount; - - this.distributions = requireNonNull(distributions, "distributions is null"); - this.textPool = requireNonNull(textPool, "textPool is null"); + @Override + public boolean hasNext() { + return index < rowCount; } @Override - public Iterator> iterator() { - return new SupplierGeneratorIterator( - distributions, - textPool, - calculateStartIndex(SCALE_BASE, scaleFactor, part, partCount), - calculateRowCount(SCALE_BASE, scaleFactor, part, partCount)); + public List next() { + List supplier = makeSupplier(startIndex + index + 1); + + addressRandom.rowFinished(); + nationKeyRandom.rowFinished(); + phoneRandom.rowFinished(); + accountBalanceRandom.rowFinished(); + commentRandom.rowFinished(); + bbbCommentRandom.rowFinished(); + bbbJunkRandom.rowFinished(); + bbbOffsetRandom.rowFinished(); + bbbTypeRandom.rowFinished(); + + index++; + + return supplier; } - private static class SupplierGeneratorIterator - implements Iterator> { - private final TPCHRandomAlphaNumeric addressRandom = new TPCHRandomAlphaNumeric(706178559L, - ADDRESS_AVERAGE_LENGTH); - private final RowRandomBoundedInt nationKeyRandom; - private final TPCHRandomPhoneNumber phoneRandom = new TPCHRandomPhoneNumber(884434366L); - private final RowRandomBoundedInt accountBalanceRandom = new RowRandomBoundedInt(962338209L, - ACCOUNT_BALANCE_MIN, ACCOUNT_BALANCE_MAX); - private final TPCHRandomText commentRandom; - private final RowRandomBoundedInt bbbCommentRandom = new RowRandomBoundedInt(202794285L, 1, SCALE_BASE); - private final RowRandomInt bbbJunkRandom = new RowRandomInt(263032577L, 1); - private final RowRandomInt bbbOffsetRandom = new RowRandomInt(715851524L, 1); - private final RowRandomBoundedInt bbbTypeRandom = new RowRandomBoundedInt(753643799L, 0, 100); - - private final long startIndex; - private final long rowCount; - - private long index; - - private SupplierGeneratorIterator(Distributions distributions, TextPool textPool, long startIndex, - long rowCount) { - this.startIndex = startIndex; - this.rowCount = rowCount; - - nationKeyRandom = new RowRandomBoundedInt(110356601L, 0, distributions.getNations().size() - 1); - commentRandom = new TPCHRandomText(1341315363L, textPool, COMMENT_AVERAGE_LENGTH); - - addressRandom.advanceRows(startIndex); - nationKeyRandom.advanceRows(startIndex); - phoneRandom.advanceRows(startIndex); - accountBalanceRandom.advanceRows(startIndex); - commentRandom.advanceRows(startIndex); - bbbCommentRandom.advanceRows(startIndex); - bbbJunkRandom.advanceRows(startIndex); - bbbOffsetRandom.advanceRows(startIndex); - bbbTypeRandom.advanceRows(startIndex); - } + private List makeSupplier(long supplierKey) { + String comment = commentRandom.nextValue(); + + // Add supplier complaints or commendation to the comment + int bbbCommentRandomValue = bbbCommentRandom.nextValue(); + if (bbbCommentRandomValue <= BBB_COMMENTS_PER_SCALE_BASE) { + StringBuilder buffer = new StringBuilder(comment); + + // select random place for BBB comment + int noise = bbbJunkRandom.nextInt(0, (comment.length() - BBB_COMMENT_LENGTH)); + int offset = bbbOffsetRandom.nextInt(0, (comment.length() - (BBB_COMMENT_LENGTH + noise))); - @Override - public boolean hasNext() { - return index < rowCount; + // select complaint or recommendation + String type; + if (bbbTypeRandom.nextValue() < BBB_COMPLAINT_PERCENT) { + type = BBB_COMPLAINT_TEXT; + } else { + type = BBB_RECOMMEND_TEXT; } - @Override - public List next() { - List supplier = makeSupplier(startIndex + index + 1); + // write base text (e.g., "Customer ") + buffer.replace(offset, offset + BBB_BASE_TEXT.length(), BBB_BASE_TEXT); - addressRandom.rowFinished(); - nationKeyRandom.rowFinished(); - phoneRandom.rowFinished(); - accountBalanceRandom.rowFinished(); - commentRandom.rowFinished(); - bbbCommentRandom.rowFinished(); - bbbJunkRandom.rowFinished(); - bbbOffsetRandom.rowFinished(); - bbbTypeRandom.rowFinished(); + // write complaint or commendation text (e.g., "Complaints" or "Recommends") + buffer.replace( + BBB_BASE_TEXT.length() + offset + noise, + BBB_BASE_TEXT.length() + offset + noise + type.length(), + type); - index++; + comment = buffer.toString(); + } - return supplier; - } + long nationKey = nationKeyRandom.nextValue(); - private List makeSupplier(long supplierKey) { - String comment = commentRandom.nextValue(); - - // Add supplier complaints or commendation to the comment - int bbbCommentRandomValue = bbbCommentRandom.nextValue(); - if (bbbCommentRandomValue <= BBB_COMMENTS_PER_SCALE_BASE) { - StringBuilder buffer = new StringBuilder(comment); - - // select random place for BBB comment - int noise = bbbJunkRandom.nextInt(0, (comment.length() - BBB_COMMENT_LENGTH)); - int offset = bbbOffsetRandom.nextInt(0, (comment.length() - (BBB_COMMENT_LENGTH + noise))); - - // select complaint or recommendation - String type; - if (bbbTypeRandom.nextValue() < BBB_COMPLAINT_PERCENT) { - type = BBB_COMPLAINT_TEXT; - } else { - type = BBB_RECOMMEND_TEXT; - } - - // write base text (e.g., "Customer ") - buffer.replace(offset, offset + BBB_BASE_TEXT.length(), BBB_BASE_TEXT); - - // write complaint or commendation text (e.g., "Complaints" or "Recommends") - buffer.replace( - BBB_BASE_TEXT.length() + offset + noise, - BBB_BASE_TEXT.length() + offset + noise + type.length(), - type); - - comment = buffer.toString(); - } - - long nationKey = nationKeyRandom.nextValue(); - - List supplier = new ArrayList(); - supplier.add(supplierKey); - supplier.add(String.format(ENGLISH, "Supplier#%09d", supplierKey)); - supplier.add(addressRandom.nextValue()); - supplier.add(nationKey); - supplier.add(phoneRandom.nextValue(nationKey)); - supplier.add((double) accountBalanceRandom.nextValue() / 100.); - supplier.add(comment); - - return supplier; - } + List supplier = new ArrayList(); + supplier.add(supplierKey); + supplier.add(String.format(ENGLISH, "Supplier#%09d", supplierKey)); + supplier.add(addressRandom.nextValue()); + supplier.add(nationKey); + supplier.add(phoneRandom.nextValue(nationKey)); + supplier.add((double) accountBalanceRandom.nextValue() / 100.); + supplier.add(comment); + + return supplier; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomAlphaNumeric.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomAlphaNumeric.java index 2342d623b..f5d8f4301 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomAlphaNumeric.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomAlphaNumeric.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,41 +17,40 @@ import com.oltpbenchmark.util.RowRandomInt; -public class TPCHRandomAlphaNumeric - extends RowRandomInt { - private static final char[] ALPHA_NUMERIC = "0123456789abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ," - .toCharArray(); +public class TPCHRandomAlphaNumeric extends RowRandomInt { + private static final char[] ALPHA_NUMERIC = + "0123456789abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ,".toCharArray(); - private static final double LOW_LENGTH_MULTIPLIER = 0.4; - private static final double HIGH_LENGTH_MULTIPLIER = 1.6; + private static final double LOW_LENGTH_MULTIPLIER = 0.4; + private static final double HIGH_LENGTH_MULTIPLIER = 1.6; - private static final int USAGE_PER_ROW = 9; + private static final int USAGE_PER_ROW = 9; - private final int minLength; - private final int maxLength; + private final int minLength; + private final int maxLength; - public TPCHRandomAlphaNumeric(long seed, int averageLength) { - this(seed, averageLength, 1); - } + public TPCHRandomAlphaNumeric(long seed, int averageLength) { + this(seed, averageLength, 1); + } - public TPCHRandomAlphaNumeric(long seed, int averageLength, int seedsPerRow) { - super(seed, USAGE_PER_ROW * seedsPerRow); - this.minLength = (int) (averageLength * LOW_LENGTH_MULTIPLIER); - this.maxLength = (int) (averageLength * HIGH_LENGTH_MULTIPLIER); - } + public TPCHRandomAlphaNumeric(long seed, int averageLength, int seedsPerRow) { + super(seed, USAGE_PER_ROW * seedsPerRow); + this.minLength = (int) (averageLength * LOW_LENGTH_MULTIPLIER); + this.maxLength = (int) (averageLength * HIGH_LENGTH_MULTIPLIER); + } - public String nextValue() { - char[] buffer = new char[nextInt(minLength, maxLength)]; + public String nextValue() { + char[] buffer = new char[nextInt(minLength, maxLength)]; - long charIndex = 0; - for (int i = 0; i < buffer.length; i++) { - if (i % 5 == 0) { - charIndex = nextInt(0, Integer.MAX_VALUE); - } - buffer[i] = ALPHA_NUMERIC[(int) (charIndex & 0x3f)]; - charIndex >>= 6; - } - - return new String(buffer); + long charIndex = 0; + for (int i = 0; i < buffer.length; i++) { + if (i % 5 == 0) { + charIndex = nextInt(0, Integer.MAX_VALUE); + } + buffer[i] = ALPHA_NUMERIC[(int) (charIndex & 0x3f)]; + charIndex >>= 6; } + + return new String(buffer); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomPhoneNumber.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomPhoneNumber.java index 6727fd7c1..a8124b0c4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomPhoneNumber.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomPhoneNumber.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,29 +15,29 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import com.oltpbenchmark.util.RowRandomInt; - import static java.util.Locale.ENGLISH; -public class TPCHRandomPhoneNumber - extends RowRandomInt { - // limited by country codes in phone numbers - private static final int NATIONS_MAX = 90; +import com.oltpbenchmark.util.RowRandomInt; + +public class TPCHRandomPhoneNumber extends RowRandomInt { + // limited by country codes in phone numbers + private static final int NATIONS_MAX = 90; - public TPCHRandomPhoneNumber(long seed) { - this(seed, 1); - } + public TPCHRandomPhoneNumber(long seed) { + this(seed, 1); + } - public TPCHRandomPhoneNumber(long seed, int seedsPerRow) { - super(seed, 3 * seedsPerRow); - } + public TPCHRandomPhoneNumber(long seed, int seedsPerRow) { + super(seed, 3 * seedsPerRow); + } - public String nextValue(long nationKey) { - return String.format(ENGLISH, - "%02d-%03d-%03d-%04d", - (10 + (nationKey % NATIONS_MAX)), - nextInt(100, 999), - nextInt(100, 999), - nextInt(1000, 9999)); - } + public String nextValue(long nationKey) { + return String.format( + ENGLISH, + "%02d-%03d-%03d-%04d", + (10 + (nationKey % NATIONS_MAX)), + nextInt(100, 999), + nextInt(100, 999), + nextInt(1000, 9999)); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomString.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomString.java index 00afa4f9e..bc1dbc0e5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomString.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomString.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,20 +17,19 @@ import com.oltpbenchmark.util.RowRandomInt; -public class TPCHRandomString - extends RowRandomInt { - private final Distribution distribution; +public class TPCHRandomString extends RowRandomInt { + private final Distribution distribution; - public TPCHRandomString(long seed, Distribution distribution) { - this(seed, distribution, 1); - } + public TPCHRandomString(long seed, Distribution distribution) { + this(seed, distribution, 1); + } - public TPCHRandomString(long seed, Distribution distribution, int seedsPerRow) { - super(seed, seedsPerRow); - this.distribution = distribution; - } + public TPCHRandomString(long seed, Distribution distribution, int seedsPerRow) { + super(seed, seedsPerRow); + this.distribution = distribution; + } - public String nextValue() { - return distribution.randomValue(this); - } + public String nextValue() { + return distribution.randomValue(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomStringSequence.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomStringSequence.java index faec0c336..06964d420 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomStringSequence.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomStringSequence.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,39 +15,38 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import com.oltpbenchmark.util.StringUtil; import com.oltpbenchmark.util.RowRandomInt; - +import com.oltpbenchmark.util.StringUtil; import java.util.ArrayList; import java.util.Collections; import java.util.List; -public class TPCHRandomStringSequence - extends RowRandomInt { - private final int count; - private final Distribution distribution; +public class TPCHRandomStringSequence extends RowRandomInt { + private final int count; + private final Distribution distribution; - public TPCHRandomStringSequence(long seed, int count, Distribution distribution) { - this(seed, count, distribution, 1); - } - - public TPCHRandomStringSequence(long seed, int count, Distribution distribution, int seedsPerRow) { - super(seed, distribution.size() * seedsPerRow); - this.count = count; - this.distribution = distribution; - } + public TPCHRandomStringSequence(long seed, int count, Distribution distribution) { + this(seed, count, distribution, 1); + } - public String nextValue() { - List values = new ArrayList<>(distribution.getValues()); + public TPCHRandomStringSequence( + long seed, int count, Distribution distribution, int seedsPerRow) { + super(seed, distribution.size() * seedsPerRow); + this.count = count; + this.distribution = distribution; + } - // randomize first 'count' elements of the string - for (int currentPosition = 0; currentPosition < count; currentPosition++) { - int swapPosition = nextInt(currentPosition, values.size() - 1); - Collections.swap(values, currentPosition, swapPosition); - } + public String nextValue() { + List values = new ArrayList<>(distribution.getValues()); - // join random words - String result = StringUtil.join(" ", values.subList(0, count)); - return result; + // randomize first 'count' elements of the string + for (int currentPosition = 0; currentPosition < count; currentPosition++) { + int swapPosition = nextInt(currentPosition, values.size() - 1); + Collections.swap(values, currentPosition, swapPosition); } + + // join random words + String result = StringUtil.join(" ", values.subList(0, count)); + return result; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomText.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomText.java index ca834f12a..13896bba5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomText.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TPCHRandomText.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,29 +17,28 @@ import com.oltpbenchmark.util.RowRandomInt; -public class TPCHRandomText - extends RowRandomInt { - private static final double LOW_LENGTH_MULTIPLIER = 0.4; - private static final double HIGH_LENGTH_MULTIPLIER = 1.6; +public class TPCHRandomText extends RowRandomInt { + private static final double LOW_LENGTH_MULTIPLIER = 0.4; + private static final double HIGH_LENGTH_MULTIPLIER = 1.6; - private final TextPool textPool; - private final int minLength; - private final int maxLength; + private final TextPool textPool; + private final int minLength; + private final int maxLength; - public TPCHRandomText(long seed, TextPool textPool, double averageTextLength) { - this(seed, textPool, averageTextLength, 1); - } + public TPCHRandomText(long seed, TextPool textPool, double averageTextLength) { + this(seed, textPool, averageTextLength, 1); + } - public TPCHRandomText(long seed, TextPool textPool, double averageTextLength, int seedsPerRow) { - super(seed, seedsPerRow * 2); - this.textPool = textPool; - this.minLength = (int) (averageTextLength * LOW_LENGTH_MULTIPLIER); - this.maxLength = (int) (averageTextLength * HIGH_LENGTH_MULTIPLIER); - } + public TPCHRandomText(long seed, TextPool textPool, double averageTextLength, int seedsPerRow) { + super(seed, seedsPerRow * 2); + this.textPool = textPool; + this.minLength = (int) (averageTextLength * LOW_LENGTH_MULTIPLIER); + this.maxLength = (int) (averageTextLength * HIGH_LENGTH_MULTIPLIER); + } - public String nextValue() { - int offset = nextInt(0, textPool.size() - maxLength); - int length = nextInt(minLength, maxLength); - return textPool.getText(offset, offset + length); - } + public String nextValue() { + int offset = nextInt(0, textPool.size() - maxLength); + int length = nextInt(minLength, maxLength); + return textPool.getText(offset, offset + length); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPool.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPool.java index cd6363077..10d6ff74b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPool.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPool.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,191 +15,194 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import com.oltpbenchmark.util.RowRandomInt; - import static com.oltpbenchmark.benchmarks.tpch.util.Distributions.getDefaultDistributions; import static java.lang.String.format; import static java.nio.charset.StandardCharsets.US_ASCII; import static java.util.Objects.requireNonNull; +import com.oltpbenchmark.util.RowRandomInt; + public class TextPool { - private static final int DEFAULT_TEXT_POOL_SIZE = 300 * 1024 * 1024; - private static final int MAX_SENTENCE_LENGTH = 256; + private static final int DEFAULT_TEXT_POOL_SIZE = 300 * 1024 * 1024; + private static final int MAX_SENTENCE_LENGTH = 256; - private static final TextPool DEFAULT_TEXT_POOL = new TextPool(DEFAULT_TEXT_POOL_SIZE, getDefaultDistributions()); + private static final TextPool DEFAULT_TEXT_POOL = + new TextPool(DEFAULT_TEXT_POOL_SIZE, getDefaultDistributions()); - public static TextPool getDefaultTestPool() { - return DEFAULT_TEXT_POOL; - } + public static TextPool getDefaultTestPool() { + return DEFAULT_TEXT_POOL; + } - private final byte[] textPool; - private final int textPoolSize; + private final byte[] textPool; + private final int textPoolSize; - public TextPool(int size, Distributions distributions) { - this(size, distributions, progress -> { - }); - } + public TextPool(int size, Distributions distributions) { + this(size, distributions, progress -> {}); + } - public TextPool(int size, Distributions distributions, TextGenerationProgressMonitor monitor) { - requireNonNull(distributions, "distributions is null"); - requireNonNull(monitor, "monitor is null"); + public TextPool(int size, Distributions distributions, TextGenerationProgressMonitor monitor) { + requireNonNull(distributions, "distributions is null"); + requireNonNull(monitor, "monitor is null"); - ByteArrayBuilder output = new ByteArrayBuilder(size + MAX_SENTENCE_LENGTH); + ByteArrayBuilder output = new ByteArrayBuilder(size + MAX_SENTENCE_LENGTH); - RowRandomInt randomInt = new RowRandomInt(933588178L, Integer.MAX_VALUE); + RowRandomInt randomInt = new RowRandomInt(933588178L, Integer.MAX_VALUE); - while (output.getLength() < size) { - generateSentence(distributions, output, randomInt); - monitor.updateProgress(Math.min(1.0 * output.getLength() / size, 1.0)); - } - output.erase(output.getLength() - size); - textPool = output.getBytes(); - textPoolSize = output.getLength(); + while (output.getLength() < size) { + generateSentence(distributions, output, randomInt); + monitor.updateProgress(Math.min(1.0 * output.getLength() / size, 1.0)); } - - public int size() { - return textPoolSize; + output.erase(output.getLength() - size); + textPool = output.getBytes(); + textPoolSize = output.getLength(); + } + + public int size() { + return textPoolSize; + } + + public String getText(int begin, int end) { + if (end > textPoolSize) { + throw new IndexOutOfBoundsException( + format("Index %d is beyond end of text pool (size = %d)", end, textPoolSize)); } - - public String getText(int begin, int end) { - if (end > textPoolSize) { - throw new IndexOutOfBoundsException( - format("Index %d is beyond end of text pool (size = %d)", end, textPoolSize)); - } - return new String(textPool, begin, end - begin, US_ASCII); + return new String(textPool, begin, end - begin, US_ASCII); + } + + private static void generateSentence( + Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { + String syntax = distributions.getGrammars().randomValue(random); + + int maxLength = syntax.length(); + for (int i = 0; i < maxLength; i += 2) { + switch (syntax.charAt(i)) { + case 'V': + generateVerbPhrase(distributions, builder, random); + break; + case 'N': + generateNounPhrase(distributions, builder, random); + break; + case 'P': + String preposition = distributions.getPrepositions().randomValue(random); + builder.append(preposition); + builder.append(" the "); + generateNounPhrase(distributions, builder, random); + break; + case 'T': + // trim trailing space + // terminators should abut previous word + builder.erase(1); + String terminator = distributions.getTerminators().randomValue(random); + builder.append(terminator); + break; + default: + throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); + } + if (builder.getLastChar() != ' ') { + builder.append(" "); + } } - - private static void generateSentence(Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { - String syntax = distributions.getGrammars().randomValue(random); - - int maxLength = syntax.length(); - for (int i = 0; i < maxLength; i += 2) { - switch (syntax.charAt(i)) { - case 'V': - generateVerbPhrase(distributions, builder, random); - break; - case 'N': - generateNounPhrase(distributions, builder, random); - break; - case 'P': - String preposition = distributions.getPrepositions().randomValue(random); - builder.append(preposition); - builder.append(" the "); - generateNounPhrase(distributions, builder, random); - break; - case 'T': - // trim trailing space - // terminators should abut previous word - builder.erase(1); - String terminator = distributions.getTerminators().randomValue(random); - builder.append(terminator); - break; - default: - throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); - } - if (builder.getLastChar() != ' ') { - builder.append(" "); - } - } + } + + private static void generateVerbPhrase( + Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { + String syntax = distributions.getVerbPhrase().randomValue(random); + int maxLength = syntax.length(); + for (int i = 0; i < maxLength; i += 2) { + Distribution source; + switch (syntax.charAt(i)) { + case 'D': + source = distributions.getAdverbs(); + break; + case 'V': + source = distributions.getVerbs(); + break; + case 'X': + source = distributions.getAuxiliaries(); + break; + default: + throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); + } + + // pick a random word + String word = source.randomValue(random); + builder.append(word); + + // add a space + builder.append(" "); } - - private static void generateVerbPhrase(Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { - String syntax = distributions.getVerbPhrase().randomValue(random); - int maxLength = syntax.length(); - for (int i = 0; i < maxLength; i += 2) { - Distribution source; - switch (syntax.charAt(i)) { - case 'D': - source = distributions.getAdverbs(); - break; - case 'V': - source = distributions.getVerbs(); - break; - case 'X': - source = distributions.getAuxiliaries(); - break; - default: - throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); - } - - // pick a random word - String word = source.randomValue(random); - builder.append(word); - - // add a space - builder.append(" "); - } + } + + private static void generateNounPhrase( + Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { + String syntax = distributions.getNounPhrase().randomValue(random); + int maxLength = syntax.length(); + for (int i = 0; i < maxLength; i++) { + Distribution source; + switch (syntax.charAt(i)) { + case 'A': + source = distributions.getArticles(); + break; + case 'J': + source = distributions.getAdjectives(); + break; + case 'D': + source = distributions.getAdverbs(); + break; + case 'N': + source = distributions.getNouns(); + break; + case ',': + builder.erase(1); + builder.append(", "); + continue; + case ' ': + continue; + default: + throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); + } + // pick a random word + String word = source.randomValue(random); + builder.append(word); + + // add a space + builder.append(" "); } + } - private static void generateNounPhrase(Distributions distributions, ByteArrayBuilder builder, RowRandomInt random) { - String syntax = distributions.getNounPhrase().randomValue(random); - int maxLength = syntax.length(); - for (int i = 0; i < maxLength; i++) { - Distribution source; - switch (syntax.charAt(i)) { - case 'A': - source = distributions.getArticles(); - break; - case 'J': - source = distributions.getAdjectives(); - break; - case 'D': - source = distributions.getAdverbs(); - break; - case 'N': - source = distributions.getNouns(); - break; - case ',': - builder.erase(1); - builder.append(", "); - continue; - case ' ': - continue; - default: - throw new IllegalArgumentException("Unknown token '" + syntax.charAt(i) + "'"); - } - // pick a random word - String word = source.randomValue(random); - builder.append(word); - - // add a space - builder.append(" "); - } - } + public interface TextGenerationProgressMonitor { + void updateProgress(double progress); + } - public interface TextGenerationProgressMonitor { - void updateProgress(double progress); - } + private static class ByteArrayBuilder { + private int length; + private final byte[] bytes; - private static class ByteArrayBuilder { - private int length; - private final byte[] bytes; - - public ByteArrayBuilder(int size) { - this.bytes = new byte[size]; - } + public ByteArrayBuilder(int size) { + this.bytes = new byte[size]; + } - @SuppressWarnings("deprecation") - public void append(String string) { - // This is safe because the data is ASCII - string.getBytes(0, string.length(), bytes, length); - length += string.length(); - } + @SuppressWarnings("deprecation") + public void append(String string) { + // This is safe because the data is ASCII + string.getBytes(0, string.length(), bytes, length); + length += string.length(); + } - public void erase(int count) { - length -= count; - } + public void erase(int count) { + length -= count; + } - public int getLength() { - return length; - } + public int getLength() { + return length; + } - public byte[] getBytes() { - return bytes; - } + public byte[] getBytes() { + return bytes; + } - public char getLastChar() { - return (char) bytes[length - 1]; - } + public char getLastChar() { + return (char) bytes[length - 1]; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java index 66de3482c..5971dcf24 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/tpch/util/TextPoolGenerator.java @@ -15,223 +15,226 @@ */ package com.oltpbenchmark.benchmarks.tpch.util; -import com.oltpbenchmark.util.StringUtil; -import com.oltpbenchmark.util.RowRandomInt; +import static java.util.Objects.requireNonNull; +import com.oltpbenchmark.util.RowRandomInt; +import com.oltpbenchmark.util.StringUtil; import java.util.List; -import static java.util.Objects.requireNonNull; - public class TextPoolGenerator { - private static final int MAX_SENTENCE_LENGTH = 256; - - private final int size; - private final TextGenerationProgressMonitor monitor; - - private final ParsedDistribution grammars; - private final ParsedDistribution nounPhrases; - private final ParsedDistribution verbPhrases; - private final IndexedDistribution prepositions; - private final IndexedDistribution terminators; - private final IndexedDistribution adverbs; - private final IndexedDistribution verbs; - private final IndexedDistribution auxiliaries; - private final IndexedDistribution articles; - private final IndexedDistribution adjectives; - private final IndexedDistribution nouns; - - public TextPoolGenerator(int size, Distributions distributions) { - this(size, distributions, new TextGenerationProgressMonitor() { - @Override - public void updateProgress(double progress) { - } + private static final int MAX_SENTENCE_LENGTH = 256; + + private final int size; + private final TextGenerationProgressMonitor monitor; + + private final ParsedDistribution grammars; + private final ParsedDistribution nounPhrases; + private final ParsedDistribution verbPhrases; + private final IndexedDistribution prepositions; + private final IndexedDistribution terminators; + private final IndexedDistribution adverbs; + private final IndexedDistribution verbs; + private final IndexedDistribution auxiliaries; + private final IndexedDistribution articles; + private final IndexedDistribution adjectives; + private final IndexedDistribution nouns; + + public TextPoolGenerator(int size, Distributions distributions) { + this( + size, + distributions, + new TextGenerationProgressMonitor() { + @Override + public void updateProgress(double progress) {} }); + } + + public TextPoolGenerator( + int size, Distributions distributions, TextGenerationProgressMonitor monitor) { + this.size = size; + requireNonNull(distributions, "distributions is null"); + this.monitor = requireNonNull(monitor, "monitor is null"); + + this.grammars = new ParsedDistribution(distributions.getGrammars()); + this.nounPhrases = new ParsedDistribution(distributions.getNounPhrase()); + this.verbPhrases = new ParsedDistribution(distributions.getVerbPhrase()); + + prepositions = new IndexedDistribution(distributions.getPrepositions()); + terminators = new IndexedDistribution(distributions.getTerminators()); + adverbs = new IndexedDistribution(distributions.getAdverbs()); + verbs = new IndexedDistribution(distributions.getVerbs()); + auxiliaries = new IndexedDistribution(distributions.getAuxiliaries()); + articles = new IndexedDistribution(distributions.getArticles()); + adjectives = new IndexedDistribution(distributions.getAdjectives()); + nouns = new IndexedDistribution(distributions.getNouns()); + } + + public String generate() { + StringBuilder output = new StringBuilder(size + MAX_SENTENCE_LENGTH); + + RowRandomInt randomInt = new RowRandomInt(933588178L, Integer.MAX_VALUE); + + while (output.length() < size) { + generateSentence(output, randomInt); + monitor.updateProgress(Math.min(1.0 * output.length() / size, 1.0)); } - - public TextPoolGenerator(int size, Distributions distributions, TextGenerationProgressMonitor monitor) { - this.size = size; - requireNonNull(distributions, "distributions is null"); - this.monitor = requireNonNull(monitor, "monitor is null"); - - this.grammars = new ParsedDistribution(distributions.getGrammars()); - this.nounPhrases = new ParsedDistribution(distributions.getNounPhrase()); - this.verbPhrases = new ParsedDistribution(distributions.getVerbPhrase()); - - prepositions = new IndexedDistribution(distributions.getPrepositions()); - terminators = new IndexedDistribution(distributions.getTerminators()); - adverbs = new IndexedDistribution(distributions.getAdverbs()); - verbs = new IndexedDistribution(distributions.getVerbs()); - auxiliaries = new IndexedDistribution(distributions.getAuxiliaries()); - articles = new IndexedDistribution(distributions.getArticles()); - adjectives = new IndexedDistribution(distributions.getAdjectives()); - nouns = new IndexedDistribution(distributions.getNouns()); + output.setLength(size); + return output.toString(); + } + + private void generateSentence(StringBuilder builder, RowRandomInt random) { + int index = grammars.getRandomIndex(random); + for (char token : grammars.getTokens(index)) { + switch (token) { + case 'V': + generateVerbPhrase(builder, random); + break; + case 'N': + generateNounPhrase(builder, random); + break; + case 'P': + String preposition = prepositions.randomValue(random); + builder.append(preposition); + builder.append(" the "); + generateNounPhrase(builder, random); + break; + case 'T': + // trim trailing space + // terminators should abut previous word + builder.setLength(builder.length() - 1); + String terminator = terminators.randomValue(random); + builder.append(terminator); + break; + default: + throw new IllegalStateException("Unknown token '" + token + "'"); + } + if (builder.charAt(builder.length() - 1) != ' ') { + builder.append(' '); + } + } + } + + private void generateVerbPhrase(StringBuilder builder, RowRandomInt random) { + int index = verbPhrases.getRandomIndex(random); + for (char token : verbPhrases.getTokens(index)) { + // pick a random word + switch (token) { + case 'D': + builder.append(adverbs.randomValue(random)); + break; + case 'V': + builder.append(verbs.randomValue(random)); + break; + case 'X': + builder.append(auxiliaries.randomValue(random)); + break; + default: + throw new IllegalStateException("Unknown token '" + token + "'"); + } + + // string may end with a comma or such + builder.append(nounPhrases.getBonusText(index)); + + // add a space + builder.append(" "); } + } + + private void generateNounPhrase(StringBuilder builder, RowRandomInt random) { + int index = nounPhrases.getRandomIndex(random); + for (char token : nounPhrases.getTokens(index)) { + // pick a random word + switch (token) { + case 'A': + builder.append(articles.randomValue(random)); + break; + case 'J': + builder.append(adjectives.randomValue(random)); + break; + case 'D': + builder.append(adverbs.randomValue(random)); + break; + case 'N': + builder.append(nouns.randomValue(random)); + break; + default: + throw new IllegalStateException("Unknown token '" + token + "'"); + } + + // string may end with a comma or such + builder.append(nounPhrases.getBonusText(index)); + + // add a space + builder.append(" "); + } + } - public String generate() { - StringBuilder output = new StringBuilder(size + MAX_SENTENCE_LENGTH); + public interface TextGenerationProgressMonitor { + void updateProgress(double progress); + } - RowRandomInt randomInt = new RowRandomInt(933588178L, Integer.MAX_VALUE); + private static class IndexedDistribution { + private final String[] randomTable; - while (output.length() < size) { - generateSentence(output, randomInt); - monitor.updateProgress(Math.min(1.0 * output.length() / size, 1.0)); + private IndexedDistribution(Distribution distribution) { + randomTable = new String[distribution.getWeight(distribution.size() - 1)]; + int valueIndex = 0; + for (int i = 0; i < randomTable.length; i++) { + if (i >= distribution.getWeight(valueIndex)) { + valueIndex++; } - output.setLength(size); - return output.toString(); + randomTable[i] = distribution.getValue(valueIndex); + } } - private void generateSentence(StringBuilder builder, RowRandomInt random) { - int index = grammars.getRandomIndex(random); - for (char token : grammars.getTokens(index)) { - switch (token) { - case 'V': - generateVerbPhrase(builder, random); - break; - case 'N': - generateNounPhrase(builder, random); - break; - case 'P': - String preposition = prepositions.randomValue(random); - builder.append(preposition); - builder.append(" the "); - generateNounPhrase(builder, random); - break; - case 'T': - // trim trailing space - // terminators should abut previous word - builder.setLength(builder.length() - 1); - String terminator = terminators.randomValue(random); - builder.append(terminator); - break; - default: - throw new IllegalStateException("Unknown token '" + token + "'"); - } - if (builder.charAt(builder.length() - 1) != ' ') { - builder.append(' '); - } - } + public String randomValue(RowRandomInt random) { + int randomIndex = random.nextInt(0, randomTable.length - 1); + return randomTable[randomIndex]; } - - private void generateVerbPhrase(StringBuilder builder, RowRandomInt random) { - int index = verbPhrases.getRandomIndex(random); - for (char token : verbPhrases.getTokens(index)) { - // pick a random word - switch (token) { - case 'D': - builder.append(adverbs.randomValue(random)); - break; - case 'V': - builder.append(verbs.randomValue(random)); - break; - case 'X': - builder.append(auxiliaries.randomValue(random)); - break; - default: - throw new IllegalStateException("Unknown token '" + token + "'"); - } - - // string may end with a comma or such - builder.append(nounPhrases.getBonusText(index)); - - // add a space - builder.append(" "); + } + + private static class ParsedDistribution { + private final char[][] parsedDistribution; + private final String[] bonusText; + + private final int[] randomTable; + + private ParsedDistribution(Distribution distribution) { + parsedDistribution = new char[distribution.size()][]; + bonusText = new String[distribution.size()]; + for (int i = 0; i < distribution.size(); i++) { + List tokens = + StringUtil.splitToList(StringUtil.WHITESPACE, distribution.getValue(i)); + + parsedDistribution[i] = new char[tokens.size()]; + for (int j = 0; j < parsedDistribution[i].length; j++) { + String token = tokens.get(j); + parsedDistribution[i][j] = token.charAt(0); + bonusText[i] = token.substring(1); } - } + } - private void generateNounPhrase(StringBuilder builder, RowRandomInt random) { - int index = nounPhrases.getRandomIndex(random); - for (char token : nounPhrases.getTokens(index)) { - // pick a random word - switch (token) { - case 'A': - builder.append(articles.randomValue(random)); - break; - case 'J': - builder.append(adjectives.randomValue(random)); - break; - case 'D': - builder.append(adverbs.randomValue(random)); - break; - case 'N': - builder.append(nouns.randomValue(random)); - break; - default: - throw new IllegalStateException("Unknown token '" + token + "'"); - } - - // string may end with a comma or such - builder.append(nounPhrases.getBonusText(index)); - - // add a space - builder.append(" "); + randomTable = new int[distribution.getWeight(distribution.size() - 1)]; + int valueIndex = 0; + for (int i = 0; i < randomTable.length; i++) { + if (i >= distribution.getWeight(valueIndex)) { + valueIndex++; } + randomTable[i] = valueIndex; + } } - public interface TextGenerationProgressMonitor { - void updateProgress(double progress); + public int getRandomIndex(RowRandomInt random) { + int randomIndex = random.nextInt(0, randomTable.length - 1); + return randomTable[randomIndex]; } - private static class IndexedDistribution { - private final String[] randomTable; - - private IndexedDistribution(Distribution distribution) { - randomTable = new String[distribution.getWeight(distribution.size() - 1)]; - int valueIndex = 0; - for (int i = 0; i < randomTable.length; i++) { - if (i >= distribution.getWeight(valueIndex)) { - valueIndex++; - } - randomTable[i] = distribution.getValue(valueIndex); - } - } - - public String randomValue(RowRandomInt random) { - int randomIndex = random.nextInt(0, randomTable.length - 1); - return randomTable[randomIndex]; - } + public char[] getTokens(int index) { + return parsedDistribution[index]; } - private static class ParsedDistribution { - private final char[][] parsedDistribution; - private final String[] bonusText; - - private final int[] randomTable; - - private ParsedDistribution(Distribution distribution) { - parsedDistribution = new char[distribution.size()][]; - bonusText = new String[distribution.size()]; - for (int i = 0; i < distribution.size(); i++) { - List tokens = StringUtil.splitToList(StringUtil.WHITESPACE, distribution.getValue(i)); - - parsedDistribution[i] = new char[tokens.size()]; - for (int j = 0; j < parsedDistribution[i].length; j++) { - String token = tokens.get(j); - parsedDistribution[i][j] = token.charAt(0); - bonusText[i] = token.substring(1); - } - } - - randomTable = new int[distribution.getWeight(distribution.size() - 1)]; - int valueIndex = 0; - for (int i = 0; i < randomTable.length; i++) { - if (i >= distribution.getWeight(valueIndex)) { - valueIndex++; - } - randomTable[i] = valueIndex; - } - } - - public int getRandomIndex(RowRandomInt random) { - int randomIndex = random.nextInt(0, randomTable.length - 1); - return randomTable[randomIndex]; - } - - public char[] getTokens(int index) { - return parsedDistribution[index]; - } - - public String getBonusText(int index) { - return bonusText[index]; - } + public String getBonusText(int index) { + return bonusText[index]; } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterBenchmark.java index f48cd7821..448f6d929 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterBenchmark.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.twitter; import com.oltpbenchmark.WorkloadConfiguration; @@ -26,52 +25,58 @@ import com.oltpbenchmark.benchmarks.twitter.procedures.GetFollowers; import com.oltpbenchmark.benchmarks.twitter.util.TraceTransactionGenerator; import com.oltpbenchmark.benchmarks.twitter.util.TwitterOperation; -import org.apache.commons.io.FileUtils; - import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import org.apache.commons.io.FileUtils; public final class TwitterBenchmark extends BenchmarkModule { - private final TwitterConfiguration twitterConf; + private final TwitterConfiguration twitterConf; - public TwitterBenchmark(WorkloadConfiguration workConf) { - super(workConf); - this.twitterConf = new TwitterConfiguration(workConf); - } + public TwitterBenchmark(WorkloadConfiguration workConf) { + super(workConf); + this.twitterConf = new TwitterConfiguration(workConf); + } - @Override - protected Package getProcedurePackageImpl() { - return GetFollowers.class.getPackage(); - } - - @Override - protected List> makeWorkersImpl() throws IOException { - List tweetIds = FileUtils.readLines(new File(twitterConf.getTracefile()), Charset.defaultCharset()); - List userIds = FileUtils.readLines(new File(twitterConf.getTracefile2()), Charset.defaultCharset()); + @Override + protected Package getProcedurePackageImpl() { + return GetFollowers.class.getPackage(); + } - if (tweetIds.size() != userIds.size()) { - throw new RuntimeException(String.format("there was a problem reading files, sizes don't match. tweets %d, userids %d", tweetIds.size(), userIds.size())); - } + @Override + protected List> makeWorkersImpl() throws IOException { + List tweetIds = + FileUtils.readLines(new File(twitterConf.getTracefile()), Charset.defaultCharset()); + List userIds = + FileUtils.readLines(new File(twitterConf.getTracefile2()), Charset.defaultCharset()); - List trace = new ArrayList<>(); - for (int i = 0; i < tweetIds.size(); i++) { - trace.add(new TwitterOperation(Integer.parseInt(tweetIds.get(i)), Integer.parseInt(userIds.get(i)))); - } + if (tweetIds.size() != userIds.size()) { + throw new RuntimeException( + String.format( + "there was a problem reading files, sizes don't match. tweets %d, userids %d", + tweetIds.size(), userIds.size())); + } - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - TransactionGenerator generator = new TraceTransactionGenerator(trace); - workers.add(new TwitterWorker(this, i, generator)); - } - return workers; + List trace = new ArrayList<>(); + for (int i = 0; i < tweetIds.size(); i++) { + trace.add( + new TwitterOperation( + Integer.parseInt(tweetIds.get(i)), Integer.parseInt(userIds.get(i)))); } - @Override - protected Loader makeLoaderImpl() { - return new TwitterLoader(this); + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + TransactionGenerator generator = new TraceTransactionGenerator(trace); + workers.add(new TwitterWorker(this, i, generator)); } + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new TwitterLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConfiguration.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConfiguration.java index b5dc214a5..2feb5bad1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConfiguration.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConfiguration.java @@ -22,17 +22,17 @@ public class TwitterConfiguration { - private final XMLConfiguration xmlConfig; + private final XMLConfiguration xmlConfig; - public TwitterConfiguration(WorkloadConfiguration workConf) { - this.xmlConfig = workConf.getXmlConfig(); - } + public TwitterConfiguration(WorkloadConfiguration workConf) { + this.xmlConfig = workConf.getXmlConfig(); + } - public String getTracefile() { - return xmlConfig.getString("tracefile", null); - } + public String getTracefile() { + return xmlConfig.getString("tracefile", null); + } - public String getTracefile2() { - return xmlConfig.getString("tracefile2", null); - } + public String getTracefile2() { + return xmlConfig.getString("tracefile2", null); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConstants.java index 153d89eec..3c4e75439 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterConstants.java @@ -19,40 +19,30 @@ public abstract class TwitterConstants { - public static final String TABLENAME_USER = "user_profiles"; - public static final String TABLENAME_TWEETS = "tweets"; - public static final String TABLENAME_FOLLOWS = "follows"; - public static final String TABLENAME_FOLLOWERS = "followers"; - public static final String TABLENAME_ADDED_TWEETS = "added_tweets"; - - /** - * Number of user baseline - */ - public static final int NUM_USERS = 500; - - /** - * Number of tweets baseline - */ - public static final int NUM_TWEETS = 20000; - - /** - * Max follow per user baseline - */ - public static final int MAX_FOLLOW_PER_USER = 50; - - /** - * Message length (inclusive) - */ - public static final int MAX_TWEET_LENGTH = 140; - - /** - * Name length (inclusive) - */ - public static final int MIN_NAME_LENGTH = 3; - public static final int MAX_NAME_LENGTH = 20; - // TODO: make the next parameters of WorkLoadConfiguration - public static int LIMIT_TWEETS = 100; - public static int LIMIT_TWEETS_FOR_UID = 10; - public static int LIMIT_FOLLOWERS = 20; + public static final String TABLENAME_USER = "user_profiles"; + public static final String TABLENAME_TWEETS = "tweets"; + public static final String TABLENAME_FOLLOWS = "follows"; + public static final String TABLENAME_FOLLOWERS = "followers"; + public static final String TABLENAME_ADDED_TWEETS = "added_tweets"; + /** Number of user baseline */ + public static final int NUM_USERS = 500; + + /** Number of tweets baseline */ + public static final int NUM_TWEETS = 20000; + + /** Max follow per user baseline */ + public static final int MAX_FOLLOW_PER_USER = 50; + + /** Message length (inclusive) */ + public static final int MAX_TWEET_LENGTH = 140; + + /** Name length (inclusive) */ + public static final int MIN_NAME_LENGTH = 3; + + public static final int MAX_NAME_LENGTH = 20; + // TODO: make the next parameters of WorkLoadConfiguration + public static int LIMIT_TWEETS = 100; + public static int LIMIT_TWEETS_FOR_UID = 10; + public static int LIMIT_FOLLOWERS = 20; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java index 7e0d80311..6f3a6910a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterLoader.java @@ -27,7 +27,6 @@ import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -36,281 +35,276 @@ import java.util.concurrent.CountDownLatch; public final class TwitterLoader extends Loader { - private final int num_users; - private final long num_tweets; - private final int num_follows; - - public TwitterLoader(TwitterBenchmark benchmark) { - super(benchmark); - this.num_users = (int) Math.round(TwitterConstants.NUM_USERS * this.scaleFactor); - this.num_tweets = (int) Math.round(TwitterConstants.NUM_TWEETS * this.scaleFactor); - this.num_follows = (int) Math.round(TwitterConstants.MAX_FOLLOW_PER_USER * this.scaleFactor); - if (LOG.isDebugEnabled()) { - LOG.debug("# of USERS: {}", this.num_users); - LOG.debug("# of TWEETS: {}", this.num_tweets); - LOG.debug("# of FOLLOWS: {}", this.num_follows); - } + private final int num_users; + private final long num_tweets; + private final int num_follows; + + public TwitterLoader(TwitterBenchmark benchmark) { + super(benchmark); + this.num_users = (int) Math.round(TwitterConstants.NUM_USERS * this.scaleFactor); + this.num_tweets = (int) Math.round(TwitterConstants.NUM_TWEETS * this.scaleFactor); + this.num_follows = (int) Math.round(TwitterConstants.MAX_FOLLOW_PER_USER * this.scaleFactor); + if (LOG.isDebugEnabled()) { + LOG.debug("# of USERS: {}", this.num_users); + LOG.debug("# of TWEETS: {}", this.num_tweets); + LOG.debug("# of FOLLOWS: {}", this.num_follows); } + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + // first we load USERS + final int itemsPerThread = Math.max(this.num_users / numLoaders, 1); + final int numUserThreads = (int) Math.ceil((double) this.num_users / itemsPerThread); + // then we load FOLLOWS and TWEETS + final long tweetsPerThread = Math.max(this.num_tweets / numLoaders, 1); + final int numTweetThreads = (int) Math.ceil((double) this.num_tweets / tweetsPerThread); + + final CountDownLatch userLatch = new CountDownLatch(numUserThreads); + + // USERS + for (int i = 0; i < numUserThreads; i++) { + final int lo = i * itemsPerThread + 1; + final int hi = Math.min(this.num_users, (i + 1) * itemsPerThread); + + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadUsers(conn, lo, hi); + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - // first we load USERS - final int itemsPerThread = Math.max(this.num_users / numLoaders, 1); - final int numUserThreads = (int) Math.ceil((double) this.num_users / itemsPerThread); - // then we load FOLLOWS and TWEETS - final long tweetsPerThread = Math.max(this.num_tweets / numLoaders, 1); - final int numTweetThreads = (int) Math.ceil((double) this.num_tweets / tweetsPerThread); - - final CountDownLatch userLatch = new CountDownLatch(numUserThreads); - - // USERS - for (int i = 0; i < numUserThreads; i++) { - final int lo = i * itemsPerThread + 1; - final int hi = Math.min(this.num_users, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadUsers(conn, lo, hi); - - } - - @Override - public void afterLoad() { - userLatch.countDown(); - } - }); - } - - // FOLLOW_DATA depends on USERS - for (int i = 0; i < numUserThreads; i++) { - final int lo = i * itemsPerThread + 1; - final int hi = Math.min(this.num_users, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - loadFollowData(conn, lo, hi); - } - - @Override - public void beforeLoad() { - try { - userLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - } - }); - } - - // TWEETS depends on USERS - for (int i = 0; i < numTweetThreads; i++) { - final long lo = i * tweetsPerThread + 1; - final long hi = Math.min(this.num_tweets, (i + 1) * tweetsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - - - loadTweets(conn, lo, hi); - } - - @Override - public void beforeLoad() { - try { - userLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - } - - return threads; + @Override + public void afterLoad() { + userLatch.countDown(); + } + }); } - /** - * @throws SQLException - * @author Djellel Load num_users users. - */ - protected void loadUsers(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_USER); - - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + // FOLLOW_DATA depends on USERS + for (int i = 0; i < numUserThreads; i++) { + final int lo = i * itemsPerThread + 1; + final int hi = Math.min(this.num_users, (i + 1) * itemsPerThread); - int total = 0; - - try (PreparedStatement userInsert = conn.prepareStatement(sql)) { - int batchSize = 0; - - NameHistogram name_h = new NameHistogram(); - FlatHistogram name_len_rng = new FlatHistogram<>(this.rng(), name_h); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadFollowData(conn, lo, hi); + } - for (int i = lo; i <= hi; i++) { - // Generate a random username for this user - int name_length = name_len_rng.nextValue(); - String name = TextGenerator.randomStr(this.rng(), name_length); + @Override + public void beforeLoad() { + try { + userLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + } - userInsert.setInt(1, i); // ID - userInsert.setString(2, name); // NAME - userInsert.setString(3, name + "@tweeter.com"); // EMAIL - userInsert.setNull(4, java.sql.Types.INTEGER); - userInsert.setNull(5, java.sql.Types.INTEGER); - userInsert.setNull(6, java.sql.Types.INTEGER); - userInsert.addBatch(); + // TWEETS depends on USERS + for (int i = 0; i < numTweetThreads; i++) { + final long lo = i * tweetsPerThread + 1; + final long hi = Math.min(this.num_tweets, (i + 1) * tweetsPerThread); - batchSize++; - total++; - if ((batchSize % workConf.getBatchSize()) == 0) { - userInsert.executeBatch(); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { - userInsert.clearBatch(); - batchSize = 0; - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Users %d / %d", total, this.num_users)); - } - } + loadTweets(conn, lo, hi); } - if (batchSize > 0) { - userInsert.executeBatch(); - userInsert.clearBatch(); + + @Override + public void beforeLoad() { + try { + userLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Users Loaded [%d]", total)); - } + }); } - /** - * @throws SQLException - * @author Djellel What's going on here?: The number of tweets is fixed to - * num_tweets We simply select using the distribution who issued the - * tweet - */ - protected void loadTweets(Connection conn, long lo, long hi) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_TWEETS); - - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - int total = 0; - - try (PreparedStatement tweetInsert = conn.prepareStatement(sql)) { - - - int batchSize = 0; - ScrambledZipfianGenerator zy = new ScrambledZipfianGenerator(1, this.num_users); - - TweetHistogram tweet_h = new TweetHistogram(); - FlatHistogram tweet_len_rng = new FlatHistogram<>(this.rng(), tweet_h); - - for (long i = lo; i <= hi; i++) { - int uid = zy.nextInt(); - tweetInsert.setLong(1, i); - tweetInsert.setInt(2, uid); - tweetInsert.setString(3, TextGenerator.randomStr(this.rng(), tweet_len_rng.nextValue())); - tweetInsert.setNull(4, java.sql.Types.DATE); - tweetInsert.addBatch(); - batchSize++; - total++; - - if ((batchSize % workConf.getBatchSize()) == 0) { - tweetInsert.executeBatch(); - tweetInsert.clearBatch(); - batchSize = 0; - if (LOG.isDebugEnabled()) { - LOG.debug("tweet % {}/{}", total, this.num_tweets); - } - } - } - if (batchSize > 0) { - tweetInsert.executeBatch(); - } + return threads; + } + + /** + * @throws SQLException + * @author Djellel Load num_users users. + */ + protected void loadUsers(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_USER); + + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + + try (PreparedStatement userInsert = conn.prepareStatement(sql)) { + int batchSize = 0; + + NameHistogram name_h = new NameHistogram(); + FlatHistogram name_len_rng = new FlatHistogram<>(this.rng(), name_h); + + for (int i = lo; i <= hi; i++) { + // Generate a random username for this user + int name_length = name_len_rng.nextValue(); + String name = TextGenerator.randomStr(this.rng(), name_length); + + userInsert.setInt(1, i); // ID + userInsert.setString(2, name); // NAME + userInsert.setString(3, name + "@tweeter.com"); // EMAIL + userInsert.setNull(4, java.sql.Types.INTEGER); + userInsert.setNull(5, java.sql.Types.INTEGER); + userInsert.setNull(6, java.sql.Types.INTEGER); + userInsert.addBatch(); + + batchSize++; + total++; + if ((batchSize % workConf.getBatchSize()) == 0) { + userInsert.executeBatch(); + + userInsert.clearBatch(); + batchSize = 0; + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Users %d / %d", total, this.num_users)); + } } - if (LOG.isDebugEnabled()) { - LOG.debug("[Tweets Loaded] {}", this.num_tweets); + } + if (batchSize > 0) { + userInsert.executeBatch(); + userInsert.clearBatch(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Users Loaded [%d]", total)); + } + } + + /** + * @throws SQLException + * @author Djellel What's going on here?: The number of tweets is fixed to num_tweets We simply + * select using the distribution who issued the tweet + */ + protected void loadTweets(Connection conn, long lo, long hi) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_TWEETS); + + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + int total = 0; + + try (PreparedStatement tweetInsert = conn.prepareStatement(sql)) { + + int batchSize = 0; + ScrambledZipfianGenerator zy = new ScrambledZipfianGenerator(1, this.num_users); + + TweetHistogram tweet_h = new TweetHistogram(); + FlatHistogram tweet_len_rng = new FlatHistogram<>(this.rng(), tweet_h); + + for (long i = lo; i <= hi; i++) { + int uid = zy.nextInt(); + tweetInsert.setLong(1, i); + tweetInsert.setInt(2, uid); + tweetInsert.setString(3, TextGenerator.randomStr(this.rng(), tweet_len_rng.nextValue())); + tweetInsert.setNull(4, java.sql.Types.DATE); + tweetInsert.addBatch(); + batchSize++; + total++; + + if ((batchSize % workConf.getBatchSize()) == 0) { + tweetInsert.executeBatch(); + tweetInsert.clearBatch(); + batchSize = 0; + if (LOG.isDebugEnabled()) { + LOG.debug("tweet % {}/{}", total, this.num_tweets); + } } + } + if (batchSize > 0) { + tweetInsert.executeBatch(); + } } - - /** - * @throws SQLException - * @author Djellel What's going on here?: For each user (follower) we select - * how many users he is following (followees List) then select users - * to fill up that list. Selecting is based on the distribution. - * NOTE: We are using two different distribution to avoid - * correlation: ZipfianGenerator (describes the followed most) - * ScrambledZipfianGenerator (describes the heavy tweeters) - */ - protected void loadFollowData(Connection conn, int lo, int hi) throws SQLException { - - int total = 1; - - Table followsTable = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_FOLLOWS); - Table followersTable = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_FOLLOWERS); - - String followsTableSql = SQLUtil.getInsertSQL(followsTable, this.getDatabaseType()); - String followersTableSql = SQLUtil.getInsertSQL(followersTable, this.getDatabaseType()); - - try (PreparedStatement followsInsert = conn.prepareStatement(followsTableSql); - PreparedStatement followersInsert = conn.prepareStatement(followersTableSql)) { - - - int batchSize = 0; - - ZipfianGenerator zipfFollowee = new ZipfianGenerator(rng(),1, this.num_users, 1.75); - ZipfianGenerator zipfFollows = new ZipfianGenerator(rng(), this.num_follows, 1.75); - List followees = new ArrayList<>(); - for (int follower = lo; follower <= hi; follower++) { - followees.clear(); - int time = zipfFollows.nextInt(); - if (time == 0) { - time = 1; // At least this follower will follow 1 user - } - for (int f = 0; f < time; ) { - int followee = zipfFollowee.nextInt(); - if (follower != followee && !followees.contains(followee)) { - followsInsert.setInt(1, follower); - followsInsert.setInt(2, followee); - followsInsert.addBatch(); - - followersInsert.setInt(1, followee); - followersInsert.setInt(2, follower); - followersInsert.addBatch(); - - followees.add(followee); - - total++; - batchSize++; - - - if ((batchSize % workConf.getBatchSize()) == 0) { - followsInsert.executeBatch(); - followersInsert.executeBatch(); - followsInsert.clearBatch(); - followersInsert.clearBatch(); - batchSize = 0; - if (LOG.isDebugEnabled()) { - LOG.debug("Follows % {}", (int) (((double) follower / (double) this.num_users) * 100)); - } - } - } - - f++; - } - } - if (batchSize > 0) { - followsInsert.executeBatch(); - followersInsert.executeBatch(); - } + if (LOG.isDebugEnabled()) { + LOG.debug("[Tweets Loaded] {}", this.num_tweets); + } + } + + /** + * @throws SQLException + * @author Djellel What's going on here?: For each user (follower) we select how many users he is + * following (followees List) then select users to fill up that list. Selecting is based on + * the distribution. NOTE: We are using two different distribution to avoid correlation: + * ZipfianGenerator (describes the followed most) ScrambledZipfianGenerator (describes the + * heavy tweeters) + */ + protected void loadFollowData(Connection conn, int lo, int hi) throws SQLException { + + int total = 1; + + Table followsTable = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_FOLLOWS); + Table followersTable = benchmark.getCatalog().getTable(TwitterConstants.TABLENAME_FOLLOWERS); + + String followsTableSql = SQLUtil.getInsertSQL(followsTable, this.getDatabaseType()); + String followersTableSql = SQLUtil.getInsertSQL(followersTable, this.getDatabaseType()); + + try (PreparedStatement followsInsert = conn.prepareStatement(followsTableSql); + PreparedStatement followersInsert = conn.prepareStatement(followersTableSql)) { + + int batchSize = 0; + + ZipfianGenerator zipfFollowee = new ZipfianGenerator(rng(), 1, this.num_users, 1.75); + ZipfianGenerator zipfFollows = new ZipfianGenerator(rng(), this.num_follows, 1.75); + List followees = new ArrayList<>(); + for (int follower = lo; follower <= hi; follower++) { + followees.clear(); + int time = zipfFollows.nextInt(); + if (time == 0) { + time = 1; // At least this follower will follow 1 user } - if (LOG.isDebugEnabled()) { - LOG.debug("[Follows Loaded] {}", total); + for (int f = 0; f < time; ) { + int followee = zipfFollowee.nextInt(); + if (follower != followee && !followees.contains(followee)) { + followsInsert.setInt(1, follower); + followsInsert.setInt(2, followee); + followsInsert.addBatch(); + + followersInsert.setInt(1, followee); + followersInsert.setInt(2, follower); + followersInsert.addBatch(); + + followees.add(followee); + + total++; + batchSize++; + + if ((batchSize % workConf.getBatchSize()) == 0) { + followsInsert.executeBatch(); + followersInsert.executeBatch(); + followsInsert.clearBatch(); + followersInsert.clearBatch(); + batchSize = 0; + if (LOG.isDebugEnabled()) { + LOG.debug( + "Follows % {}", (int) (((double) follower / (double) this.num_users) * 100)); + } + } + } + + f++; } + } + if (batchSize > 0) { + followsInsert.executeBatch(); + followersInsert.executeBatch(); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("[Follows Loaded] {}", total); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterWorker.java index 5f08756e8..05d81e6d8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/TwitterWorker.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.twitter; import com.oltpbenchmark.api.Procedure.UserAbortException; @@ -28,77 +27,80 @@ import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.SQLException; import java.sql.Time; public final class TwitterWorker extends Worker { - private final TransactionGenerator generator; - - private final FlatHistogram tweet_len_rng; - private final int num_users; - - public TwitterWorker(TwitterBenchmark benchmarkModule, int id, TransactionGenerator generator) { - super(benchmarkModule, id); - this.generator = generator; - this.num_users = (int) Math.round(TwitterConstants.NUM_USERS * this.getWorkloadConfiguration().getScaleFactor()); - - TweetHistogram tweet_h = new TweetHistogram(); - this.tweet_len_rng = new FlatHistogram<>(this.rng(), tweet_h); + private final TransactionGenerator generator; + + private final FlatHistogram tweet_len_rng; + private final int num_users; + + public TwitterWorker( + TwitterBenchmark benchmarkModule, int id, TransactionGenerator generator) { + super(benchmarkModule, id); + this.generator = generator; + this.num_users = + (int) + Math.round( + TwitterConstants.NUM_USERS * this.getWorkloadConfiguration().getScaleFactor()); + + TweetHistogram tweet_h = new TweetHistogram(); + this.tweet_len_rng = new FlatHistogram<>(this.rng(), tweet_h); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + TwitterOperation t = generator.nextTransaction(); + // zero is an invalid id, so fixing random here to be atleast 1 + t.uid = this.rng().nextInt(this.num_users - 1) + 1; + + if (nextTrans.getProcedureClass().equals(GetTweet.class)) { + doSelect1Tweet(conn, t.tweetid); + } else if (nextTrans.getProcedureClass().equals(GetTweetsFromFollowing.class)) { + doSelectTweetsFromPplIFollow(conn, t.uid); + } else if (nextTrans.getProcedureClass().equals(GetFollowers.class)) { + doSelectNamesOfPplThatFollowMe(conn, t.uid); + } else if (nextTrans.getProcedureClass().equals(GetUserTweets.class)) { + doSelectTweetsForUid(conn, t.uid); + } else if (nextTrans.getProcedureClass().equals(InsertTweet.class)) { + int len = this.tweet_len_rng.nextValue(); + String text = TextGenerator.randomStr(this.rng(), len); + doInsertTweet(conn, t.uid, text); } + return (TransactionStatus.SUCCESS); + } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - TwitterOperation t = generator.nextTransaction(); - // zero is an invalid id, so fixing random here to be atleast 1 - t.uid = this.rng().nextInt(this.num_users - 1 ) + 1; - - if (nextTrans.getProcedureClass().equals(GetTweet.class)) { - doSelect1Tweet(conn, t.tweetid); - } else if (nextTrans.getProcedureClass().equals(GetTweetsFromFollowing.class)) { - doSelectTweetsFromPplIFollow(conn, t.uid); - } else if (nextTrans.getProcedureClass().equals(GetFollowers.class)) { - doSelectNamesOfPplThatFollowMe(conn, t.uid); - } else if (nextTrans.getProcedureClass().equals(GetUserTweets.class)) { - doSelectTweetsForUid(conn, t.uid); - } else if (nextTrans.getProcedureClass().equals(InsertTweet.class)) { - int len = this.tweet_len_rng.nextValue(); - String text = TextGenerator.randomStr(this.rng(), len); - doInsertTweet(conn, t.uid, text); - } - return (TransactionStatus.SUCCESS); - } + public void doSelect1Tweet(Connection conn, int tweet_id) throws SQLException { + GetTweet proc = this.getProcedure(GetTweet.class); - public void doSelect1Tweet(Connection conn, int tweet_id) throws SQLException { - GetTweet proc = this.getProcedure(GetTweet.class); + proc.run(conn, tweet_id); + } - proc.run(conn, tweet_id); - } + public void doSelectTweetsFromPplIFollow(Connection conn, int uid) throws SQLException { + GetTweetsFromFollowing proc = this.getProcedure(GetTweetsFromFollowing.class); - public void doSelectTweetsFromPplIFollow(Connection conn, int uid) throws SQLException { - GetTweetsFromFollowing proc = this.getProcedure(GetTweetsFromFollowing.class); + proc.run(conn, uid); + } - proc.run(conn, uid); - } - - public void doSelectNamesOfPplThatFollowMe(Connection conn, int uid) throws SQLException { - GetFollowers proc = this.getProcedure(GetFollowers.class); - - proc.run(conn, uid); - } + public void doSelectNamesOfPplThatFollowMe(Connection conn, int uid) throws SQLException { + GetFollowers proc = this.getProcedure(GetFollowers.class); - public void doSelectTweetsForUid(Connection conn, int uid) throws SQLException { - GetUserTweets proc = this.getProcedure(GetUserTweets.class); + proc.run(conn, uid); + } - proc.run(conn, uid); - } + public void doSelectTweetsForUid(Connection conn, int uid) throws SQLException { + GetUserTweets proc = this.getProcedure(GetUserTweets.class); - public void doInsertTweet(Connection conn, int uid, String text) throws SQLException { - InsertTweet proc = this.getProcedure(InsertTweet.class); + proc.run(conn, uid); + } - Time time = new Time(System.currentTimeMillis()); - proc.run(conn, uid, text, time); + public void doInsertTweet(Connection conn, int uid, String text) throws SQLException { + InsertTweet proc = this.getProcedure(InsertTweet.class); - } + Time time = new Time(System.currentTimeMillis()); + proc.run(conn, uid, text, time); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java index 93fad32ab..16d187ffe 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetFollowers.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.twitter.TwitterConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,37 +27,43 @@ public class GetFollowers extends Procedure { - public final SQLStmt getFollowers = new SQLStmt("SELECT f2 FROM " + TwitterConstants.TABLENAME_FOLLOWERS + " WHERE f1 = ? LIMIT " + TwitterConstants.LIMIT_FOLLOWERS); + public final SQLStmt getFollowers = + new SQLStmt( + "SELECT f2 FROM " + + TwitterConstants.TABLENAME_FOLLOWERS + + " WHERE f1 = ? LIMIT " + + TwitterConstants.LIMIT_FOLLOWERS); - /** - * NOTE: The ?? is substituted into a string of repeated ?'s - */ - public final SQLStmt getFollowerNames = new SQLStmt("SELECT uid, name FROM " + TwitterConstants.TABLENAME_USER + " WHERE uid IN (??)", TwitterConstants.LIMIT_FOLLOWERS); + /** NOTE: The ?? is substituted into a string of repeated ?'s */ + public final SQLStmt getFollowerNames = + new SQLStmt( + "SELECT uid, name FROM " + TwitterConstants.TABLENAME_USER + " WHERE uid IN (??)", + TwitterConstants.LIMIT_FOLLOWERS); - public void run(Connection conn, long uid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getFollowers)) { - stmt.setLong(1, uid); - try (ResultSet rs = stmt.executeQuery()) { + public void run(Connection conn, long uid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getFollowers)) { + stmt.setLong(1, uid); + try (ResultSet rs = stmt.executeQuery()) { - try (PreparedStatement getFollowerNamesstmt = this.getPreparedStatement(conn, getFollowerNames)) { - int ctr = 0; - long last = -1; - while (rs.next() && ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { - last = rs.getLong(1); - getFollowerNamesstmt.setLong(ctr, last); - } - if (ctr > 0) { - while (ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { - getFollowerNamesstmt.setLong(ctr, last); - } - try (ResultSet getFollowerNamesrs = getFollowerNamesstmt.executeQuery()) { - assert getFollowerNamesrs != null; - } - } - } + try (PreparedStatement getFollowerNamesstmt = + this.getPreparedStatement(conn, getFollowerNames)) { + int ctr = 0; + long last = -1; + while (rs.next() && ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { + last = rs.getLong(1); + getFollowerNamesstmt.setLong(ctr, last); + } + if (ctr > 0) { + while (ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { + getFollowerNamesstmt.setLong(ctr, last); + } + try (ResultSet getFollowerNamesrs = getFollowerNamesstmt.executeQuery()) { + assert getFollowerNamesrs != null; } + } } - // LOG.warn("No followers for user : "+uid); //... so what ? + } } - + // LOG.warn("No followers for user : "+uid); //... so what ? + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java index ae72db178..f979601e0 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweet.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.twitter.TwitterConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,16 +27,15 @@ public class GetTweet extends Procedure { - public SQLStmt getTweet = new SQLStmt( - "SELECT * FROM " + TwitterConstants.TABLENAME_TWEETS + " WHERE id = ?" - ); + public SQLStmt getTweet = + new SQLStmt("SELECT * FROM " + TwitterConstants.TABLENAME_TWEETS + " WHERE id = ?"); - public void run(Connection conn, long tweet_id) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweet)) { - stmt.setLong(1, tweet_id); - try (ResultSet rs = stmt.executeQuery()) { - assert rs != null; - } - } + public void run(Connection conn, long tweet_id) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweet)) { + stmt.setLong(1, tweet_id); + try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java index c726ab571..73ce2dea1 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetTweetsFromFollowing.java @@ -15,13 +15,11 @@ * */ - package com.oltpbenchmark.benchmarks.twitter.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.twitter.TwitterConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -29,39 +27,43 @@ public class GetTweetsFromFollowing extends Procedure { - public final SQLStmt getFollowing = new SQLStmt("SELECT f2 FROM " + TwitterConstants.TABLENAME_FOLLOWS + " WHERE f1 = ? LIMIT " + TwitterConstants.LIMIT_FOLLOWERS); - - /** - * NOTE: The ?? is substituted into a string of repeated ?'s - */ - public final SQLStmt getTweets = new SQLStmt("SELECT * FROM " + TwitterConstants.TABLENAME_TWEETS + " WHERE uid IN (??)", TwitterConstants.LIMIT_FOLLOWERS); + public final SQLStmt getFollowing = + new SQLStmt( + "SELECT f2 FROM " + + TwitterConstants.TABLENAME_FOLLOWS + + " WHERE f1 = ? LIMIT " + + TwitterConstants.LIMIT_FOLLOWERS); - public void run(Connection conn, int uid) throws SQLException { - try (PreparedStatement getFollowingStatement = this.getPreparedStatement(conn, getFollowing)) { - getFollowingStatement.setLong(1, uid); - try (ResultSet followingResult = getFollowingStatement.executeQuery()) { + /** NOTE: The ?? is substituted into a string of repeated ?'s */ + public final SQLStmt getTweets = + new SQLStmt( + "SELECT * FROM " + TwitterConstants.TABLENAME_TWEETS + " WHERE uid IN (??)", + TwitterConstants.LIMIT_FOLLOWERS); - try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweets)) { - int ctr = 0; - long last = -1; - while (followingResult.next() && ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { - last = followingResult.getLong(1); - stmt.setLong(ctr, last); + public void run(Connection conn, int uid) throws SQLException { + try (PreparedStatement getFollowingStatement = this.getPreparedStatement(conn, getFollowing)) { + getFollowingStatement.setLong(1, uid); + try (ResultSet followingResult = getFollowingStatement.executeQuery()) { - } - if (ctr > 0) { - while (ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { - stmt.setLong(ctr, last); - } - try (ResultSet getTweetsResult = stmt.executeQuery()) { - assert getTweetsResult != null; - } - } else { - // LOG.debug("No followers for user: "+uid); // so what .. ? - } - } + try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweets)) { + int ctr = 0; + long last = -1; + while (followingResult.next() && ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { + last = followingResult.getLong(1); + stmt.setLong(ctr, last); + } + if (ctr > 0) { + while (ctr++ < TwitterConstants.LIMIT_FOLLOWERS) { + stmt.setLong(ctr, last); } + try (ResultSet getTweetsResult = stmt.executeQuery()) { + assert getTweetsResult != null; + } + } else { + // LOG.debug("No followers for user: "+uid); // so what .. ? + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java index cd5e633c2..afbc8cc1a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/GetUserTweets.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.twitter.TwitterConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -28,14 +27,19 @@ public class GetUserTweets extends Procedure { - public final SQLStmt getTweets = new SQLStmt("SELECT * FROM " + TwitterConstants.TABLENAME_TWEETS + " WHERE uid = ? LIMIT " + TwitterConstants.LIMIT_TWEETS_FOR_UID); + public final SQLStmt getTweets = + new SQLStmt( + "SELECT * FROM " + + TwitterConstants.TABLENAME_TWEETS + + " WHERE uid = ? LIMIT " + + TwitterConstants.LIMIT_TWEETS_FOR_UID); - public void run(Connection conn, long uid) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweets)) { - stmt.setLong(1, uid); - try (ResultSet rs = stmt.executeQuery()) { - assert rs != null; - } - } + public void run(Connection conn, long uid) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, getTweets)) { + stmt.setLong(1, uid); + try (ResultSet rs = stmt.executeQuery()) { + assert rs != null; + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/InsertTweet.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/InsertTweet.java index 96a1797a5..68410d838 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/InsertTweet.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/procedures/InsertTweet.java @@ -20,7 +20,6 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.twitter.TwitterConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -28,15 +27,20 @@ public class InsertTweet extends Procedure { - //FIXME: Carlo is this correct? 1) added_tweets is empty initially 2) id is supposed to be not null - public final SQLStmt insertTweet = new SQLStmt("INSERT INTO " + TwitterConstants.TABLENAME_ADDED_TWEETS + " (uid,text,createdate) VALUES (?, ?, ?)"); + // FIXME: Carlo is this correct? 1) added_tweets is empty initially 2) id is supposed to be not + // null + public final SQLStmt insertTweet = + new SQLStmt( + "INSERT INTO " + + TwitterConstants.TABLENAME_ADDED_TWEETS + + " (uid,text,createdate) VALUES (?, ?, ?)"); - public boolean run(Connection conn, long uid, String text, Time time) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, insertTweet)) { - stmt.setLong(1, uid); - stmt.setString(2, text); - stmt.setDate(3, new java.sql.Date(System.currentTimeMillis())); - return (stmt.execute()); - } + public boolean run(Connection conn, long uid, String text, Time time) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, insertTweet)) { + stmt.setLong(1, uid); + stmt.setString(2, text); + stmt.setDate(3, new java.sql.Date(System.currentTimeMillis())); + return (stmt.execute()); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/NameHistogram.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/NameHistogram.java index ddeb3cedb..e026fad32 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/NameHistogram.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/NameHistogram.java @@ -26,24 +26,23 @@ * @author pavlo */ public final class NameHistogram extends Histogram { - private static final long serialVersionUID = 0L; - - { - this.put(1, 2); - this.put(2, 12); - this.put(3, 209); - this.put(4, 2027); - this.put(5, 7987); - this.put(6, 22236); - this.put(7, 38682); - this.put(8, 54809); - this.put(9, 65614); - this.put(10, 70547); - this.put(11, 69153); - this.put(12, 63777); - this.put(13, 56049); - this.put(14, 47905); - this.put(15, 48166); - } + private static final long serialVersionUID = 0L; + { + this.put(1, 2); + this.put(2, 12); + this.put(3, 209); + this.put(4, 2027); + this.put(5, 7987); + this.put(6, 22236); + this.put(7, 38682); + this.put(8, 54809); + this.put(9, 65614); + this.put(10, 70547); + this.put(11, 69153); + this.put(12, 63777); + this.put(13, 56049); + this.put(14, 47905); + this.put(15, 48166); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TraceTransactionGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TraceTransactionGenerator.java index 7727ecd04..39736f448 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TraceTransactionGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TraceTransactionGenerator.java @@ -15,33 +15,31 @@ * */ - package com.oltpbenchmark.benchmarks.twitter.util; import com.oltpbenchmark.api.TransactionGenerator; import com.oltpbenchmark.distributions.CounterGenerator; - import java.util.List; public class TraceTransactionGenerator implements TransactionGenerator { - private static CounterGenerator nextInTrace; - private final List transactions; + private static CounterGenerator nextInTrace; + private final List transactions; - /** - * @param transactions a list of transactions shared between threads. - */ - public TraceTransactionGenerator(List transactions) { - this.transactions = transactions; - nextInTrace = new CounterGenerator(transactions.size()); - } + /** + * @param transactions a list of transactions shared between threads. + */ + public TraceTransactionGenerator(List transactions) { + this.transactions = transactions; + nextInTrace = new CounterGenerator(transactions.size()); + } - @Override - public TwitterOperation nextTransaction() { - try { - return transactions.get(nextInTrace.nextInt()); - } catch (IndexOutOfBoundsException id) { - nextInTrace.reset(); - return transactions.get(nextInTrace.nextInt()); - } + @Override + public TwitterOperation nextTransaction() { + try { + return transactions.get(nextInTrace.nextInt()); + } catch (IndexOutOfBoundsException id) { + nextInTrace.reset(); + return transactions.get(nextInTrace.nextInt()); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TweetHistogram.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TweetHistogram.java index 7740c30c7..618cdb4bd 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TweetHistogram.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TweetHistogram.java @@ -22,152 +22,151 @@ /** * A histogram of tweet length. This is derived from * http://simplymeasured.com/blog/2010/06/lakers-vs-celtics-social-media-breakdown-nba/ - *

- * And seems to match the distribution shown in: + * + *

And seems to match the distribution shown in: * http://blog.hubspot.com/Portals/249/sotwitter09.pdf * * @author pavlo */ public final class TweetHistogram extends Histogram { - private static final long serialVersionUID = 0L; - - { - this.put(4, 2); - this.put(6, 610); - this.put(7, 2253); - this.put(8, 1488); - this.put(9, 1656); - this.put(10, 2837); - this.put(11, 3040); - this.put(12, 2865); - this.put(13, 2850); - this.put(14, 3372); - this.put(15, 4639); - this.put(16, 5023); - this.put(17, 4787); - this.put(18, 4669); - this.put(19, 4703); - this.put(20, 4470); - this.put(21, 4417); - this.put(22, 4307); - this.put(23, 4484); - this.put(24, 4636); - this.put(25, 4691); - this.put(26, 4865); - this.put(27, 5181); - this.put(28, 5122); - this.put(29, 5043); - this.put(30, 5143); - this.put(31, 5165); - this.put(32, 5362); - this.put(33, 5342); - this.put(34, 5255); - this.put(35, 5499); - this.put(36, 5336); - this.put(37, 5164); - this.put(38, 5445); - this.put(39, 5220); - this.put(40, 5114); - this.put(41, 5144); - this.put(42, 5120); - this.put(43, 5007); - this.put(44, 5256); - this.put(45, 5158); - this.put(46, 5314); - this.put(47, 5085); - this.put(48, 5288); - this.put(49, 5095); - this.put(50, 5113); - this.put(51, 4954); - this.put(52, 4932); - this.put(53, 5024); - this.put(54, 4779); - this.put(55, 5169); - this.put(56, 4742); - this.put(57, 4916); - this.put(58, 5180); - this.put(59, 4791); - this.put(60, 4552); - this.put(61, 4548); - this.put(62, 4547); - this.put(63, 4536); - this.put(64, 4557); - this.put(65, 4407); - this.put(66, 4350); - this.put(67, 4217); - this.put(68, 4443); - this.put(69, 4145); - this.put(70, 4211); - this.put(71, 4148); - this.put(72, 3980); - this.put(73, 4079); - this.put(74, 3956); - this.put(75, 4151); - this.put(76, 3920); - this.put(77, 3655); - this.put(78, 3655); - this.put(79, 3887); - this.put(80, 3777); - this.put(81, 3551); - this.put(82, 3693); - this.put(83, 3622); - this.put(84, 3470); - this.put(85, 3610); - this.put(86, 4867); - this.put(87, 4690); - this.put(88, 3344); - this.put(89, 3278); - this.put(90, 3303); - this.put(91, 3260); - this.put(92, 3117); - this.put(93, 3129); - this.put(94, 3148); - this.put(95, 3037); - this.put(96, 3087); - this.put(97, 2976); - this.put(98, 2970); - this.put(99, 2874); - this.put(100, 2879); - this.put(101, 2991); - this.put(102, 2832); - this.put(103, 2706); - this.put(104, 2684); - this.put(105, 2870); - this.put(106, 2749); - this.put(107, 2639); - this.put(108, 2496); - this.put(109, 2585); - this.put(110, 2640); - this.put(111, 2787); - this.put(112, 2602); - this.put(113, 2497); - this.put(114, 2495); - this.put(115, 2586); - this.put(116, 2523); - this.put(117, 2641); - this.put(118, 2574); - this.put(119, 2833); - this.put(120, 2321); - this.put(121, 2261); - this.put(122, 2429); - this.put(123, 2440); - this.put(124, 2419); - this.put(125, 2367); - this.put(126, 2536); - this.put(127, 2588); - this.put(128, 2602); - this.put(129, 2628); - this.put(130, 2750); - this.put(131, 2778); - this.put(132, 2741); - this.put(133, 2973); - this.put(134, 3545); - this.put(135, 4364); - this.put(136, 4371); - this.put(137, 4436); - this.put(138, 6212); - this.put(139, 6919); - this.put(140, 15701); - } + private static final long serialVersionUID = 0L; + { + this.put(4, 2); + this.put(6, 610); + this.put(7, 2253); + this.put(8, 1488); + this.put(9, 1656); + this.put(10, 2837); + this.put(11, 3040); + this.put(12, 2865); + this.put(13, 2850); + this.put(14, 3372); + this.put(15, 4639); + this.put(16, 5023); + this.put(17, 4787); + this.put(18, 4669); + this.put(19, 4703); + this.put(20, 4470); + this.put(21, 4417); + this.put(22, 4307); + this.put(23, 4484); + this.put(24, 4636); + this.put(25, 4691); + this.put(26, 4865); + this.put(27, 5181); + this.put(28, 5122); + this.put(29, 5043); + this.put(30, 5143); + this.put(31, 5165); + this.put(32, 5362); + this.put(33, 5342); + this.put(34, 5255); + this.put(35, 5499); + this.put(36, 5336); + this.put(37, 5164); + this.put(38, 5445); + this.put(39, 5220); + this.put(40, 5114); + this.put(41, 5144); + this.put(42, 5120); + this.put(43, 5007); + this.put(44, 5256); + this.put(45, 5158); + this.put(46, 5314); + this.put(47, 5085); + this.put(48, 5288); + this.put(49, 5095); + this.put(50, 5113); + this.put(51, 4954); + this.put(52, 4932); + this.put(53, 5024); + this.put(54, 4779); + this.put(55, 5169); + this.put(56, 4742); + this.put(57, 4916); + this.put(58, 5180); + this.put(59, 4791); + this.put(60, 4552); + this.put(61, 4548); + this.put(62, 4547); + this.put(63, 4536); + this.put(64, 4557); + this.put(65, 4407); + this.put(66, 4350); + this.put(67, 4217); + this.put(68, 4443); + this.put(69, 4145); + this.put(70, 4211); + this.put(71, 4148); + this.put(72, 3980); + this.put(73, 4079); + this.put(74, 3956); + this.put(75, 4151); + this.put(76, 3920); + this.put(77, 3655); + this.put(78, 3655); + this.put(79, 3887); + this.put(80, 3777); + this.put(81, 3551); + this.put(82, 3693); + this.put(83, 3622); + this.put(84, 3470); + this.put(85, 3610); + this.put(86, 4867); + this.put(87, 4690); + this.put(88, 3344); + this.put(89, 3278); + this.put(90, 3303); + this.put(91, 3260); + this.put(92, 3117); + this.put(93, 3129); + this.put(94, 3148); + this.put(95, 3037); + this.put(96, 3087); + this.put(97, 2976); + this.put(98, 2970); + this.put(99, 2874); + this.put(100, 2879); + this.put(101, 2991); + this.put(102, 2832); + this.put(103, 2706); + this.put(104, 2684); + this.put(105, 2870); + this.put(106, 2749); + this.put(107, 2639); + this.put(108, 2496); + this.put(109, 2585); + this.put(110, 2640); + this.put(111, 2787); + this.put(112, 2602); + this.put(113, 2497); + this.put(114, 2495); + this.put(115, 2586); + this.put(116, 2523); + this.put(117, 2641); + this.put(118, 2574); + this.put(119, 2833); + this.put(120, 2321); + this.put(121, 2261); + this.put(122, 2429); + this.put(123, 2440); + this.put(124, 2419); + this.put(125, 2367); + this.put(126, 2536); + this.put(127, 2588); + this.put(128, 2602); + this.put(129, 2628); + this.put(130, 2750); + this.put(131, 2778); + this.put(132, 2741); + this.put(133, 2973); + this.put(134, 3545); + this.put(135, 4364); + this.put(136, 4371); + this.put(137, 4436); + this.put(138, 6212); + this.put(139, 6919); + this.put(140, 15701); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TwitterOperation.java b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TwitterOperation.java index b6bd6bc6c..7e6c3679c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TwitterOperation.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/twitter/util/TwitterOperation.java @@ -15,24 +15,19 @@ * */ - package com.oltpbenchmark.benchmarks.twitter.util; import com.oltpbenchmark.api.Operation; -/** - * Immutable class containing information about transactions. - */ +/** Immutable class containing information about transactions. */ public final class TwitterOperation extends Operation { - public final int tweetid; - public int uid; - - public TwitterOperation(int tweetid, int uid) { - super(); - this.tweetid = tweetid; - this.uid = uid; - } - + public final int tweetid; + public int uid; + public TwitterOperation(int tweetid, int uid) { + super(); + this.tweetid = tweetid; + this.uid = uid; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterBenchmark.java index 521caa0d5..a2abca3b9 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterBenchmark.java @@ -22,41 +22,40 @@ import com.oltpbenchmark.api.Loader; import com.oltpbenchmark.api.Worker; import com.oltpbenchmark.benchmarks.voter.procedures.Vote; - import java.util.ArrayList; import java.util.List; public final class VoterBenchmark extends BenchmarkModule { - public final int numContestants; - - public VoterBenchmark(WorkloadConfiguration workConf) { - super(workConf); + public final int numContestants; - int contestants = Math.max(1, (int) Math.round(VoterConstants.NUM_CONTESTANTS * workConf.getScaleFactor())); - if (contestants > VoterConstants.CONTESTANT_NAMES.length) { - contestants = VoterConstants.CONTESTANT_NAMES.length; - } - this.numContestants = contestants; - } + public VoterBenchmark(WorkloadConfiguration workConf) { + super(workConf); - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new VoterWorker(this, i)); - } - return workers; + int contestants = + Math.max(1, (int) Math.round(VoterConstants.NUM_CONTESTANTS * workConf.getScaleFactor())); + if (contestants > VoterConstants.CONTESTANT_NAMES.length) { + contestants = VoterConstants.CONTESTANT_NAMES.length; } - - @Override - protected Loader makeLoaderImpl() { - return new VoterLoader(this); + this.numContestants = contestants; + } + + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new VoterWorker(this, i)); } - - @Override - protected Package getProcedurePackageImpl() { - return Vote.class.getPackage(); - } - + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new VoterLoader(this); + } + + @Override + protected Package getProcedurePackageImpl() { + return Vote.class.getPackage(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterConstants.java index 6cee8deb9..0b39e0d6d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterConstants.java @@ -15,74 +15,78 @@ * */ - package com.oltpbenchmark.benchmarks.voter; public abstract class VoterConstants { - public static final int MAX_VOTES = 1000; - public static final int NUM_CONTESTANTS = 6; + public static final int MAX_VOTES = 1000; + public static final int NUM_CONTESTANTS = 6; - public static final String TABLENAME_CONTESTANTS = "contestants"; - public static final String TABLENAME_VOTES = "votes"; - public static final String TABLENAME_LOCATIONS = "area_code_state"; + public static final String TABLENAME_CONTESTANTS = "contestants"; + public static final String TABLENAME_VOTES = "votes"; + public static final String TABLENAME_LOCATIONS = "area_code_state"; - // Initialize some common constants and variables - public static final String[] CONTESTANT_NAMES = new String[]{ - "Edwina Burnam", - "Tabatha Gehling", - "Kelly Clauss", - "Jessie Alloway", - "Alana Bregman", - "Jessie Eichman", - "Allie Rogalski", - "Nita Coster", - "Kurt Walser", - "Ericka Dieter", - "Loraine Nygren", - "Tania Mattioli" - }; + // Initialize some common constants and variables + public static final String[] CONTESTANT_NAMES = + new String[] { + "Edwina Burnam", + "Tabatha Gehling", + "Kelly Clauss", + "Jessie Alloway", + "Alana Bregman", + "Jessie Eichman", + "Allie Rogalski", + "Nita Coster", + "Kurt Walser", + "Ericka Dieter", + "Loraine Nygren", + "Tania Mattioli" + }; - // Domain data: matching lists of Area codes and States - public static final short[] AREA_CODES = new short[]{ - 907, 205, 256, 334, 251, 870, 501, 479, 480, 602, 623, 928, 520, 341, 764, 628, 831, 925, - 909, 562, 661, 510, 650, 949, 760, 415, 951, 209, 669, 408, 559, 626, 442, 530, 916, 627, - 714, 707, 310, 323, 213, 424, 747, 818, 858, 935, 619, 805, 369, 720, 303, 970, 719, 860, - 203, 959, 475, 202, 302, 689, 407, 239, 850, 727, 321, 754, 954, 927, 352, 863, 386, 904, - 561, 772, 786, 305, 941, 813, 478, 770, 470, 404, 762, 706, 678, 912, 229, 808, 515, 319, - 563, 641, 712, 208, 217, 872, 312, 773, 464, 708, 224, 847, 779, 815, 618, 309, 331, 630, - 317, 765, 574, 260, 219, 812, 913, 785, 316, 620, 606, 859, 502, 270, 504, 985, 225, 318, - 337, 774, 508, 339, 781, 857, 617, 978, 351, 413, 443, 410, 301, 240, 207, 517, 810, 278, - 679, 313, 586, 947, 248, 734, 269, 989, 906, 616, 231, 612, 320, 651, 763, 952, 218, 507, - 636, 660, 975, 816, 573, 314, 557, 417, 769, 601, 662, 228, 406, 336, 252, 984, 919, 980, - 910, 828, 704, 701, 402, 308, 603, 908, 848, 732, 551, 201, 862, 973, 609, 856, 575, 957, - 505, 775, 702, 315, 518, 646, 347, 212, 718, 516, 917, 845, 631, 716, 585, 607, 914, 216, - 330, 234, 567, 419, 440, 380, 740, 614, 283, 513, 937, 918, 580, 405, 503, 541, 971, 814, - 717, 570, 878, 835, 484, 610, 267, 215, 724, 412, 401, 843, 864, 803, 605, 423, 865, 931, - 615, 901, 731, 254, 325, 713, 940, 817, 430, 903, 806, 737, 512, 361, 210, 979, 936, 409, - 972, 469, 214, 682, 832, 281, 830, 956, 432, 915, 435, 801, 385, 434, 804, 757, 703, 571, - 276, 236, 540, 802, 509, 360, 564, 206, 425, 253, 715, 920, 262, 414, 608, 304, 307}; + // Domain data: matching lists of Area codes and States + public static final short[] AREA_CODES = + new short[] { + 907, 205, 256, 334, 251, 870, 501, 479, 480, 602, 623, 928, 520, 341, 764, 628, 831, 925, + 909, 562, 661, 510, 650, 949, 760, 415, 951, 209, 669, 408, 559, 626, 442, 530, 916, 627, + 714, 707, 310, 323, 213, 424, 747, 818, 858, 935, 619, 805, 369, 720, 303, 970, 719, 860, + 203, 959, 475, 202, 302, 689, 407, 239, 850, 727, 321, 754, 954, 927, 352, 863, 386, 904, + 561, 772, 786, 305, 941, 813, 478, 770, 470, 404, 762, 706, 678, 912, 229, 808, 515, 319, + 563, 641, 712, 208, 217, 872, 312, 773, 464, 708, 224, 847, 779, 815, 618, 309, 331, 630, + 317, 765, 574, 260, 219, 812, 913, 785, 316, 620, 606, 859, 502, 270, 504, 985, 225, 318, + 337, 774, 508, 339, 781, 857, 617, 978, 351, 413, 443, 410, 301, 240, 207, 517, 810, 278, + 679, 313, 586, 947, 248, 734, 269, 989, 906, 616, 231, 612, 320, 651, 763, 952, 218, 507, + 636, 660, 975, 816, 573, 314, 557, 417, 769, 601, 662, 228, 406, 336, 252, 984, 919, 980, + 910, 828, 704, 701, 402, 308, 603, 908, 848, 732, 551, 201, 862, 973, 609, 856, 575, 957, + 505, 775, 702, 315, 518, 646, 347, 212, 718, 516, 917, 845, 631, 716, 585, 607, 914, 216, + 330, 234, 567, 419, 440, 380, 740, 614, 283, 513, 937, 918, 580, 405, 503, 541, 971, 814, + 717, 570, 878, 835, 484, 610, 267, 215, 724, 412, 401, 843, 864, 803, 605, 423, 865, 931, + 615, 901, 731, 254, 325, 713, 940, 817, 430, 903, 806, 737, 512, 361, 210, 979, 936, 409, + 972, 469, 214, 682, 832, 281, 830, 956, 432, 915, 435, 801, 385, 434, 804, 757, 703, 571, + 276, 236, 540, 802, 509, 360, 564, 206, 425, 253, 715, 920, 262, 414, 608, 304, 307 + }; - public static final String[] STATE_CODES = new String[]{ - "AK", "AL", "AL", "AL", "AL", "AR", "AR", "AR", "AZ", "AZ", "AZ", "AZ", "AZ", "CA", "CA", - "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", - "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", - "CA", "CA", "CA", "CA", "CO", "CO", "CO", "CO", "CT", "CT", "CT", "CT", "DC", "DE", "FL", - "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", - "FL", "FL", "FL", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "HI", "IA", "IA", - "IA", "IA", "IA", "ID", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", - "IL", "IL", "IL", "IN", "IN", "IN", "IN", "IN", "IN", "KS", "KS", "KS", "KS", "KY", "KY", - "KY", "KY", "LA", "LA", "LA", "LA", "LA", "MA", "MA", "MA", "MA", "MA", "MA", "MA", "MA", - "MA", "MD", "MD", "MD", "MD", "ME", "MI", "MI", "MI", "MI", "MI", "MI", "MI", "MI", "MI", - "MI", "MI", "MI", "MI", "MI", "MN", "MN", "MN", "MN", "MN", "MN", "MN", "MO", "MO", "MO", - "MO", "MO", "MO", "MO", "MO", "MS", "MS", "MS", "MS", "MT", "NC", "NC", "NC", "NC", "NC", - "NC", "NC", "NC", "ND", "NE", "NE", "NH", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", - "NJ", "NM", "NM", "NM", "NV", "NV", "NY", "NY", "NY", "NY", "NY", "NY", "NY", "NY", "NY", - "NY", "NY", "NY", "NY", "NY", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", - "OH", "OH", "OK", "OK", "OK", "OR", "OR", "OR", "PA", "PA", "PA", "PA", "PA", "PA", "PA", - "PA", "PA", "PA", "PA", "RI", "SC", "SC", "SC", "SD", "TN", "TN", "TN", "TN", "TN", "TN", - "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", - "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "UT", "UT", "UT", "VA", "VA", - "VA", "VA", "VA", "VA", "VA", "VA", "VT", "WA", "WA", "WA", "WA", "WA", "WA", "WI", "WI", - "WI", "WI", "WI", "WV", "WY"}; + public static final String[] STATE_CODES = + new String[] { + "AK", "AL", "AL", "AL", "AL", "AR", "AR", "AR", "AZ", "AZ", "AZ", "AZ", "AZ", "CA", "CA", + "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", + "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", "CA", + "CA", "CA", "CA", "CA", "CO", "CO", "CO", "CO", "CT", "CT", "CT", "CT", "DC", "DE", "FL", + "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", "FL", + "FL", "FL", "FL", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "GA", "HI", "IA", "IA", + "IA", "IA", "IA", "ID", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", "IL", + "IL", "IL", "IL", "IN", "IN", "IN", "IN", "IN", "IN", "KS", "KS", "KS", "KS", "KY", "KY", + "KY", "KY", "LA", "LA", "LA", "LA", "LA", "MA", "MA", "MA", "MA", "MA", "MA", "MA", "MA", + "MA", "MD", "MD", "MD", "MD", "ME", "MI", "MI", "MI", "MI", "MI", "MI", "MI", "MI", "MI", + "MI", "MI", "MI", "MI", "MI", "MN", "MN", "MN", "MN", "MN", "MN", "MN", "MO", "MO", "MO", + "MO", "MO", "MO", "MO", "MO", "MS", "MS", "MS", "MS", "MT", "NC", "NC", "NC", "NC", "NC", + "NC", "NC", "NC", "ND", "NE", "NE", "NH", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", "NJ", + "NJ", "NM", "NM", "NM", "NV", "NV", "NY", "NY", "NY", "NY", "NY", "NY", "NY", "NY", "NY", + "NY", "NY", "NY", "NY", "NY", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", "OH", + "OH", "OH", "OK", "OK", "OK", "OR", "OR", "OR", "PA", "PA", "PA", "PA", "PA", "PA", "PA", + "PA", "PA", "PA", "PA", "RI", "SC", "SC", "SC", "SD", "TN", "TN", "TN", "TN", "TN", "TN", + "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", + "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "TX", "UT", "UT", "UT", "VA", "VA", + "VA", "VA", "VA", "VA", "VA", "VA", "VT", "WA", "WA", "WA", "WA", "WA", "WA", "WI", "WI", + "WI", "WI", "WI", "WV", "WY" + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterLoader.java index f5d486f27..115c5e24d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterLoader.java @@ -21,7 +21,6 @@ import com.oltpbenchmark.api.LoaderThread; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -30,56 +29,60 @@ public final class VoterLoader extends Loader { - public VoterLoader(VoterBenchmark benchmark) { - super(benchmark); - } + public VoterLoader(VoterBenchmark benchmark) { + super(benchmark); + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); - // CONTESTANTS - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadContestants(conn); - } + // CONTESTANTS + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadContestants(conn); + } }); - // LOCATIONS - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadLocations(conn); - } + // LOCATIONS + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadLocations(conn); + } }); - return threads; - } + return threads; + } - private void loadContestants(Connection conn) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(VoterConstants.TABLENAME_CONTESTANTS); - try (PreparedStatement ps = conn.prepareStatement(SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()))) { + private void loadContestants(Connection conn) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(VoterConstants.TABLENAME_CONTESTANTS); + try (PreparedStatement ps = + conn.prepareStatement(SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()))) { - for (int i = 0; i < this.benchmark.numContestants; i++) { - ps.setInt(1, i + 1); - ps.setString(2, VoterConstants.CONTESTANT_NAMES[i]); - ps.addBatch(); - } - ps.executeBatch(); - } + for (int i = 0; i < this.benchmark.numContestants; i++) { + ps.setInt(1, i + 1); + ps.setString(2, VoterConstants.CONTESTANT_NAMES[i]); + ps.addBatch(); + } + ps.executeBatch(); } + } - private void loadLocations(Connection conn) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(VoterConstants.TABLENAME_LOCATIONS); - try (PreparedStatement ps = conn.prepareStatement(SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()))) { + private void loadLocations(Connection conn) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(VoterConstants.TABLENAME_LOCATIONS); + try (PreparedStatement ps = + conn.prepareStatement(SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()))) { - for (int i = 0; i < VoterConstants.AREA_CODES.length; i++) { - ps.setShort(1, VoterConstants.AREA_CODES[i]); - ps.setString(2, VoterConstants.STATE_CODES[i]); - ps.addBatch(); - } - ps.executeBatch(); - } + for (int i = 0; i < VoterConstants.AREA_CODES.length; i++) { + ps.setShort(1, VoterConstants.AREA_CODES[i]); + ps.setString(2, VoterConstants.STATE_CODES[i]); + ps.addBatch(); + } + ps.executeBatch(); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterWorker.java index c82a6f90b..21eef6228 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/VoterWorker.java @@ -20,31 +20,30 @@ import com.oltpbenchmark.api.Procedure.UserAbortException; import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.api.Worker; +import com.oltpbenchmark.benchmarks.voter.procedures.Vote; import com.oltpbenchmark.benchmarks.voter.util.PhoneCallGenerator; import com.oltpbenchmark.benchmarks.voter.util.PhoneCallGenerator.PhoneCall; -import com.oltpbenchmark.benchmarks.voter.procedures.Vote; import com.oltpbenchmark.types.TransactionStatus; - import java.sql.Connection; import java.sql.SQLException; public final class VoterWorker extends Worker { - private final PhoneCallGenerator switchboard; - - public VoterWorker(VoterBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - switchboard = new PhoneCallGenerator(rng(),0, benchmarkModule.numContestants); - } + private final PhoneCallGenerator switchboard; - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType txnType) throws UserAbortException, SQLException { + public VoterWorker(VoterBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + switchboard = new PhoneCallGenerator(rng(), 0, benchmarkModule.numContestants); + } - PhoneCall call = switchboard.receive(); - Vote proc = getProcedure(Vote.class); + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType txnType) + throws UserAbortException, SQLException { - proc.run(conn, call.voteId, call.phoneNumber, call.contestantNumber, VoterConstants.MAX_VOTES); - return TransactionStatus.SUCCESS; - } + PhoneCall call = switchboard.receive(); + Vote proc = getProcedure(Vote.class); + proc.run(conn, call.voteId, call.phoneNumber, call.contestantNumber, VoterConstants.MAX_VOTES); + return TransactionStatus.SUCCESS; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/procedures/Vote.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/procedures/Vote.java index f1d057ca7..c29669db2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/procedures/Vote.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/procedures/Vote.java @@ -46,89 +46,95 @@ package com.oltpbenchmark.benchmarks.voter.procedures; +import static com.oltpbenchmark.benchmarks.voter.VoterConstants.*; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.voter.VoterConstants.*; - public class Vote extends Procedure { - // potential return codes - public static final long VOTE_SUCCESSFUL = 0; - public static final long ERR_INVALID_CONTESTANT = 1; - public static final long ERR_VOTER_OVER_VOTE_LIMIT = 2; - - // Checks if the vote is for a valid contestant - public final SQLStmt checkContestantStmt = new SQLStmt( - "SELECT contestant_number FROM " + TABLENAME_CONTESTANTS + " WHERE contestant_number = ?" - ); - - // Checks if the voter has exceeded their allowed number of votes - public final SQLStmt checkVoterStmt = new SQLStmt( - "SELECT COUNT(*) FROM " + TABLENAME_VOTES + " WHERE phone_number = ?" - ); - - // Checks an area code to retrieve the corresponding state - public final SQLStmt checkStateStmt = new SQLStmt( - "SELECT state FROM " + TABLENAME_LOCATIONS + " WHERE area_code = ?" - ); - - // Records a vote - public final SQLStmt insertVoteStmt = new SQLStmt( - "INSERT INTO " + TABLENAME_VOTES + " (vote_id, phone_number, state, contestant_number, created) " + - "VALUES (?, ?, ?, ?, NOW())" - ); - public long run(Connection conn, long voteId, long phoneNumber, int contestantNumber, long maxVotesPerPhoneNumber) throws SQLException { - - try (PreparedStatement ps = getPreparedStatement(conn, checkContestantStmt)) { - ps.setInt(1, contestantNumber); - try (ResultSet rs = ps.executeQuery()) { - if (!rs.next()) { - return ERR_INVALID_CONTESTANT; - } - } - } - - - try (PreparedStatement ps = getPreparedStatement(conn, checkVoterStmt)) { - ps.setLong(1, phoneNumber); - try (ResultSet rs = ps.executeQuery()) { - boolean hasVoterEnt = rs.next(); - if (hasVoterEnt && rs.getLong(1) >= maxVotesPerPhoneNumber) { - return ERR_VOTER_OVER_VOTE_LIMIT; - } - } + // potential return codes + public static final long VOTE_SUCCESSFUL = 0; + public static final long ERR_INVALID_CONTESTANT = 1; + public static final long ERR_VOTER_OVER_VOTE_LIMIT = 2; + + // Checks if the vote is for a valid contestant + public final SQLStmt checkContestantStmt = + new SQLStmt( + "SELECT contestant_number FROM " + + TABLENAME_CONTESTANTS + + " WHERE contestant_number = ?"); + + // Checks if the voter has exceeded their allowed number of votes + public final SQLStmt checkVoterStmt = + new SQLStmt("SELECT COUNT(*) FROM " + TABLENAME_VOTES + " WHERE phone_number = ?"); + + // Checks an area code to retrieve the corresponding state + public final SQLStmt checkStateStmt = + new SQLStmt("SELECT state FROM " + TABLENAME_LOCATIONS + " WHERE area_code = ?"); + + // Records a vote + public final SQLStmt insertVoteStmt = + new SQLStmt( + "INSERT INTO " + + TABLENAME_VOTES + + " (vote_id, phone_number, state, contestant_number, created) " + + "VALUES (?, ?, ?, ?, NOW())"); + + public long run( + Connection conn, + long voteId, + long phoneNumber, + int contestantNumber, + long maxVotesPerPhoneNumber) + throws SQLException { + + try (PreparedStatement ps = getPreparedStatement(conn, checkContestantStmt)) { + ps.setInt(1, contestantNumber); + try (ResultSet rs = ps.executeQuery()) { + if (!rs.next()) { + return ERR_INVALID_CONTESTANT; } + } + } - - String state = null; - - try (PreparedStatement ps = getPreparedStatement(conn, checkStateStmt)) { - ps.setShort(1, (short) (phoneNumber / 10000000L)); - try (ResultSet rs = ps.executeQuery()) { - // Some sample client libraries use the legacy random phone generation that mostly - // created invalid phone numbers. Until refactoring, re-assign all such votes to - // the "XX" fake state (those votes will not appear on the Live Statistics dashboard, - // but are tracked as legitimate instead of invalid, as old clients would mostly get - // it wrong and see all their transactions rejected). - state = rs.next() ? rs.getString(1) : "XX"; - } + try (PreparedStatement ps = getPreparedStatement(conn, checkVoterStmt)) { + ps.setLong(1, phoneNumber); + try (ResultSet rs = ps.executeQuery()) { + boolean hasVoterEnt = rs.next(); + if (hasVoterEnt && rs.getLong(1) >= maxVotesPerPhoneNumber) { + return ERR_VOTER_OVER_VOTE_LIMIT; } + } + } - try (PreparedStatement ps = getPreparedStatement(conn, insertVoteStmt)) { - ps.setLong(1, voteId); - ps.setLong(2, phoneNumber); - ps.setString(3, state); - ps.setInt(4, contestantNumber); - ps.execute(); - } + String state = null; + + try (PreparedStatement ps = getPreparedStatement(conn, checkStateStmt)) { + ps.setShort(1, (short) (phoneNumber / 10000000L)); + try (ResultSet rs = ps.executeQuery()) { + // Some sample client libraries use the legacy random phone generation that mostly + // created invalid phone numbers. Until refactoring, re-assign all such votes to + // the "XX" fake state (those votes will not appear on the Live Statistics dashboard, + // but are tracked as legitimate instead of invalid, as old clients would mostly get + // it wrong and see all their transactions rejected). + state = rs.next() ? rs.getString(1) : "XX"; + } + } - // Set the return value to 0: successful vote - return VOTE_SUCCESSFUL; + try (PreparedStatement ps = getPreparedStatement(conn, insertVoteStmt)) { + ps.setLong(1, voteId); + ps.setLong(2, phoneNumber); + ps.setString(3, state); + ps.setInt(4, contestantNumber); + ps.execute(); } + + // Set the return value to 0: successful vote + return VOTE_SUCCESSFUL; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/voter/util/PhoneCallGenerator.java b/src/main/java/com/oltpbenchmark/benchmarks/voter/util/PhoneCallGenerator.java index 07823c739..574e72b04 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/voter/util/PhoneCallGenerator.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/voter/util/PhoneCallGenerator.java @@ -18,73 +18,73 @@ package com.oltpbenchmark.benchmarks.voter.util; import com.oltpbenchmark.benchmarks.voter.VoterConstants; - import java.util.Random; public class PhoneCallGenerator { - private final Random rand; - private long nextVoteId; - private final int contestantCount; - private final int[] votingMap = new int[VoterConstants.AREA_CODES.length]; - - public static class PhoneCall { - public final long voteId; - public final int contestantNumber; - public final long phoneNumber; - - protected PhoneCall(long voteId, int contestantNumber, long phoneNumber) { - this.voteId = voteId; - this.contestantNumber = contestantNumber; - this.phoneNumber = phoneNumber; - } - } + private final Random rand; + private long nextVoteId; + private final int contestantCount; + private final int[] votingMap = new int[VoterConstants.AREA_CODES.length]; - public PhoneCallGenerator(Random rng, int clientId, int contestantCount) { - this.rand = rng; - this.nextVoteId = clientId * 10000000L; - this.contestantCount = contestantCount; - - // This is a just a small fudge to make the geographical voting map more interesting for the benchmark! - for (int i = 0; i < votingMap.length; i++) { - votingMap[i] = 1; - if (rand.nextInt(100) >= 30) { - votingMap[i] = (int) (Math.abs(Math.sin(i) * contestantCount) % contestantCount) + 1; - } - } - } + public static class PhoneCall { + public final long voteId; + public final int contestantNumber; + public final long phoneNumber; - /** - * Receives/generates a simulated voting call - * - * @return Call details (calling number and contestant to whom the vote is given) - */ - public PhoneCall receive() { + protected PhoneCall(long voteId, int contestantNumber, long phoneNumber) { + this.voteId = voteId; + this.contestantNumber = contestantNumber; + this.phoneNumber = phoneNumber; + } + } + + public PhoneCallGenerator(Random rng, int clientId, int contestantCount) { + this.rand = rng; + this.nextVoteId = clientId * 10000000L; + this.contestantCount = contestantCount; + + // This is a just a small fudge to make the geographical voting map more interesting for the + // benchmark! + for (int i = 0; i < votingMap.length; i++) { + votingMap[i] = 1; + if (rand.nextInt(100) >= 30) { + votingMap[i] = (int) (Math.abs(Math.sin(i) * contestantCount) % contestantCount) + 1; + } + } + } - // (including invalid votes to demonstrate transaction validating in the database) + /** + * Receives/generates a simulated voting call + * + * @return Call details (calling number and contestant to whom the vote is given) + */ + public PhoneCall receive() { - // Pick a random area code for the originating phone call - int areaCodeIndex = rand.nextInt(VoterConstants.AREA_CODES.length); + // (including invalid votes to demonstrate transaction validating in the database) - // Pick a contestant number - int contestantNumber = votingMap[areaCodeIndex]; - if (rand.nextBoolean()) { - contestantNumber = rand.nextInt(contestantCount) + 1; - } + // Pick a random area code for the originating phone call + int areaCodeIndex = rand.nextInt(VoterConstants.AREA_CODES.length); - // introduce an invalid contestant every 100 call or so to simulate fraud - // and invalid entries (something the transaction validates against) - if (rand.nextInt(100) == 0) { - contestantNumber = 999; - } + // Pick a contestant number + int contestantNumber = votingMap[areaCodeIndex]; + if (rand.nextBoolean()) { + contestantNumber = rand.nextInt(contestantCount) + 1; + } - // Build the phone number - long phoneNumber = VoterConstants.AREA_CODES[areaCodeIndex] * 10000000L + rand.nextInt(10000000); + // introduce an invalid contestant every 100 call or so to simulate fraud + // and invalid entries (something the transaction validates against) + if (rand.nextInt(100) == 0) { + contestantNumber = 999; + } - // This needs to be globally unique + // Build the phone number + long phoneNumber = + VoterConstants.AREA_CODES[areaCodeIndex] * 10000000L + rand.nextInt(10000000); - // Return the generated phone number - return new PhoneCall(this.nextVoteId++, contestantNumber, phoneNumber); - } + // This needs to be globally unique + // Return the generated phone number + return new PhoneCall(this.nextVoteId++, contestantNumber, phoneNumber); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java index bb6c597a3..5c2d0c033 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaBenchmark.java @@ -25,100 +25,105 @@ import com.oltpbenchmark.benchmarks.wikipedia.procedures.AddWatchList; import com.oltpbenchmark.util.RandomDistribution.IntegerFlatHistogram; import com.oltpbenchmark.util.TextGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class WikipediaBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(WikipediaBenchmark.class); + private static final Logger LOG = LoggerFactory.getLogger(WikipediaBenchmark.class); - protected final IntegerFlatHistogram commentLength; - protected final IntegerFlatHistogram minorEdit; - private final IntegerFlatHistogram[] revisionDeltas; + protected final IntegerFlatHistogram commentLength; + protected final IntegerFlatHistogram minorEdit; + private final IntegerFlatHistogram[] revisionDeltas; - protected final int num_users; - protected final int num_pages; + protected final int num_users; + protected final int num_pages; - public WikipediaBenchmark(WorkloadConfiguration workConf) { - super(workConf); + public WikipediaBenchmark(WorkloadConfiguration workConf) { + super(workConf); - this.commentLength = new IntegerFlatHistogram(this.rng(), RevisionHistograms.COMMENT_LENGTH); - this.minorEdit = new IntegerFlatHistogram(this.rng(), RevisionHistograms.MINOR_EDIT); - this.revisionDeltas = new IntegerFlatHistogram[RevisionHistograms.REVISION_DELTA_SIZES.length]; - for (int i = 0; i < this.revisionDeltas.length; i++) { - this.revisionDeltas[i] = new IntegerFlatHistogram(this.rng(), RevisionHistograms.REVISION_DELTAS[i]); - } - - this.num_users = (int) Math.ceil(WikipediaConstants.USERS * this.getWorkloadConfiguration().getScaleFactor()); - this.num_pages = (int) Math.ceil(WikipediaConstants.PAGES * this.getWorkloadConfiguration().getScaleFactor()); + this.commentLength = new IntegerFlatHistogram(this.rng(), RevisionHistograms.COMMENT_LENGTH); + this.minorEdit = new IntegerFlatHistogram(this.rng(), RevisionHistograms.MINOR_EDIT); + this.revisionDeltas = new IntegerFlatHistogram[RevisionHistograms.REVISION_DELTA_SIZES.length]; + for (int i = 0; i < this.revisionDeltas.length; i++) { + this.revisionDeltas[i] = + new IntegerFlatHistogram(this.rng(), RevisionHistograms.REVISION_DELTAS[i]); } - /** - * Special function that takes in a char field that represents the last - * version of the page and then do some permutation on it. This ensures that - * each revision looks somewhat similar to previous one so that we just - * don't have a bunch of random text fields for the same page. - * - * @param orig_text - * @return - */ - protected char[] generateRevisionText(char[] orig_text) { - // Figure out how much we are going to change - // If the delta is greater than the length of the original - // text, then we will just cut our length in half. - // Where is your god now? - // There is probably some sort of minimal size that we should adhere to, - // but it's 12:30am and I simply don't feel like dealing with that now - IntegerFlatHistogram h = null; - for (int i = 0; i < this.revisionDeltas.length - 1; i++) { - if (orig_text.length <= RevisionHistograms.REVISION_DELTA_SIZES[i]) { - h = this.revisionDeltas[i]; - } - } - if (h == null) { - h = this.revisionDeltas[this.revisionDeltas.length - 1]; - } - - - int delta = h.nextValue(); - if (orig_text.length + delta <= 0) { - delta = -1 * (int) Math.round(orig_text.length / 1.5); - if (Math.abs(delta) == orig_text.length && delta < 0) { - delta /= 2; - } - } - if (delta != 0) { - orig_text = TextGenerator.resizeText(this.rng(), orig_text, delta); - } - - // And permute it a little bit. This ensures that the text is slightly - // different than the last revision - orig_text = TextGenerator.permuteText(this.rng(), orig_text); - - return (orig_text); + this.num_users = + (int) + Math.ceil(WikipediaConstants.USERS * this.getWorkloadConfiguration().getScaleFactor()); + this.num_pages = + (int) + Math.ceil(WikipediaConstants.PAGES * this.getWorkloadConfiguration().getScaleFactor()); + } + + /** + * Special function that takes in a char field that represents the last version of the page and + * then do some permutation on it. This ensures that each revision looks somewhat similar to + * previous one so that we just don't have a bunch of random text fields for the same page. + * + * @param orig_text + * @return + */ + protected char[] generateRevisionText(char[] orig_text) { + // Figure out how much we are going to change + // If the delta is greater than the length of the original + // text, then we will just cut our length in half. + // Where is your god now? + // There is probably some sort of minimal size that we should adhere to, + // but it's 12:30am and I simply don't feel like dealing with that now + IntegerFlatHistogram h = null; + for (int i = 0; i < this.revisionDeltas.length - 1; i++) { + if (orig_text.length <= RevisionHistograms.REVISION_DELTA_SIZES[i]) { + h = this.revisionDeltas[i]; + } } - - @Override - protected Package getProcedurePackageImpl() { - return (AddWatchList.class.getPackage()); + if (h == null) { + h = this.revisionDeltas[this.revisionDeltas.length - 1]; } - @Override - protected List> makeWorkersImpl() { - LOG.debug(String.format("Initializing %d %s", this.workConf.getTerminals(), WikipediaWorker.class.getSimpleName())); - - List> workers = new ArrayList<>(); - for (int i = 0; i < this.workConf.getTerminals(); ++i) { - WikipediaWorker worker = new WikipediaWorker(this, i); - workers.add(worker); - } - return workers; + int delta = h.nextValue(); + if (orig_text.length + delta <= 0) { + delta = -1 * (int) Math.round(orig_text.length / 1.5); + if (Math.abs(delta) == orig_text.length && delta < 0) { + delta /= 2; + } + } + if (delta != 0) { + orig_text = TextGenerator.resizeText(this.rng(), orig_text, delta); } - @Override - protected Loader makeLoaderImpl() { - return new WikipediaLoader(this); + // And permute it a little bit. This ensures that the text is slightly + // different than the last revision + orig_text = TextGenerator.permuteText(this.rng(), orig_text); + + return (orig_text); + } + + @Override + protected Package getProcedurePackageImpl() { + return (AddWatchList.class.getPackage()); + } + + @Override + protected List> makeWorkersImpl() { + LOG.debug( + String.format( + "Initializing %d %s", + this.workConf.getTerminals(), WikipediaWorker.class.getSimpleName())); + + List> workers = new ArrayList<>(); + for (int i = 0; i < this.workConf.getTerminals(); ++i) { + WikipediaWorker worker = new WikipediaWorker(this, i); + workers.add(worker); } + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new WikipediaLoader(this); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaConstants.java index 11a520f7a..197259289 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaConstants.java @@ -19,64 +19,51 @@ public abstract class WikipediaConstants { - /** - * The percentage of page updates that are made by anonymous users [0%-100%] - */ - public static final int ANONYMOUS_PAGE_UPDATE_PROB = 26; - - /** - * - */ - public static final int ANONYMOUS_USER_ID = 0; - - public static final double USER_ID_SIGMA = 1.0001d; - - /** - * Length of the tokens - */ - public static final int TOKEN_LENGTH = 32; - - /** - * Number of baseline pages - */ - public static final int PAGES = 1000; - - /** - * Number of baseline Users - */ - public static final int USERS = 2000; - - // ---------------------------------------------------------------- - // DISTRIBUTION CONSTANTS - // ---------------------------------------------------------------- - - public static final double NUM_WATCHES_PER_USER_SIGMA = 1.75d; - - public static final int MAX_WATCHES_PER_USER = 1000; - - public static final double WATCHLIST_PAGE_SIGMA = 1.0001d; - - public static final double REVISION_USER_SIGMA = 1.0001d; - - // ---------------------------------------------------------------- - // DATA SET INFORMATION - // ---------------------------------------------------------------- - - /** - * Table Names - */ - public static final String TABLENAME_IPBLOCKS = "ipblocks"; - public static final String TABLENAME_LOGGING = "logging"; - public static final String TABLENAME_PAGE = "page"; - public static final String TABLENAME_PAGE_BACKUP = "page_backup"; - public static final String TABLENAME_PAGE_RESTRICTIONS = "page_restrictions"; - public static final String TABLENAME_RECENTCHANGES = "recentchanges"; - public static final String TABLENAME_REVISION = "revision"; - public static final String TABLENAME_TEXT = "text"; - public static final String TABLENAME_USER = "useracct"; - public static final String TABLENAME_USER_GROUPS = "user_groups"; - public static final String TABLENAME_VALUE_BACKUP = "value_backup"; - public static final String TABLENAME_WATCHLIST = "watchlist"; + /** The percentage of page updates that are made by anonymous users [0%-100%] */ + public static final int ANONYMOUS_PAGE_UPDATE_PROB = 26; + /** */ + public static final int ANONYMOUS_USER_ID = 0; + public static final double USER_ID_SIGMA = 1.0001d; + + /** Length of the tokens */ + public static final int TOKEN_LENGTH = 32; + + /** Number of baseline pages */ + public static final int PAGES = 1000; + + /** Number of baseline Users */ + public static final int USERS = 2000; + + // ---------------------------------------------------------------- + // DISTRIBUTION CONSTANTS + // ---------------------------------------------------------------- + + public static final double NUM_WATCHES_PER_USER_SIGMA = 1.75d; + + public static final int MAX_WATCHES_PER_USER = 1000; + + public static final double WATCHLIST_PAGE_SIGMA = 1.0001d; + + public static final double REVISION_USER_SIGMA = 1.0001d; + + // ---------------------------------------------------------------- + // DATA SET INFORMATION + // ---------------------------------------------------------------- + + /** Table Names */ + public static final String TABLENAME_IPBLOCKS = "ipblocks"; + + public static final String TABLENAME_LOGGING = "logging"; + public static final String TABLENAME_PAGE = "page"; + public static final String TABLENAME_PAGE_BACKUP = "page_backup"; + public static final String TABLENAME_PAGE_RESTRICTIONS = "page_restrictions"; + public static final String TABLENAME_RECENTCHANGES = "recentchanges"; + public static final String TABLENAME_REVISION = "revision"; + public static final String TABLENAME_TEXT = "text"; + public static final String TABLENAME_USER = "useracct"; + public static final String TABLENAME_USER_GROUPS = "user_groups"; + public static final String TABLENAME_VALUE_BACKUP = "value_backup"; + public static final String TABLENAME_WATCHLIST = "watchlist"; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaLoader.java index b3c895127..51ce4431d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaLoader.java @@ -31,7 +31,6 @@ import com.oltpbenchmark.util.StringUtil; import com.oltpbenchmark.util.TextGenerator; import com.oltpbenchmark.util.TimeUtil; - import java.sql.Connection; import java.sql.JDBCType; import java.sql.PreparedStatement; @@ -47,606 +46,615 @@ */ public final class WikipediaLoader extends Loader { - /** - * UserId -> # of Revisions - */ - private final int[] user_revision_ctr; - - /** - * PageId -> Last Revision Id - */ - private final int[] page_last_rev_id; - - /** - * PageId -> Last Revision Length - */ - private final int[] page_last_rev_length; - - /** - * Constructor - * - * @param benchmark - */ - public WikipediaLoader(WikipediaBenchmark benchmark) { - super(benchmark); - - this.user_revision_ctr = new int[this.benchmark.num_users]; - Arrays.fill(this.user_revision_ctr, 0); - - this.page_last_rev_id = new int[this.benchmark.num_pages]; - Arrays.fill(this.page_last_rev_id, -1); - this.page_last_rev_length = new int[this.benchmark.num_pages]; - Arrays.fill(this.page_last_rev_length, -1); - - if (LOG.isDebugEnabled()) { - LOG.debug("# of USERS: {}", this.benchmark.num_users); - LOG.debug("# of PAGES: {}", this.benchmark.num_pages); - } - } + /** UserId -> # of Revisions */ + private final int[] user_revision_ctr; - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); - final int numItems = this.benchmark.num_pages + this.benchmark.num_users; - final int itemsPerThread = Math.max(numItems / numLoaders, 1); - final int numUserThreads = (int) Math.ceil((double) this.benchmark.num_users / itemsPerThread); - final int numPageThreads = (int) Math.ceil((double) this.benchmark.num_pages / itemsPerThread); + /** PageId -> Last Revision Id */ + private final int[] page_last_rev_id; - final CountDownLatch userPageLatch = new CountDownLatch(numUserThreads + numPageThreads); + /** PageId -> Last Revision Length */ + private final int[] page_last_rev_length; - final CountDownLatch anonUserLatch = new CountDownLatch(1); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); - - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); - - String sql = SQLUtil.getInsertSQL(catalog_tbl, benchmark.getWorkloadConfiguration().getDatabaseType()); - // Empty string which is treated as NULL in Oracle DB - String dummyString = getDatabaseType() == DatabaseType.ORACLE ? " " : ""; - - // load anonymous user - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - int param = 1; - stmt.setInt(param++, WikipediaConstants.ANONYMOUS_USER_ID); // user_id - stmt.setString(param++, "Anonymous"); // user_name - stmt.setString(param++, dummyString); // user_real_name - stmt.setString(param++, dummyString); // user_password - stmt.setString(param++, dummyString); // user_newpassword - stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_newpass_time - stmt.setString(param++, dummyString); // user_email - stmt.setString(param++, dummyString); // user_options - stmt.setString(param++, dummyString); // user_touched - stmt.setString(param++, dummyString); // user_token - stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_authenticated - stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_token - stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_token_expires - stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_registration - stmt.setInt(param, 0); // user_editcount - - stmt.executeUpdate(); - } - - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); - } + /** + * Constructor + * + * @param benchmark + */ + public WikipediaLoader(WikipediaBenchmark benchmark) { + super(benchmark); - @Override - public void afterLoad() { - anonUserLatch.countDown(); - } - }); + this.user_revision_ctr = new int[this.benchmark.num_users]; + Arrays.fill(this.user_revision_ctr, 0); + this.page_last_rev_id = new int[this.benchmark.num_pages]; + Arrays.fill(this.page_last_rev_id, -1); + this.page_last_rev_length = new int[this.benchmark.num_pages]; + Arrays.fill(this.page_last_rev_length, -1); - // USERS - for (int i = 0; i < numUserThreads; i++) { - // load USERS[lo, hi] - final int lo = i * itemsPerThread + 1; - final int hi = Math.min(this.benchmark.num_users, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadUsers(conn, lo, hi); - } - - @Override - public void afterLoad() { - userPageLatch.countDown(); - } - - @Override - public void beforeLoad() { - try { - anonUserLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - }); - } + if (LOG.isDebugEnabled()) { + LOG.debug("# of USERS: {}", this.benchmark.num_users); + LOG.debug("# of PAGES: {}", this.benchmark.num_pages); + } + } + + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + final int numLoaders = this.benchmark.getWorkloadConfiguration().getLoaderThreads(); + final int numItems = this.benchmark.num_pages + this.benchmark.num_users; + final int itemsPerThread = Math.max(numItems / numLoaders, 1); + final int numUserThreads = (int) Math.ceil((double) this.benchmark.num_users / itemsPerThread); + final int numPageThreads = (int) Math.ceil((double) this.benchmark.num_pages / itemsPerThread); + + final CountDownLatch userPageLatch = new CountDownLatch(numUserThreads + numPageThreads); + + final CountDownLatch anonUserLatch = new CountDownLatch(1); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); + + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); + + String sql = + SQLUtil.getInsertSQL( + catalog_tbl, benchmark.getWorkloadConfiguration().getDatabaseType()); + // Empty string which is treated as NULL in Oracle DB + String dummyString = getDatabaseType() == DatabaseType.ORACLE ? " " : ""; + + // load anonymous user + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + int param = 1; + stmt.setInt(param++, WikipediaConstants.ANONYMOUS_USER_ID); // user_id + stmt.setString(param++, "Anonymous"); // user_name + stmt.setString(param++, dummyString); // user_real_name + stmt.setString(param++, dummyString); // user_password + stmt.setString(param++, dummyString); // user_newpassword + stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_newpass_time + stmt.setString(param++, dummyString); // user_email + stmt.setString(param++, dummyString); // user_options + stmt.setString(param++, dummyString); // user_touched + stmt.setString(param++, dummyString); // user_token + stmt.setNull( + param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_authenticated + stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_token + stmt.setNull( + param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_email_token_expires + stmt.setNull(param++, JDBCType.VARCHAR.getVendorTypeNumber()); // user_registration + stmt.setInt(param, 0); // user_editcount + + stmt.executeUpdate(); + } - // PAGES - for (int i = 0; i < numPageThreads; i++) { - // load PAGES[lo, hi] - final int lo = i * itemsPerThread + 1; - final int hi = Math.min(this.benchmark.num_pages, (i + 1) * itemsPerThread); - - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - loadPages(conn, lo, hi); - } - - @Override - public void afterLoad() { - userPageLatch.countDown(); - } - - @Override - public void beforeLoad() { - try { - anonUserLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - - } - }); - } + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); + } + + @Override + public void afterLoad() { + anonUserLatch.countDown(); + } + }); - // WATCHLIST and REVISIONS depends on USERS and PAGES + // USERS + for (int i = 0; i < numUserThreads; i++) { + // load USERS[lo, hi] + final int lo = i * itemsPerThread + 1; + final int hi = Math.min(this.benchmark.num_users, (i + 1) * itemsPerThread); - // WATCHLIST - threads.add(new LoaderThread(this.benchmark) { + threads.add( + new LoaderThread(this.benchmark) { @Override public void load(Connection conn) throws SQLException { - loadWatchlist(conn); + loadUsers(conn, lo, hi); } @Override - public void beforeLoad() { - try { - userPageLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + public void afterLoad() { + userPageLatch.countDown(); + } + @Override + public void beforeLoad() { + try { + anonUserLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } - }); + }); + } + + // PAGES + for (int i = 0; i < numPageThreads; i++) { + // load PAGES[lo, hi] + final int lo = i * itemsPerThread + 1; + final int hi = Math.min(this.benchmark.num_pages, (i + 1) * itemsPerThread); - // REVISIONS - threads.add(new LoaderThread(this.benchmark) { + threads.add( + new LoaderThread(this.benchmark) { @Override public void load(Connection conn) throws SQLException { - loadRevision(conn); + loadPages(conn, lo, hi); + } + + @Override + public void afterLoad() { + userPageLatch.countDown(); } @Override public void beforeLoad() { - try { - userPageLatch.await(); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + try { + anonUserLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + } + // WATCHLIST and REVISIONS depends on USERS and PAGES + + // WATCHLIST + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadWatchlist(conn); + } + + @Override + public void beforeLoad() { + try { + userPageLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } + } }); - return threads; - } - - /** - * USERACCTS - */ - private void loadUsers(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); - - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - - try (PreparedStatement userInsert = conn.prepareStatement(sql)) { - FlatHistogram h_nameLength = new FlatHistogram<>(rng(), UserHistograms.NAME_LENGTH); - FlatHistogram h_realNameLength = new FlatHistogram<>(rng(), UserHistograms.REAL_NAME_LENGTH); - FlatHistogram h_revCount = new FlatHistogram<>(rng(), UserHistograms.REVISION_COUNT); - - int[] types = catalog_tbl.getColumnTypes(); - int batchSize = 0; - int lastPercent = -1; - for (int i = lo; i <= hi; i++) { - // The name will be prefixed with their UserId. This increases - // the likelihood that all of our usernames are going to be unique - // It's not a guarantee, but it's good enough... - String name = i + TextGenerator.randomStr(rng(), h_nameLength.nextValue()); - String realName = TextGenerator.randomStr(rng(), h_realNameLength.nextValue()); - int revCount = h_revCount.nextValue(); - String password = StringUtil.repeat("*", rng().nextInt(32) + 1); - - char[] eChars = TextGenerator.randomChars(rng(), rng().nextInt(32) + 5); - eChars[4 + rng().nextInt(eChars.length - 4)] = '@'; - String email = new String(eChars); - - String token = TextGenerator.randomStr(rng(), WikipediaConstants.TOKEN_LENGTH); - String userOptions = "fake_longoptionslist"; - String newPassTime = TimeUtil.getCurrentTimeString14(); - String touched = TimeUtil.getCurrentTimeString14(); - - int param = 1; - userInsert.setInt(param++, i); // user_id - userInsert.setString(param++, name); // user_name - userInsert.setString(param++, realName); // user_real_name - userInsert.setString(param++, password); // user_password - userInsert.setString(param++, password); // user_newpassword - userInsert.setString(param++, newPassTime); // user_newpass_time - userInsert.setString(param++, email); // user_email - userInsert.setString(param++, userOptions); // user_options - userInsert.setString(param++, touched); // user_touched - userInsert.setString(param++, token); // user_token - userInsert.setNull(param++, types[param - 2]); // user_email_authenticated - userInsert.setNull(param++, types[param - 2]); // user_email_token - userInsert.setNull(param++, types[param - 2]); // user_email_token_expires - userInsert.setNull(param++, types[param - 2]); // user_registration - userInsert.setInt(param++, revCount); // user_editcount - userInsert.addBatch(); - - if (++batchSize % workConf.getBatchSize() == 0) { - userInsert.executeBatch(); - userInsert.clearBatch(); - this.addToTableCount(catalog_tbl.getName(), batchSize); - batchSize = 0; - if (LOG.isDebugEnabled()) { - int percent = (int) (((double) i / (double) this.benchmark.num_users) * 100); - if (percent != lastPercent) { - LOG.debug("USERACCT ({}%)", percent); - } - lastPercent = percent; - } - } + // REVISIONS + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + loadRevision(conn); + } + + @Override + public void beforeLoad() { + try { + userPageLatch.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); } - if (batchSize > 0) { - this.addToTableCount(catalog_tbl.getName(), batchSize); - userInsert.executeBatch(); - userInsert.clearBatch(); + } + }); + + return threads; + } + + /** USERACCTS */ + private void loadUsers(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); + + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + + try (PreparedStatement userInsert = conn.prepareStatement(sql)) { + FlatHistogram h_nameLength = new FlatHistogram<>(rng(), UserHistograms.NAME_LENGTH); + FlatHistogram h_realNameLength = + new FlatHistogram<>(rng(), UserHistograms.REAL_NAME_LENGTH); + FlatHistogram h_revCount = new FlatHistogram<>(rng(), UserHistograms.REVISION_COUNT); + + int[] types = catalog_tbl.getColumnTypes(); + int batchSize = 0; + int lastPercent = -1; + for (int i = lo; i <= hi; i++) { + // The name will be prefixed with their UserId. This increases + // the likelihood that all of our usernames are going to be unique + // It's not a guarantee, but it's good enough... + String name = i + TextGenerator.randomStr(rng(), h_nameLength.nextValue()); + String realName = TextGenerator.randomStr(rng(), h_realNameLength.nextValue()); + int revCount = h_revCount.nextValue(); + String password = StringUtil.repeat("*", rng().nextInt(32) + 1); + + char[] eChars = TextGenerator.randomChars(rng(), rng().nextInt(32) + 5); + eChars[4 + rng().nextInt(eChars.length - 4)] = '@'; + String email = new String(eChars); + + String token = TextGenerator.randomStr(rng(), WikipediaConstants.TOKEN_LENGTH); + String userOptions = "fake_longoptionslist"; + String newPassTime = TimeUtil.getCurrentTimeString14(); + String touched = TimeUtil.getCurrentTimeString14(); + + int param = 1; + userInsert.setInt(param++, i); // user_id + userInsert.setString(param++, name); // user_name + userInsert.setString(param++, realName); // user_real_name + userInsert.setString(param++, password); // user_password + userInsert.setString(param++, password); // user_newpassword + userInsert.setString(param++, newPassTime); // user_newpass_time + userInsert.setString(param++, email); // user_email + userInsert.setString(param++, userOptions); // user_options + userInsert.setString(param++, touched); // user_touched + userInsert.setString(param++, token); // user_token + userInsert.setNull(param++, types[param - 2]); // user_email_authenticated + userInsert.setNull(param++, types[param - 2]); // user_email_token + userInsert.setNull(param++, types[param - 2]); // user_email_token_expires + userInsert.setNull(param++, types[param - 2]); // user_registration + userInsert.setInt(param++, revCount); // user_editcount + userInsert.addBatch(); + + if (++batchSize % workConf.getBatchSize() == 0) { + userInsert.executeBatch(); + userInsert.clearBatch(); + this.addToTableCount(catalog_tbl.getName(), batchSize); + batchSize = 0; + if (LOG.isDebugEnabled()) { + int percent = (int) (((double) i / (double) this.benchmark.num_users) * 100); + if (percent != lastPercent) { + LOG.debug("USERACCT ({}%)", percent); } + lastPercent = percent; + } } - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); - DatabaseType dbType = this.getDatabaseType(); - if (dbType.shouldUpdateColumnSequenceAfterLoad()) { - this.updateAutoIncrement(conn, catalog_tbl.getColumn(0), this.benchmark.num_users); - } - if (LOG.isDebugEnabled()) { - LOG.debug("Users % {}", this.benchmark.num_users); - } + } + if (batchSize > 0) { + this.addToTableCount(catalog_tbl.getName(), batchSize); + userInsert.executeBatch(); + userInsert.clearBatch(); + } } - - /** - * PAGE - */ - private void loadPages(Connection conn, int lo, int hi) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_PAGE); - - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement pageInsert = conn.prepareStatement(sql)) { - FlatHistogram h_restrictions = new FlatHistogram<>(rng(), PageHistograms.RESTRICTIONS); - - int batchSize = 0; - int lastPercent = -1; - - for (int i = lo; i <= hi; i++) { - String title = WikipediaUtil.generatePageTitle(rng(), i); - int namespace = WikipediaUtil.generatePageNamespace(rng(), i); - String restrictions = h_restrictions.nextValue(); - double pageRandom = rng().nextDouble(); - String pageTouched = TimeUtil.getCurrentTimeString14(); - - int param = 1; - pageInsert.setInt(param++, i); // page_id - pageInsert.setInt(param++, namespace); // page_namespace - pageInsert.setString(param++, title); // page_title - pageInsert.setString(param++, restrictions);// page_restrictions - pageInsert.setInt(param++, 0); // page_counter - pageInsert.setInt(param++, 0); // page_is_redirect - pageInsert.setInt(param++, 0); // page_is_new - pageInsert.setDouble(param++, pageRandom); // page_random - pageInsert.setString(param++, pageTouched); // page_touched - pageInsert.setInt(param++, 0); // page_latest - pageInsert.setInt(param++, 0); // page_len - pageInsert.addBatch(); - - if (++batchSize % workConf.getBatchSize() == 0) { - pageInsert.executeBatch(); - pageInsert.clearBatch(); - this.addToTableCount(catalog_tbl.getName(), batchSize); - batchSize = 0; - if (LOG.isDebugEnabled()) { - int percent = (int) (((double) i / (double) this.benchmark.num_pages) * 100); - if (percent != lastPercent) { - LOG.debug("PAGE ({}%)", percent); - } - lastPercent = percent; - } - } - } - if (batchSize > 0) { - pageInsert.executeBatch(); - pageInsert.clearBatch(); - this.addToTableCount(catalog_tbl.getName(), batchSize); + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); + DatabaseType dbType = this.getDatabaseType(); + if (dbType.shouldUpdateColumnSequenceAfterLoad()) { + this.updateAutoIncrement(conn, catalog_tbl.getColumn(0), this.benchmark.num_users); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Users % {}", this.benchmark.num_users); + } + } + + /** PAGE */ + private void loadPages(Connection conn, int lo, int hi) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_PAGE); + + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, true); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement pageInsert = conn.prepareStatement(sql)) { + FlatHistogram h_restrictions = + new FlatHistogram<>(rng(), PageHistograms.RESTRICTIONS); + + int batchSize = 0; + int lastPercent = -1; + + for (int i = lo; i <= hi; i++) { + String title = WikipediaUtil.generatePageTitle(rng(), i); + int namespace = WikipediaUtil.generatePageNamespace(rng(), i); + String restrictions = h_restrictions.nextValue(); + double pageRandom = rng().nextDouble(); + String pageTouched = TimeUtil.getCurrentTimeString14(); + + int param = 1; + pageInsert.setInt(param++, i); // page_id + pageInsert.setInt(param++, namespace); // page_namespace + pageInsert.setString(param++, title); // page_title + pageInsert.setString(param++, restrictions); // page_restrictions + pageInsert.setInt(param++, 0); // page_counter + pageInsert.setInt(param++, 0); // page_is_redirect + pageInsert.setInt(param++, 0); // page_is_new + pageInsert.setDouble(param++, pageRandom); // page_random + pageInsert.setString(param++, pageTouched); // page_touched + pageInsert.setInt(param++, 0); // page_latest + pageInsert.setInt(param++, 0); // page_len + pageInsert.addBatch(); + + if (++batchSize % workConf.getBatchSize() == 0) { + pageInsert.executeBatch(); + pageInsert.clearBatch(); + this.addToTableCount(catalog_tbl.getName(), batchSize); + batchSize = 0; + if (LOG.isDebugEnabled()) { + int percent = (int) (((double) i / (double) this.benchmark.num_pages) * 100); + if (percent != lastPercent) { + LOG.debug("PAGE ({}%)", percent); } + lastPercent = percent; + } } - SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); - DatabaseType dbType = this.getDatabaseType(); - if (dbType.shouldUpdateColumnSequenceAfterLoad()) { - this.updateAutoIncrement(conn, catalog_tbl.getColumn(0), this.benchmark.num_pages); + } + if (batchSize > 0) { + pageInsert.executeBatch(); + pageInsert.clearBatch(); + this.addToTableCount(catalog_tbl.getName(), batchSize); + } + } + SQLUtil.setIdentityInsert(conn, getDatabaseType(), catalog_tbl, false); + DatabaseType dbType = this.getDatabaseType(); + if (dbType.shouldUpdateColumnSequenceAfterLoad()) { + this.updateAutoIncrement(conn, catalog_tbl.getColumn(0), this.benchmark.num_pages); + } + if (LOG.isDebugEnabled()) { + LOG.debug("Users % {}", this.benchmark.num_pages); + } + } + + /** WATCHLIST */ + private void loadWatchlist(Connection conn) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_WATCHLIST); + + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement watchInsert = conn.prepareStatement(sql)) { + int max_watches_per_user = + Math.min(this.benchmark.num_pages, WikipediaConstants.MAX_WATCHES_PER_USER); + Zipf h_numWatches = + new Zipf(rng(), 0, max_watches_per_user, WikipediaConstants.NUM_WATCHES_PER_USER_SIGMA); + Zipf h_pageId = + new Zipf(rng(), 1, this.benchmark.num_pages, WikipediaConstants.WATCHLIST_PAGE_SIGMA); + + // Use a large max batch size for tables with smaller tuples + int maxBatchSize = workConf.getBatchSize() * 5; + + int batchSize = 0; + int lastPercent = -1; + Set userPages = new HashSet<>(); + + for (int user_id = 1; user_id <= this.benchmark.num_users; user_id++) { + int num_watches = h_numWatches.nextInt(); + if (LOG.isTraceEnabled()) { + LOG.trace("{} => {}", user_id, num_watches); } - if (LOG.isDebugEnabled()) { - LOG.debug("Users % {}", this.benchmark.num_pages); + if (num_watches == 0) { + continue; } - } - /** - * WATCHLIST - */ - private void loadWatchlist(Connection conn) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_WATCHLIST); - - - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement watchInsert = conn.prepareStatement(sql)) { - int max_watches_per_user = Math.min(this.benchmark.num_pages, WikipediaConstants.MAX_WATCHES_PER_USER); - Zipf h_numWatches = new Zipf(rng(), 0, max_watches_per_user, WikipediaConstants.NUM_WATCHES_PER_USER_SIGMA); - Zipf h_pageId = new Zipf(rng(), 1, this.benchmark.num_pages, WikipediaConstants.WATCHLIST_PAGE_SIGMA); - - // Use a large max batch size for tables with smaller tuples - int maxBatchSize = workConf.getBatchSize() * 5; - - int batchSize = 0; - int lastPercent = -1; - Set userPages = new HashSet<>(); - - for (int user_id = 1; user_id <= this.benchmark.num_users; user_id++) { - int num_watches = h_numWatches.nextInt(); - if (LOG.isTraceEnabled()) { - LOG.trace("{} => {}", user_id, num_watches); - } - if (num_watches == 0) { - continue; - } - - userPages.clear(); - for (int i = 0; i < num_watches; i++) { - int pageId = -1; - // HACK: Work around for testing with small database sizes - if (num_watches == max_watches_per_user) { - pageId = i + 1; - } else { - pageId = h_pageId.nextInt(); - while (userPages.contains(pageId)) { - pageId = h_pageId.nextInt(); - } - } - - userPages.add(pageId); - - Integer namespace = WikipediaUtil.generatePageNamespace(rng(), pageId); - String title = WikipediaUtil.generatePageTitle(rng(), pageId); - - int param = 1; - watchInsert.setInt(param++, user_id); // wl_user - watchInsert.setInt(param++, namespace); // wl_namespace - watchInsert.setString(param++, title); // wl_title - watchInsert.setNull(param++, java.sql.Types.VARCHAR); // wl_notificationtimestamp - watchInsert.addBatch(); - batchSize++; - } - - if (batchSize >= maxBatchSize) { - watchInsert.executeBatch(); - watchInsert.clearBatch(); - this.addToTableCount(catalog_tbl.getName(), batchSize); - batchSize = 0; - if (LOG.isDebugEnabled()) { - int percent = (int) (((double) user_id / (double) this.benchmark.num_users) * 100); - if (percent != lastPercent) { - LOG.debug("WATCHLIST ({}%)", percent); - } - lastPercent = percent; - } - } + userPages.clear(); + for (int i = 0; i < num_watches; i++) { + int pageId = -1; + // HACK: Work around for testing with small database sizes + if (num_watches == max_watches_per_user) { + pageId = i + 1; + } else { + pageId = h_pageId.nextInt(); + while (userPages.contains(pageId)) { + pageId = h_pageId.nextInt(); } + } - if (batchSize > 0) { - watchInsert.executeBatch(); - watchInsert.clearBatch(); - this.addToTableCount(catalog_tbl.getName(), batchSize); - } - } - if (LOG.isDebugEnabled()) { - LOG.debug("Watchlist Loaded"); + userPages.add(pageId); + + Integer namespace = WikipediaUtil.generatePageNamespace(rng(), pageId); + String title = WikipediaUtil.generatePageTitle(rng(), pageId); + + int param = 1; + watchInsert.setInt(param++, user_id); // wl_user + watchInsert.setInt(param++, namespace); // wl_namespace + watchInsert.setString(param++, title); // wl_title + watchInsert.setNull(param++, java.sql.Types.VARCHAR); // wl_notificationtimestamp + watchInsert.addBatch(); + batchSize++; } - } - /** - * REVISIONS - */ - private void loadRevision(Connection conn) throws SQLException { - - // TEXT - Table textTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_TEXT); - String textSQL = SQLUtil.getInsertSQL(textTable, this.getDatabaseType()); - - - // REVISION - Table revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_REVISION); - String revSQL = SQLUtil.getInsertSQL(revTable, this.getDatabaseType()); - - int batchSize = 1; - Zipf h_users = new Zipf(rng(), 1, this.benchmark.num_users, WikipediaConstants.REVISION_USER_SIGMA); - FlatHistogram h_textLength = new FlatHistogram<>(rng(), TextHistograms.TEXT_LENGTH); - FlatHistogram h_commentLength = this.benchmark.commentLength; - FlatHistogram h_minorEdit = this.benchmark.minorEdit; - FlatHistogram h_nameLength = new FlatHistogram<>(rng(), UserHistograms.NAME_LENGTH); - FlatHistogram h_numRevisions = new FlatHistogram<>(rng(), PageHistograms.REVISIONS_PER_PAGE); - - final int rev_comment_max = revTable.getColumnByName("rev_comment").getSize(); - int rev_id = 1; - int lastPercent = -1; - - try (PreparedStatement textInsert = conn.prepareStatement(textSQL); - PreparedStatement revisionInsert = conn.prepareStatement(revSQL)) { - - for (int page_id = 1; page_id <= this.benchmark.num_pages; page_id++) { - // There must be at least one revision per page - int num_revised = h_numRevisions.nextValue(); - LOG.debug(String.format("# Revisions for Page %d: %d", page_id, num_revised)); - - // Generate what the new revision is going to be - int old_text_length = h_textLength.nextValue(); - char[] old_text = TextGenerator.randomChars(rng(), old_text_length); - - for (int i = 0; i < num_revised; i++) { - // Generate the User who's doing the revision and the Page revised - // Makes sure that we always update their counter - int user_id = h_users.nextInt(); - this.user_revision_ctr[user_id - 1]++; - - // Generate what the new revision is going to be - if (i > 0) { - old_text = this.benchmark.generateRevisionText(old_text); - old_text_length = old_text.length; - } - - int rev_comment_len = Math.min(rev_comment_max, h_commentLength.nextValue() + 1); // HACK - String rev_comment = TextGenerator.randomStr(rng(), rev_comment_len); - - // The REV_USER_TEXT field is usually the username, but we'll - // just put in gibberish for now - String user_text = TextGenerator.randomStr(rng(), h_nameLength.nextValue() + 1); - - // Insert the text - int col = 1; - textInsert.setInt(col++, rev_id); // old_id - textInsert.setString(col++, new String(old_text)); // old_text - textInsert.setString(col++, "utf-8"); // old_flags - textInsert.setInt(col++, page_id); // old_page - textInsert.addBatch(); - - // Insert the revision - col = 1; - revisionInsert.setInt(col++, rev_id); // rev_id - revisionInsert.setInt(col++, page_id); // rev_page - revisionInsert.setInt(col++, rev_id); // rev_text_id - revisionInsert.setString(col++, rev_comment); // rev_comment - revisionInsert.setInt(col++, user_id); // rev_user - revisionInsert.setString(col++, user_text); // rev_user_text - revisionInsert.setString(col++, TimeUtil.getCurrentTimeString14()); // rev_timestamp - revisionInsert.setInt(col++, h_minorEdit.nextValue()); // rev_minor_edit - revisionInsert.setInt(col++, 0); // rev_deleted - revisionInsert.setInt(col++, 0); // rev_len - revisionInsert.setInt(col++, 0); // rev_parent_id - revisionInsert.addBatch(); - - // Update Last Revision Stuff - this.page_last_rev_id[page_id - 1] = rev_id; - this.page_last_rev_length[page_id - 1] = old_text_length; - rev_id++; - batchSize++; - } - if (batchSize > workConf.getBatchSize()) { - textInsert.executeBatch(); - revisionInsert.executeBatch(); - this.addToTableCount(textTable.getName(), batchSize); - this.addToTableCount(revTable.getName(), batchSize); - batchSize = 0; - - if (LOG.isDebugEnabled()) { - int percent = (int) (((double) page_id / (double) this.benchmark.num_pages) * 100); - if (percent != lastPercent) { - LOG.debug("REVISIONS ({}%)", percent); - } - lastPercent = percent; - } - } - } - if (batchSize > 0) { - textInsert.executeBatch(); - revisionInsert.executeBatch(); - this.addToTableCount(textTable.getName(), batchSize); - this.addToTableCount(revTable.getName(), batchSize); + if (batchSize >= maxBatchSize) { + watchInsert.executeBatch(); + watchInsert.clearBatch(); + this.addToTableCount(catalog_tbl.getName(), batchSize); + batchSize = 0; + if (LOG.isDebugEnabled()) { + int percent = (int) (((double) user_id / (double) this.benchmark.num_users) * 100); + if (percent != lastPercent) { + LOG.debug("WATCHLIST ({}%)", percent); } + lastPercent = percent; + } } + } - DatabaseType dbType = this.getDatabaseType(); - if (dbType.shouldUpdateColumnSequenceAfterLoad()) { - this.updateAutoIncrement(conn, textTable.getColumn(0), rev_id); - this.updateAutoIncrement(conn, revTable.getColumn(0), rev_id); + if (batchSize > 0) { + watchInsert.executeBatch(); + watchInsert.clearBatch(); + this.addToTableCount(catalog_tbl.getName(), batchSize); + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("Watchlist Loaded"); + } + } + + /** REVISIONS */ + private void loadRevision(Connection conn) throws SQLException { + + // TEXT + Table textTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_TEXT); + String textSQL = SQLUtil.getInsertSQL(textTable, this.getDatabaseType()); + + // REVISION + Table revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_REVISION); + String revSQL = SQLUtil.getInsertSQL(revTable, this.getDatabaseType()); + + int batchSize = 1; + Zipf h_users = + new Zipf(rng(), 1, this.benchmark.num_users, WikipediaConstants.REVISION_USER_SIGMA); + FlatHistogram h_textLength = new FlatHistogram<>(rng(), TextHistograms.TEXT_LENGTH); + FlatHistogram h_commentLength = this.benchmark.commentLength; + FlatHistogram h_minorEdit = this.benchmark.minorEdit; + FlatHistogram h_nameLength = new FlatHistogram<>(rng(), UserHistograms.NAME_LENGTH); + FlatHistogram h_numRevisions = + new FlatHistogram<>(rng(), PageHistograms.REVISIONS_PER_PAGE); + + final int rev_comment_max = revTable.getColumnByName("rev_comment").getSize(); + int rev_id = 1; + int lastPercent = -1; + + try (PreparedStatement textInsert = conn.prepareStatement(textSQL); + PreparedStatement revisionInsert = conn.prepareStatement(revSQL)) { + + for (int page_id = 1; page_id <= this.benchmark.num_pages; page_id++) { + // There must be at least one revision per page + int num_revised = h_numRevisions.nextValue(); + LOG.debug(String.format("# Revisions for Page %d: %d", page_id, num_revised)); + + // Generate what the new revision is going to be + int old_text_length = h_textLength.nextValue(); + char[] old_text = TextGenerator.randomChars(rng(), old_text_length); + + for (int i = 0; i < num_revised; i++) { + // Generate the User who's doing the revision and the Page revised + // Makes sure that we always update their counter + int user_id = h_users.nextInt(); + this.user_revision_ctr[user_id - 1]++; + + // Generate what the new revision is going to be + if (i > 0) { + old_text = this.benchmark.generateRevisionText(old_text); + old_text_length = old_text.length; + } + + int rev_comment_len = Math.min(rev_comment_max, h_commentLength.nextValue() + 1); // HACK + String rev_comment = TextGenerator.randomStr(rng(), rev_comment_len); + + // The REV_USER_TEXT field is usually the username, but we'll + // just put in gibberish for now + String user_text = TextGenerator.randomStr(rng(), h_nameLength.nextValue() + 1); + + // Insert the text + int col = 1; + textInsert.setInt(col++, rev_id); // old_id + textInsert.setString(col++, new String(old_text)); // old_text + textInsert.setString(col++, "utf-8"); // old_flags + textInsert.setInt(col++, page_id); // old_page + textInsert.addBatch(); + + // Insert the revision + col = 1; + revisionInsert.setInt(col++, rev_id); // rev_id + revisionInsert.setInt(col++, page_id); // rev_page + revisionInsert.setInt(col++, rev_id); // rev_text_id + revisionInsert.setString(col++, rev_comment); // rev_comment + revisionInsert.setInt(col++, user_id); // rev_user + revisionInsert.setString(col++, user_text); // rev_user_text + revisionInsert.setString(col++, TimeUtil.getCurrentTimeString14()); // rev_timestamp + revisionInsert.setInt(col++, h_minorEdit.nextValue()); // rev_minor_edit + revisionInsert.setInt(col++, 0); // rev_deleted + revisionInsert.setInt(col++, 0); // rev_len + revisionInsert.setInt(col++, 0); // rev_parent_id + revisionInsert.addBatch(); + + // Update Last Revision Stuff + this.page_last_rev_id[page_id - 1] = rev_id; + this.page_last_rev_length[page_id - 1] = old_text_length; + rev_id++; + batchSize++; } - - // UPDATE USER - revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); - String revTableName = (this.getDatabaseType().shouldEscapeNames()) ? revTable.getEscapedName() : revTable.getName(); - - String updateUserSql = "UPDATE " + revTableName + " SET user_editcount = ?, " + " user_touched = ? " + " WHERE user_id = ?"; - try (PreparedStatement userUpdate = conn.prepareStatement(updateUserSql)) { - batchSize = 0; - for (int i = 0; i < this.benchmark.num_users; i++) { - int col = 1; - userUpdate.setInt(col++, this.user_revision_ctr[i]); - userUpdate.setString(col++, TimeUtil.getCurrentTimeString14()); - userUpdate.setInt(col++, i + 1); // ids start at 1 - userUpdate.addBatch(); - if ((++batchSize % workConf.getBatchSize()) == 0) { - userUpdate.executeBatch(); - userUpdate.clearBatch(); - batchSize = 0; - } - } - if (batchSize > 0) { - userUpdate.executeBatch(); - userUpdate.clearBatch(); + if (batchSize > workConf.getBatchSize()) { + textInsert.executeBatch(); + revisionInsert.executeBatch(); + this.addToTableCount(textTable.getName(), batchSize); + this.addToTableCount(revTable.getName(), batchSize); + batchSize = 0; + + if (LOG.isDebugEnabled()) { + int percent = (int) (((double) page_id / (double) this.benchmark.num_pages) * 100); + if (percent != lastPercent) { + LOG.debug("REVISIONS ({}%)", percent); } + lastPercent = percent; + } } + } + if (batchSize > 0) { + textInsert.executeBatch(); + revisionInsert.executeBatch(); + this.addToTableCount(textTable.getName(), batchSize); + this.addToTableCount(revTable.getName(), batchSize); + } + } - // UPDATE PAGES - revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_PAGE); - - revTableName = (this.getDatabaseType().shouldEscapeNames()) ? revTable.getEscapedName() : revTable.getName(); - - String updatePageSql = "UPDATE " + revTableName + - " SET page_latest = ?, " + - " page_touched = ?, " + - " page_is_new = 0, " + - " page_is_redirect = 0, " + - " page_len = ? " + - " WHERE page_id = ?"; - try (PreparedStatement pageUpdate = conn.prepareStatement(updatePageSql)) { - batchSize = 0; - for (int i = 0; i < this.benchmark.num_pages; i++) { - if (this.page_last_rev_id[i] == -1) { - continue; - } - - int col = 1; - pageUpdate.setInt(col++, this.page_last_rev_id[i]); - pageUpdate.setString(col++, TimeUtil.getCurrentTimeString14()); - pageUpdate.setInt(col++, this.page_last_rev_length[i]); - pageUpdate.setInt(col++, i + 1); // ids start at 1 - pageUpdate.addBatch(); - if ((++batchSize % workConf.getBatchSize()) == 0) { - pageUpdate.executeBatch(); - pageUpdate.clearBatch(); - batchSize = 0; - } - } - if (batchSize > 0) { - pageUpdate.executeBatch(); - pageUpdate.clearBatch(); - } + DatabaseType dbType = this.getDatabaseType(); + if (dbType.shouldUpdateColumnSequenceAfterLoad()) { + this.updateAutoIncrement(conn, textTable.getColumn(0), rev_id); + this.updateAutoIncrement(conn, revTable.getColumn(0), rev_id); + } + + // UPDATE USER + revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_USER); + String revTableName = + (this.getDatabaseType().shouldEscapeNames()) + ? revTable.getEscapedName() + : revTable.getName(); + + String updateUserSql = + "UPDATE " + + revTableName + + " SET user_editcount = ?, " + + " user_touched = ? " + + " WHERE user_id = ?"; + try (PreparedStatement userUpdate = conn.prepareStatement(updateUserSql)) { + batchSize = 0; + for (int i = 0; i < this.benchmark.num_users; i++) { + int col = 1; + userUpdate.setInt(col++, this.user_revision_ctr[i]); + userUpdate.setString(col++, TimeUtil.getCurrentTimeString14()); + userUpdate.setInt(col++, i + 1); // ids start at 1 + userUpdate.addBatch(); + if ((++batchSize % workConf.getBatchSize()) == 0) { + userUpdate.executeBatch(); + userUpdate.clearBatch(); + batchSize = 0; + } + } + if (batchSize > 0) { + userUpdate.executeBatch(); + userUpdate.clearBatch(); + } + } + + // UPDATE PAGES + revTable = benchmark.getCatalog().getTable(WikipediaConstants.TABLENAME_PAGE); + + revTableName = + (this.getDatabaseType().shouldEscapeNames()) + ? revTable.getEscapedName() + : revTable.getName(); + + String updatePageSql = + "UPDATE " + + revTableName + + " SET page_latest = ?, " + + " page_touched = ?, " + + " page_is_new = 0, " + + " page_is_redirect = 0, " + + " page_len = ? " + + " WHERE page_id = ?"; + try (PreparedStatement pageUpdate = conn.prepareStatement(updatePageSql)) { + batchSize = 0; + for (int i = 0; i < this.benchmark.num_pages; i++) { + if (this.page_last_rev_id[i] == -1) { + continue; } - if (LOG.isDebugEnabled()) { - LOG.debug("Revision loaded"); + int col = 1; + pageUpdate.setInt(col++, this.page_last_rev_id[i]); + pageUpdate.setString(col++, TimeUtil.getCurrentTimeString14()); + pageUpdate.setInt(col++, this.page_last_rev_length[i]); + pageUpdate.setInt(col++, i + 1); // ids start at 1 + pageUpdate.addBatch(); + if ((++batchSize % workConf.getBatchSize()) == 0) { + pageUpdate.executeBatch(); + pageUpdate.clearBatch(); + batchSize = 0; } + } + if (batchSize > 0) { + pageUpdate.executeBatch(); + pageUpdate.clearBatch(); + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Revision loaded"); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaWorker.java index 90193675b..c1bd0aa6b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/WikipediaWorker.java @@ -28,150 +28,183 @@ import com.oltpbenchmark.util.RandomDistribution.Flat; import com.oltpbenchmark.util.RandomDistribution.Zipf; import com.oltpbenchmark.util.TextGenerator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.SQLException; import java.util.HashSet; import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class WikipediaWorker extends Worker { - private static final Logger LOG = LoggerFactory.getLogger(WikipediaWorker.class); - - private Set addedWatchlistPages = new HashSet<>(); - - public WikipediaWorker(WikipediaBenchmark benchmarkModule, int id) { - super(benchmarkModule, id); - + private static final Logger LOG = LoggerFactory.getLogger(WikipediaWorker.class); + + private Set addedWatchlistPages = new HashSet<>(); + + public WikipediaWorker(WikipediaBenchmark benchmarkModule, int id) { + super(benchmarkModule, id); + } + + private String generateUserIP() { + return String.format( + "%d.%d.%d.%d", + this.rng().nextInt(255) + 1, + this.rng().nextInt(256), + this.rng().nextInt(256), + this.rng().nextInt(256)); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) + throws UserAbortException, SQLException { + Flat z_users = new Flat(this.rng(), 1, this.getBenchmark().num_users); + Zipf z_pages = + new Zipf(this.rng(), 1, this.getBenchmark().num_pages, WikipediaConstants.USER_ID_SIGMA); + + Class procClass = nextTransaction.getProcedureClass(); + boolean needUser = + (procClass.equals(AddWatchList.class) + || procClass.equals(RemoveWatchList.class) + || procClass.equals(GetPageAuthenticated.class)); + + int userId; + + do { + // Check whether this should be an anonymous update + if (this.rng().nextInt(100) < WikipediaConstants.ANONYMOUS_PAGE_UPDATE_PROB) { + userId = WikipediaConstants.ANONYMOUS_USER_ID; + } + // Otherwise figure out what user is updating this page + else { + userId = z_users.nextInt(); + } + // Repeat if we need a user but we generated Anonymous + } while (needUser && userId == WikipediaConstants.ANONYMOUS_USER_ID); + + // Figure out what page they're going to update + int page_id = z_pages.nextInt(); + if (procClass.equals(AddWatchList.class)) { + // This while loop gets stuck in an infinite loop for small scale factors. + // So we're just going to let it throw whatever it wants in the set from now on + // while (addedWatchlistPages.contains(page_id)) { + // page_id = z_pages.nextInt(); + // } + addedWatchlistPages.add(page_id); } - private String generateUserIP() { - return String.format("%d.%d.%d.%d", this.rng().nextInt(255) + 1, this.rng().nextInt(256), this.rng().nextInt(256), this.rng().nextInt(256)); + String pageTitle = WikipediaUtil.generatePageTitle(this.rng(), page_id); + int nameSpace = WikipediaUtil.generatePageNamespace(this.rng(), page_id); + + // AddWatchList + try { + if (procClass.equals(AddWatchList.class)) { + + this.addToWatchlist(conn, userId, nameSpace, pageTitle); + } + // RemoveWatchList + else if (procClass.equals(RemoveWatchList.class)) { + + this.removeFromWatchlist(conn, userId, nameSpace, pageTitle); + } + // UpdatePage + else if (procClass.equals(UpdatePage.class)) { + this.updatePage(conn, this.generateUserIP(), userId, nameSpace, pageTitle); + } + // GetPageAnonymous + else if (procClass.equals(GetPageAnonymous.class)) { + this.getPageAnonymous(conn, true, this.generateUserIP(), nameSpace, pageTitle); + } + // GetPageAuthenticated + else if (procClass.equals(GetPageAuthenticated.class)) { + + this.getPageAuthenticated(conn, true, this.generateUserIP(), userId, nameSpace, pageTitle); + } + } catch (SQLException esql) { + LOG.error( + "Caught SQL Exception in WikipediaWorker for procedure{}:{}", + procClass.getName(), + esql, + esql); + throw esql; } - - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTransaction) throws UserAbortException, SQLException { - Flat z_users = new Flat(this.rng(), 1, this.getBenchmark().num_users); - Zipf z_pages = new Zipf(this.rng(), 1, this.getBenchmark().num_pages, WikipediaConstants.USER_ID_SIGMA); - - Class procClass = nextTransaction.getProcedureClass(); - boolean needUser = (procClass.equals(AddWatchList.class) || procClass.equals(RemoveWatchList.class) || procClass.equals(GetPageAuthenticated.class)); - - int userId; - - do { - // Check whether this should be an anonymous update - if (this.rng().nextInt(100) < WikipediaConstants.ANONYMOUS_PAGE_UPDATE_PROB) { - userId = WikipediaConstants.ANONYMOUS_USER_ID; - } - // Otherwise figure out what user is updating this page - else { - userId = z_users.nextInt(); - } - // Repeat if we need a user but we generated Anonymous - } - while (needUser && userId == WikipediaConstants.ANONYMOUS_USER_ID); - - // Figure out what page they're going to update - int page_id = z_pages.nextInt(); - if (procClass.equals(AddWatchList.class)) { - // This while loop gets stuck in an infinite loop for small scale factors. - // So we're just going to let it throw whatever it wants in the set from now on - // while (addedWatchlistPages.contains(page_id)) { - // page_id = z_pages.nextInt(); - // } - addedWatchlistPages.add(page_id); - } - - String pageTitle = WikipediaUtil.generatePageTitle(this.rng(), page_id); - int nameSpace = WikipediaUtil.generatePageNamespace(this.rng(), page_id); - - // AddWatchList - try { - if (procClass.equals(AddWatchList.class)) { - - this.addToWatchlist(conn, userId, nameSpace, pageTitle); - } - // RemoveWatchList - else if (procClass.equals(RemoveWatchList.class)) { - - this.removeFromWatchlist(conn, userId, nameSpace, pageTitle); - } - // UpdatePage - else if (procClass.equals(UpdatePage.class)) { - this.updatePage(conn, this.generateUserIP(), userId, nameSpace, pageTitle); - } - // GetPageAnonymous - else if (procClass.equals(GetPageAnonymous.class)) { - this.getPageAnonymous(conn, true, this.generateUserIP(), nameSpace, pageTitle); - } - // GetPageAuthenticated - else if (procClass.equals(GetPageAuthenticated.class)) { - - this.getPageAuthenticated(conn, true, this.generateUserIP(), userId, nameSpace, pageTitle); - } - } catch (SQLException esql) { - LOG.error("Caught SQL Exception in WikipediaWorker for procedure{}:{}", procClass.getName(), esql, esql); - throw esql; - } - return (TransactionStatus.SUCCESS); + return (TransactionStatus.SUCCESS); + } + + /** + * Implements wikipedia selection of last version of an article (with and without the user being + * logged in) + */ + public Article getPageAnonymous( + Connection conn, boolean forSelect, String userIp, int nameSpace, String pageTitle) + throws SQLException { + GetPageAnonymous proc = this.getProcedure(GetPageAnonymous.class); + + return proc.run(conn, forSelect, userIp, nameSpace, pageTitle); + } + + public Article getPageAuthenticated( + Connection conn, + boolean forSelect, + String userIp, + int userId, + int nameSpace, + String pageTitle) + throws SQLException { + GetPageAuthenticated proc = this.getProcedure(GetPageAuthenticated.class); + + return proc.run(conn, forSelect, userIp, userId, nameSpace, pageTitle); + } + + public void addToWatchlist(Connection conn, int userId, int nameSpace, String pageTitle) + throws SQLException { + AddWatchList proc = this.getProcedure(AddWatchList.class); + + proc.run(conn, userId, nameSpace, pageTitle); + } + + public void removeFromWatchlist(Connection conn, int userId, int nameSpace, String pageTitle) + throws SQLException { + RemoveWatchList proc = this.getProcedure(RemoveWatchList.class); + + proc.run(conn, userId, nameSpace, pageTitle); + } + + public void updatePage( + Connection conn, String userIp, int userId, int nameSpace, String pageTitle) + throws SQLException { + Article a = this.getPageAnonymous(conn, false, userIp, nameSpace, pageTitle); + + // TODO: If the Article is null, then we want to insert a new page. + // But we don't support that right now. + if (a == null) { + return; } - /** - * Implements wikipedia selection of last version of an article (with and - * without the user being logged in) - */ - public Article getPageAnonymous(Connection conn, boolean forSelect, String userIp, int nameSpace, String pageTitle) throws SQLException { - GetPageAnonymous proc = this.getProcedure(GetPageAnonymous.class); - - return proc.run(conn, forSelect, userIp, nameSpace, pageTitle); - } - - public Article getPageAuthenticated(Connection conn, boolean forSelect, String userIp, int userId, int nameSpace, String pageTitle) throws SQLException { - GetPageAuthenticated proc = this.getProcedure(GetPageAuthenticated.class); - - return proc.run(conn, forSelect, userIp, userId, nameSpace, pageTitle); - } + WikipediaBenchmark b = this.getBenchmark(); + int revCommentLen = b.commentLength.nextValue(); + String revComment = TextGenerator.randomStr(this.rng(), revCommentLen + 1); + int revMinorEdit = b.minorEdit.nextValue(); - public void addToWatchlist(Connection conn, int userId, int nameSpace, String pageTitle) throws SQLException { - AddWatchList proc = this.getProcedure(AddWatchList.class); + // Permute the original text of the article + // Important: We have to make sure that we fill in the entire array + char[] newText = b.generateRevisionText(a.oldText.toCharArray()); - proc.run(conn, userId, nameSpace, pageTitle); + if (LOG.isTraceEnabled()) { + LOG.trace("UPDATING: Page: id:{} ns:{} title{}", a.pageId, nameSpace, pageTitle); } - - public void removeFromWatchlist(Connection conn, int userId, int nameSpace, String pageTitle) throws SQLException { - RemoveWatchList proc = this.getProcedure(RemoveWatchList.class); - - proc.run(conn, userId, nameSpace, pageTitle); - } - - public void updatePage(Connection conn, String userIp, int userId, int nameSpace, String pageTitle) throws SQLException { - Article a = this.getPageAnonymous(conn, false, userIp, nameSpace, pageTitle); - - // TODO: If the Article is null, then we want to insert a new page. - // But we don't support that right now. - if (a == null) { - return; - } - - WikipediaBenchmark b = this.getBenchmark(); - int revCommentLen = b.commentLength.nextValue(); - String revComment = TextGenerator.randomStr(this.rng(), revCommentLen + 1); - int revMinorEdit = b.minorEdit.nextValue(); - - // Permute the original text of the article - // Important: We have to make sure that we fill in the entire array - char[] newText = b.generateRevisionText(a.oldText.toCharArray()); - - if (LOG.isTraceEnabled()) { - LOG.trace("UPDATING: Page: id:{} ns:{} title{}", a.pageId, nameSpace, pageTitle); - } - UpdatePage proc = this.getProcedure(UpdatePage.class); - - - proc.run(conn, a.textId, a.pageId, pageTitle, new String(newText), nameSpace, userId, userIp, a.userText, a.revisionId, revComment, revMinorEdit); - - } - + UpdatePage proc = this.getProcedure(UpdatePage.class); + + proc.run( + conn, + a.textId, + a.pageId, + pageTitle, + new String(newText), + nameSpace, + userId, + userIp, + a.userText, + a.revisionId, + revComment, + revMinorEdit); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/PageHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/PageHistograms.java index 46def3023..e840ffa0d 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/PageHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/PageHistograms.java @@ -21,364 +21,358 @@ public abstract class PageHistograms { - /** - * The length of the PAGE_TITLE column - */ - public static final Histogram TITLE_LENGTH = new Histogram() { + /** The length of the PAGE_TITLE column */ + public static final Histogram TITLE_LENGTH = + new Histogram() { { - this.put(1, 5); - this.put(2, 44); - this.put(3, 364); - this.put(4, 976); - this.put(5, 1352); - this.put(6, 2267); - this.put(7, 2868); - this.put(8, 3444); - this.put(9, 3799); - this.put(10, 4388); - this.put(11, 5637); - this.put(12, 7784); - this.put(13, 9413); - this.put(14, 7919); - this.put(15, 5127); - this.put(16, 3810); - this.put(17, 3540); - this.put(18, 3323); - this.put(19, 2912); - this.put(20, 2652); - this.put(21, 2490); - this.put(22, 2320); - this.put(23, 2158); - this.put(24, 1957); - this.put(25, 1701); - this.put(26, 1602); - this.put(27, 1419); - this.put(28, 1385); - this.put(29, 1168); - this.put(30, 1102); - this.put(31, 1030); - this.put(32, 984); - this.put(33, 852); - this.put(34, 801); - this.put(35, 762); - this.put(36, 639); - this.put(37, 593); - this.put(38, 531); - this.put(39, 524); - this.put(40, 472); - this.put(41, 404); - this.put(42, 353); - this.put(43, 344); - this.put(44, 307); - this.put(45, 240); - this.put(46, 250); - this.put(47, 169); - this.put(48, 195); - this.put(49, 159); - this.put(50, 130); - this.put(51, 115); - this.put(52, 124); - this.put(53, 104); - this.put(54, 78); - this.put(55, 95); - this.put(56, 77); - this.put(57, 64); - this.put(58, 66); - this.put(59, 47); - this.put(60, 75); - this.put(61, 46); - this.put(62, 45); - this.put(63, 33); - this.put(64, 39); - this.put(65, 36); - this.put(66, 30); - this.put(67, 24); - this.put(68, 28); - this.put(69, 22); - this.put(70, 13); - this.put(71, 23); - this.put(72, 15); - this.put(73, 12); - this.put(74, 11); - this.put(75, 6); - this.put(76, 12); - this.put(77, 10); - this.put(78, 7); - this.put(79, 6); - this.put(80, 7); - this.put(81, 3); - this.put(83, 4); - this.put(84, 4); - this.put(85, 2); - this.put(86, 2); - this.put(87, 4); - this.put(88, 4); - this.put(89, 1); - this.put(90, 1); - this.put(91, 5); - this.put(92, 3); - this.put(93, 6); - this.put(94, 1); - this.put(95, 3); - this.put(96, 5); - this.put(97, 1); - this.put(99, 1); - this.put(100, 1); - this.put(103, 2); - this.put(104, 1); - this.put(105, 1); - this.put(106, 2); - this.put(109, 2); - this.put(111, 1); - this.put(115, 1); - this.put(117, 1); - this.put(118, 1); - this.put(134, 1); - this.put(141, 1); + this.put(1, 5); + this.put(2, 44); + this.put(3, 364); + this.put(4, 976); + this.put(5, 1352); + this.put(6, 2267); + this.put(7, 2868); + this.put(8, 3444); + this.put(9, 3799); + this.put(10, 4388); + this.put(11, 5637); + this.put(12, 7784); + this.put(13, 9413); + this.put(14, 7919); + this.put(15, 5127); + this.put(16, 3810); + this.put(17, 3540); + this.put(18, 3323); + this.put(19, 2912); + this.put(20, 2652); + this.put(21, 2490); + this.put(22, 2320); + this.put(23, 2158); + this.put(24, 1957); + this.put(25, 1701); + this.put(26, 1602); + this.put(27, 1419); + this.put(28, 1385); + this.put(29, 1168); + this.put(30, 1102); + this.put(31, 1030); + this.put(32, 984); + this.put(33, 852); + this.put(34, 801); + this.put(35, 762); + this.put(36, 639); + this.put(37, 593); + this.put(38, 531); + this.put(39, 524); + this.put(40, 472); + this.put(41, 404); + this.put(42, 353); + this.put(43, 344); + this.put(44, 307); + this.put(45, 240); + this.put(46, 250); + this.put(47, 169); + this.put(48, 195); + this.put(49, 159); + this.put(50, 130); + this.put(51, 115); + this.put(52, 124); + this.put(53, 104); + this.put(54, 78); + this.put(55, 95); + this.put(56, 77); + this.put(57, 64); + this.put(58, 66); + this.put(59, 47); + this.put(60, 75); + this.put(61, 46); + this.put(62, 45); + this.put(63, 33); + this.put(64, 39); + this.put(65, 36); + this.put(66, 30); + this.put(67, 24); + this.put(68, 28); + this.put(69, 22); + this.put(70, 13); + this.put(71, 23); + this.put(72, 15); + this.put(73, 12); + this.put(74, 11); + this.put(75, 6); + this.put(76, 12); + this.put(77, 10); + this.put(78, 7); + this.put(79, 6); + this.put(80, 7); + this.put(81, 3); + this.put(83, 4); + this.put(84, 4); + this.put(85, 2); + this.put(86, 2); + this.put(87, 4); + this.put(88, 4); + this.put(89, 1); + this.put(90, 1); + this.put(91, 5); + this.put(92, 3); + this.put(93, 6); + this.put(94, 1); + this.put(95, 3); + this.put(96, 5); + this.put(97, 1); + this.put(99, 1); + this.put(100, 1); + this.put(103, 2); + this.put(104, 1); + this.put(105, 1); + this.put(106, 2); + this.put(109, 2); + this.put(111, 1); + this.put(115, 1); + this.put(117, 1); + this.put(118, 1); + this.put(134, 1); + this.put(141, 1); } - }; + }; - /** - * Revisions per page - * This seems way off because I think our sample data set is incomplete - */ - public static final Histogram REVISIONS_PER_PAGE = new Histogram() { + /** Revisions per page This seems way off because I think our sample data set is incomplete */ + public static final Histogram REVISIONS_PER_PAGE = + new Histogram() { { - this.put(1, 39401); // XXX 39401 - this.put(2, 16869); // XXX 16869 - this.put(3, 8127); - this.put(4, 5229); - this.put(5, 3621); - this.put(6, 2538); - this.put(7, 2001); - this.put(8, 1668); - this.put(9, 1419); - this.put(10, 1183); - this.put(11, 1088); - this.put(12, 981); - this.put(13, 857); - this.put(14, 771); - this.put(15, 651); - this.put(16, 637); - this.put(17, 633); - this.put(18, 537); - this.put(19, 488); - this.put(20, 500); - this.put(21, 467); - this.put(22, 394); - this.put(23, 378); - this.put(24, 354); - this.put(25, 303); - this.put(26, 304); - this.put(27, 285); - this.put(28, 249); - this.put(29, 232); - this.put(30, 258); - this.put(31, 234); - this.put(32, 205); - this.put(33, 223); - this.put(34, 171); - this.put(35, 177); - this.put(36, 170); - this.put(37, 171); - this.put(38, 155); - this.put(39, 150); - this.put(40, 129); - this.put(41, 142); - this.put(42, 120); - this.put(43, 118); - this.put(44, 129); - this.put(45, 113); - this.put(46, 92); - this.put(47, 113); - this.put(48, 98); - this.put(49, 100); - this.put(50, 76); - this.put(51, 122); - this.put(52, 89); - this.put(53, 102); - this.put(54, 84); - this.put(55, 84); - this.put(56, 78); - this.put(57, 76); - this.put(58, 71); - this.put(59, 63); - this.put(60, 69); - this.put(61, 76); - this.put(62, 60); - this.put(63, 53); - this.put(64, 56); - this.put(65, 52); - this.put(66, 47); - this.put(67, 46); - this.put(68, 46); - this.put(69, 55); - this.put(70, 46); - this.put(71, 37); - this.put(72, 50); - this.put(73, 43); - this.put(74, 43); - this.put(75, 34); - this.put(76, 46); - this.put(77, 38); - this.put(78, 37); - this.put(79, 34); - this.put(80, 49); - this.put(81, 34); - this.put(82, 33); - this.put(83, 33); - this.put(84, 40); - this.put(85, 33); - this.put(86, 28); - this.put(87, 35); - this.put(88, 29); - this.put(89, 35); - this.put(90, 20); - this.put(91, 20); - this.put(92, 35); - this.put(93, 32); - this.put(94, 27); - this.put(95, 25); - this.put(96, 25); - this.put(97, 25); - this.put(98, 28); - this.put(99, 21); - this.put(100, 244); - this.put(110, 179); - this.put(120, 167); - this.put(130, 137); - this.put(140, 98); - this.put(150, 105); - this.put(160, 88); - this.put(170, 81); - this.put(180, 72); - this.put(190, 69); - this.put(200, 62); - this.put(210, 60); - this.put(220, 38); - this.put(230, 45); - this.put(240, 43); - this.put(250, 36); - this.put(260, 38); - this.put(270, 43); - this.put(280, 36); - this.put(290, 18); - this.put(300, 33); - this.put(310, 20); - this.put(320, 18); - this.put(330, 32); - this.put(340, 19); - this.put(350, 23); - this.put(360, 27); - this.put(370, 22); - this.put(380, 17); - this.put(390, 19); - this.put(400, 9); - this.put(410, 13); - this.put(420, 12); - this.put(430, 19); - this.put(440, 16); - this.put(450, 12); - this.put(460, 10); - this.put(470, 8); - this.put(480, 5); - this.put(490, 6); - this.put(500, 7); - this.put(510, 9); - this.put(520, 9); - this.put(530, 7); - this.put(540, 12); - this.put(550, 9); - this.put(560, 8); - this.put(570, 11); - this.put(580, 4); - this.put(590, 3); - this.put(600, 12); - this.put(610, 9); - this.put(620, 5); - this.put(630, 7); - this.put(640, 5); - this.put(650, 5); - this.put(660, 4); - this.put(670, 5); - this.put(680, 2); - this.put(690, 2); - this.put(700, 4); - this.put(710, 5); - this.put(720, 4); - this.put(730, 6); - this.put(740, 7); - this.put(750, 5); - this.put(760, 2); - this.put(770, 1); - this.put(780, 2); - this.put(800, 4); - this.put(810, 1); - this.put(820, 1); - this.put(830, 1); - this.put(840, 6); - this.put(850, 3); - this.put(860, 4); - this.put(870, 1); - this.put(880, 2); - this.put(890, 4); - this.put(900, 2); - this.put(910, 2); - this.put(920, 2); - this.put(930, 1); - this.put(940, 3); - this.put(950, 6); - this.put(960, 4); - this.put(970, 1); - this.put(980, 3); - this.put(990, 2); - this.put(1000, 1); + this.put(1, 39401); // XXX 39401 + this.put(2, 16869); // XXX 16869 + this.put(3, 8127); + this.put(4, 5229); + this.put(5, 3621); + this.put(6, 2538); + this.put(7, 2001); + this.put(8, 1668); + this.put(9, 1419); + this.put(10, 1183); + this.put(11, 1088); + this.put(12, 981); + this.put(13, 857); + this.put(14, 771); + this.put(15, 651); + this.put(16, 637); + this.put(17, 633); + this.put(18, 537); + this.put(19, 488); + this.put(20, 500); + this.put(21, 467); + this.put(22, 394); + this.put(23, 378); + this.put(24, 354); + this.put(25, 303); + this.put(26, 304); + this.put(27, 285); + this.put(28, 249); + this.put(29, 232); + this.put(30, 258); + this.put(31, 234); + this.put(32, 205); + this.put(33, 223); + this.put(34, 171); + this.put(35, 177); + this.put(36, 170); + this.put(37, 171); + this.put(38, 155); + this.put(39, 150); + this.put(40, 129); + this.put(41, 142); + this.put(42, 120); + this.put(43, 118); + this.put(44, 129); + this.put(45, 113); + this.put(46, 92); + this.put(47, 113); + this.put(48, 98); + this.put(49, 100); + this.put(50, 76); + this.put(51, 122); + this.put(52, 89); + this.put(53, 102); + this.put(54, 84); + this.put(55, 84); + this.put(56, 78); + this.put(57, 76); + this.put(58, 71); + this.put(59, 63); + this.put(60, 69); + this.put(61, 76); + this.put(62, 60); + this.put(63, 53); + this.put(64, 56); + this.put(65, 52); + this.put(66, 47); + this.put(67, 46); + this.put(68, 46); + this.put(69, 55); + this.put(70, 46); + this.put(71, 37); + this.put(72, 50); + this.put(73, 43); + this.put(74, 43); + this.put(75, 34); + this.put(76, 46); + this.put(77, 38); + this.put(78, 37); + this.put(79, 34); + this.put(80, 49); + this.put(81, 34); + this.put(82, 33); + this.put(83, 33); + this.put(84, 40); + this.put(85, 33); + this.put(86, 28); + this.put(87, 35); + this.put(88, 29); + this.put(89, 35); + this.put(90, 20); + this.put(91, 20); + this.put(92, 35); + this.put(93, 32); + this.put(94, 27); + this.put(95, 25); + this.put(96, 25); + this.put(97, 25); + this.put(98, 28); + this.put(99, 21); + this.put(100, 244); + this.put(110, 179); + this.put(120, 167); + this.put(130, 137); + this.put(140, 98); + this.put(150, 105); + this.put(160, 88); + this.put(170, 81); + this.put(180, 72); + this.put(190, 69); + this.put(200, 62); + this.put(210, 60); + this.put(220, 38); + this.put(230, 45); + this.put(240, 43); + this.put(250, 36); + this.put(260, 38); + this.put(270, 43); + this.put(280, 36); + this.put(290, 18); + this.put(300, 33); + this.put(310, 20); + this.put(320, 18); + this.put(330, 32); + this.put(340, 19); + this.put(350, 23); + this.put(360, 27); + this.put(370, 22); + this.put(380, 17); + this.put(390, 19); + this.put(400, 9); + this.put(410, 13); + this.put(420, 12); + this.put(430, 19); + this.put(440, 16); + this.put(450, 12); + this.put(460, 10); + this.put(470, 8); + this.put(480, 5); + this.put(490, 6); + this.put(500, 7); + this.put(510, 9); + this.put(520, 9); + this.put(530, 7); + this.put(540, 12); + this.put(550, 9); + this.put(560, 8); + this.put(570, 11); + this.put(580, 4); + this.put(590, 3); + this.put(600, 12); + this.put(610, 9); + this.put(620, 5); + this.put(630, 7); + this.put(640, 5); + this.put(650, 5); + this.put(660, 4); + this.put(670, 5); + this.put(680, 2); + this.put(690, 2); + this.put(700, 4); + this.put(710, 5); + this.put(720, 4); + this.put(730, 6); + this.put(740, 7); + this.put(750, 5); + this.put(760, 2); + this.put(770, 1); + this.put(780, 2); + this.put(800, 4); + this.put(810, 1); + this.put(820, 1); + this.put(830, 1); + this.put(840, 6); + this.put(850, 3); + this.put(860, 4); + this.put(870, 1); + this.put(880, 2); + this.put(890, 4); + this.put(900, 2); + this.put(910, 2); + this.put(920, 2); + this.put(930, 1); + this.put(940, 3); + this.put(950, 6); + this.put(960, 4); + this.put(970, 1); + this.put(980, 3); + this.put(990, 2); + this.put(1000, 1); } - }; + }; - /** - * The histogram of the PAGE_NAMESPACE column - */ - public static final Histogram NAMESPACE = new Histogram() { + /** The histogram of the PAGE_NAMESPACE column */ + public static final Histogram NAMESPACE = + new Histogram() { { - this.put(0, 40847); - this.put(1, 15304); - this.put(2, 4718); - this.put(3, 23563); - this.put(4, 2562); - this.put(5, 268); - this.put(6, 6991); - this.put(7, 330); - this.put(8, 9); - this.put(9, 6); - this.put(10, 1187); - this.put(11, 263); - this.put(12, 3); - this.put(13, 2); - this.put(14, 2831); - this.put(15, 694); - this.put(100, 393); - this.put(101, 29); + this.put(0, 40847); + this.put(1, 15304); + this.put(2, 4718); + this.put(3, 23563); + this.put(4, 2562); + this.put(5, 268); + this.put(6, 6991); + this.put(7, 330); + this.put(8, 9); + this.put(9, 6); + this.put(10, 1187); + this.put(11, 263); + this.put(12, 3); + this.put(13, 2); + this.put(14, 2831); + this.put(15, 694); + this.put(100, 393); + this.put(101, 29); } - }; + }; - /** - * The histogram of the PAGE_RESTRICTIONS column - */ - public static final Histogram RESTRICTIONS = new Histogram() { + /** The histogram of the PAGE_RESTRICTIONS column */ + public static final Histogram RESTRICTIONS = + new Histogram() { { - // HACK: Normally MediaWiki just uses an empty field if there are no restrictions. - // But Oracle handles "" as NULL, so we need to make sure that our - // restrictions are never empty. - this.put("none", 99917); // HACK for Oracle - this.put("edit=autoconfirmed:move=autoconfirmed", 20); - this.put("edit=autoconfirmed:move=sysop", 8); - this.put("edit=sysop:move=sysop", 23); - this.put("move=:edit=", 24); - this.put("move=sysop", 1); - this.put("move=sysop:edit=sysop", 5); - this.put("sysop", 2); + // HACK: Normally MediaWiki just uses an empty field if there are no restrictions. + // But Oracle handles "" as NULL, so we need to make sure that our + // restrictions are never empty. + this.put("none", 99917); // HACK for Oracle + this.put("edit=autoconfirmed:move=autoconfirmed", 20); + this.put("edit=autoconfirmed:move=sysop", 8); + this.put("edit=sysop:move=sysop", 23); + this.put("move=:edit=", 24); + this.put("move=sysop", 1); + this.put("move=sysop:edit=sysop", 5); + this.put("sysop", 2); } - }; - + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java index 9712a51ef..c1caaed04 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/RevisionHistograms.java @@ -21,1321 +21,1313 @@ public abstract class RevisionHistograms { - /** - * The length of the REV_COMMENT column - */ - public static final Histogram COMMENT_LENGTH = new Histogram() { + /** The length of the REV_COMMENT column */ + public static final Histogram COMMENT_LENGTH = + new Histogram() { { - this.put(0, 369676); - this.put(1, 2349); - this.put(2, 6499); - this.put(3, 15283); - this.put(4, 12587); - this.put(5, 9478); - this.put(6, 8950); - this.put(7, 15733); - this.put(8, 17814); - this.put(9, 13030); - this.put(10, 20114); - this.put(11, 23820); - this.put(12, 37709); - this.put(13, 33519); - this.put(14, 32407); - this.put(15, 28522); - this.put(16, 32136); - this.put(17, 28346); - this.put(18, 23220); - this.put(19, 26814); - this.put(20, 44981); - this.put(21, 22521); - this.put(22, 21283); - this.put(23, 20584); - this.put(24, 20573); - this.put(25, 20744); - this.put(26, 21000); - this.put(27, 16677); - this.put(28, 18865); - this.put(29, 17696); - this.put(30, 15825); - this.put(31, 17675); - this.put(32, 14153); - this.put(33, 16588); - this.put(34, 14771); - this.put(35, 14556); - this.put(36, 14078); - this.put(37, 11642); - this.put(38, 11149); - this.put(39, 10627); - this.put(40, 10310); - this.put(41, 8686); - this.put(42, 11333); - this.put(43, 8712); - this.put(44, 8030); - this.put(45, 8106); - this.put(46, 7814); - this.put(47, 8776); - this.put(48, 7439); - this.put(49, 6503); - this.put(50, 6323); - this.put(51, 5874); - this.put(52, 6472); - this.put(53, 6024); - this.put(54, 7171); - this.put(55, 5338); - this.put(56, 6252); - this.put(57, 5208); - this.put(58, 5260); - this.put(59, 4390); - this.put(60, 4723); - this.put(61, 4467); - this.put(62, 5498); - this.put(63, 4129); - this.put(64, 3989); - this.put(65, 3594); - this.put(66, 4851); - this.put(67, 3588); - this.put(68, 3825); - this.put(69, 3705); - this.put(70, 3212); - this.put(71, 3124); - this.put(72, 3775); - this.put(73, 2853); - this.put(74, 2969); - this.put(75, 2785); - this.put(76, 2796); - this.put(77, 3964); - this.put(78, 2514); - this.put(79, 2493); - this.put(80, 2955); - this.put(81, 3000); - this.put(82, 2916); - this.put(83, 2223); - this.put(84, 2247); - this.put(85, 2489); - this.put(86, 1892); - this.put(87, 2705); - this.put(88, 3226); - this.put(89, 1994); - this.put(90, 1852); - this.put(91, 2070); - this.put(92, 2066); - this.put(93, 2371); - this.put(94, 1961); - this.put(95, 1803); - this.put(96, 2305); - this.put(97, 1812); - this.put(98, 2145); - this.put(99, 2203); - this.put(100, 1837); - this.put(101, 1799); - this.put(102, 1726); - this.put(103, 1730); - this.put(104, 1890); - this.put(105, 1688); - this.put(106, 1478); - this.put(107, 1659); - this.put(108, 1396); - this.put(109, 2088); - this.put(110, 1772); - this.put(111, 1158); - this.put(112, 1234); - this.put(113, 1756); - this.put(114, 1417); - this.put(115, 1173); - this.put(116, 1480); - this.put(117, 1447); - this.put(118, 1640); - this.put(119, 1910); - this.put(120, 1851); - this.put(121, 1699); - this.put(122, 1994); - this.put(123, 1464); - this.put(124, 1504); - this.put(125, 3023); - this.put(126, 1779); - this.put(127, 1572); - this.put(128, 3420); - this.put(129, 1463); - this.put(130, 1637); - this.put(131, 2772); - this.put(132, 1751); - this.put(133, 2315); - this.put(134, 2190); - this.put(135, 1690); - this.put(136, 1889); - this.put(137, 2412); - this.put(138, 1839); - this.put(139, 1665); - this.put(140, 1512); - this.put(141, 1267); - this.put(142, 1543); - this.put(143, 1057); - this.put(144, 961); - this.put(145, 1019); - this.put(146, 835); - this.put(147, 835); - this.put(148, 914); - this.put(149, 726); - this.put(150, 688); - this.put(151, 598); - this.put(152, 786); - this.put(153, 610); - this.put(154, 702); - this.put(155, 925); - this.put(156, 739); - this.put(157, 804); - this.put(158, 578); - this.put(159, 531); - this.put(160, 555); - this.put(161, 629); - this.put(162, 532); - this.put(163, 543); - this.put(164, 548); - this.put(165, 568); - this.put(166, 616); - this.put(167, 503); - this.put(168, 596); - this.put(169, 535); - this.put(170, 614); - this.put(171, 538); - this.put(172, 479); - this.put(173, 513); - this.put(174, 613); - this.put(175, 447); - this.put(176, 488); - this.put(177, 436); - this.put(178, 497); - this.put(179, 438); - this.put(180, 490); - this.put(181, 385); - this.put(182, 440); - this.put(183, 409); - this.put(184, 509); - this.put(185, 343); - this.put(186, 483); - this.put(187, 405); - this.put(188, 401); - this.put(189, 362); - this.put(190, 462); - this.put(191, 336); - this.put(192, 433); - this.put(193, 423); - this.put(194, 345); - this.put(195, 439); - this.put(196, 393); - this.put(197, 580); - this.put(198, 581); - this.put(199, 5151); - this.put(200, 1201); - this.put(201, 64); - this.put(202, 56); - this.put(203, 56); - this.put(204, 43); - this.put(205, 35); - this.put(206, 41); - this.put(207, 62); - this.put(208, 66); - this.put(209, 68); - this.put(210, 82); - this.put(211, 78); - this.put(212, 50); - this.put(213, 63); - this.put(214, 59); - this.put(215, 76); - this.put(216, 76); - this.put(217, 43); - this.put(218, 38); - this.put(219, 27); - this.put(220, 36); - this.put(221, 35); - this.put(222, 37); - this.put(223, 45); - this.put(224, 32); - this.put(225, 40); - this.put(226, 30); - this.put(227, 27); - this.put(228, 16); - this.put(229, 17); - this.put(230, 18); - this.put(231, 18); - this.put(232, 11); - this.put(233, 11); - this.put(234, 21); - this.put(235, 12); - this.put(236, 11); - this.put(237, 14); - this.put(238, 10); - this.put(239, 19); - this.put(240, 11); - this.put(241, 14); - this.put(242, 8); - this.put(243, 55); - this.put(244, 19); - this.put(245, 36); - this.put(246, 35); - this.put(247, 53); - this.put(248, 96); - this.put(249, 101); - this.put(250, 173); - this.put(251, 138); - this.put(252, 110); - this.put(253, 135); - this.put(254, 34); - this.put(255, 232); + this.put(0, 369676); + this.put(1, 2349); + this.put(2, 6499); + this.put(3, 15283); + this.put(4, 12587); + this.put(5, 9478); + this.put(6, 8950); + this.put(7, 15733); + this.put(8, 17814); + this.put(9, 13030); + this.put(10, 20114); + this.put(11, 23820); + this.put(12, 37709); + this.put(13, 33519); + this.put(14, 32407); + this.put(15, 28522); + this.put(16, 32136); + this.put(17, 28346); + this.put(18, 23220); + this.put(19, 26814); + this.put(20, 44981); + this.put(21, 22521); + this.put(22, 21283); + this.put(23, 20584); + this.put(24, 20573); + this.put(25, 20744); + this.put(26, 21000); + this.put(27, 16677); + this.put(28, 18865); + this.put(29, 17696); + this.put(30, 15825); + this.put(31, 17675); + this.put(32, 14153); + this.put(33, 16588); + this.put(34, 14771); + this.put(35, 14556); + this.put(36, 14078); + this.put(37, 11642); + this.put(38, 11149); + this.put(39, 10627); + this.put(40, 10310); + this.put(41, 8686); + this.put(42, 11333); + this.put(43, 8712); + this.put(44, 8030); + this.put(45, 8106); + this.put(46, 7814); + this.put(47, 8776); + this.put(48, 7439); + this.put(49, 6503); + this.put(50, 6323); + this.put(51, 5874); + this.put(52, 6472); + this.put(53, 6024); + this.put(54, 7171); + this.put(55, 5338); + this.put(56, 6252); + this.put(57, 5208); + this.put(58, 5260); + this.put(59, 4390); + this.put(60, 4723); + this.put(61, 4467); + this.put(62, 5498); + this.put(63, 4129); + this.put(64, 3989); + this.put(65, 3594); + this.put(66, 4851); + this.put(67, 3588); + this.put(68, 3825); + this.put(69, 3705); + this.put(70, 3212); + this.put(71, 3124); + this.put(72, 3775); + this.put(73, 2853); + this.put(74, 2969); + this.put(75, 2785); + this.put(76, 2796); + this.put(77, 3964); + this.put(78, 2514); + this.put(79, 2493); + this.put(80, 2955); + this.put(81, 3000); + this.put(82, 2916); + this.put(83, 2223); + this.put(84, 2247); + this.put(85, 2489); + this.put(86, 1892); + this.put(87, 2705); + this.put(88, 3226); + this.put(89, 1994); + this.put(90, 1852); + this.put(91, 2070); + this.put(92, 2066); + this.put(93, 2371); + this.put(94, 1961); + this.put(95, 1803); + this.put(96, 2305); + this.put(97, 1812); + this.put(98, 2145); + this.put(99, 2203); + this.put(100, 1837); + this.put(101, 1799); + this.put(102, 1726); + this.put(103, 1730); + this.put(104, 1890); + this.put(105, 1688); + this.put(106, 1478); + this.put(107, 1659); + this.put(108, 1396); + this.put(109, 2088); + this.put(110, 1772); + this.put(111, 1158); + this.put(112, 1234); + this.put(113, 1756); + this.put(114, 1417); + this.put(115, 1173); + this.put(116, 1480); + this.put(117, 1447); + this.put(118, 1640); + this.put(119, 1910); + this.put(120, 1851); + this.put(121, 1699); + this.put(122, 1994); + this.put(123, 1464); + this.put(124, 1504); + this.put(125, 3023); + this.put(126, 1779); + this.put(127, 1572); + this.put(128, 3420); + this.put(129, 1463); + this.put(130, 1637); + this.put(131, 2772); + this.put(132, 1751); + this.put(133, 2315); + this.put(134, 2190); + this.put(135, 1690); + this.put(136, 1889); + this.put(137, 2412); + this.put(138, 1839); + this.put(139, 1665); + this.put(140, 1512); + this.put(141, 1267); + this.put(142, 1543); + this.put(143, 1057); + this.put(144, 961); + this.put(145, 1019); + this.put(146, 835); + this.put(147, 835); + this.put(148, 914); + this.put(149, 726); + this.put(150, 688); + this.put(151, 598); + this.put(152, 786); + this.put(153, 610); + this.put(154, 702); + this.put(155, 925); + this.put(156, 739); + this.put(157, 804); + this.put(158, 578); + this.put(159, 531); + this.put(160, 555); + this.put(161, 629); + this.put(162, 532); + this.put(163, 543); + this.put(164, 548); + this.put(165, 568); + this.put(166, 616); + this.put(167, 503); + this.put(168, 596); + this.put(169, 535); + this.put(170, 614); + this.put(171, 538); + this.put(172, 479); + this.put(173, 513); + this.put(174, 613); + this.put(175, 447); + this.put(176, 488); + this.put(177, 436); + this.put(178, 497); + this.put(179, 438); + this.put(180, 490); + this.put(181, 385); + this.put(182, 440); + this.put(183, 409); + this.put(184, 509); + this.put(185, 343); + this.put(186, 483); + this.put(187, 405); + this.put(188, 401); + this.put(189, 362); + this.put(190, 462); + this.put(191, 336); + this.put(192, 433); + this.put(193, 423); + this.put(194, 345); + this.put(195, 439); + this.put(196, 393); + this.put(197, 580); + this.put(198, 581); + this.put(199, 5151); + this.put(200, 1201); + this.put(201, 64); + this.put(202, 56); + this.put(203, 56); + this.put(204, 43); + this.put(205, 35); + this.put(206, 41); + this.put(207, 62); + this.put(208, 66); + this.put(209, 68); + this.put(210, 82); + this.put(211, 78); + this.put(212, 50); + this.put(213, 63); + this.put(214, 59); + this.put(215, 76); + this.put(216, 76); + this.put(217, 43); + this.put(218, 38); + this.put(219, 27); + this.put(220, 36); + this.put(221, 35); + this.put(222, 37); + this.put(223, 45); + this.put(224, 32); + this.put(225, 40); + this.put(226, 30); + this.put(227, 27); + this.put(228, 16); + this.put(229, 17); + this.put(230, 18); + this.put(231, 18); + this.put(232, 11); + this.put(233, 11); + this.put(234, 21); + this.put(235, 12); + this.put(236, 11); + this.put(237, 14); + this.put(238, 10); + this.put(239, 19); + this.put(240, 11); + this.put(241, 14); + this.put(242, 8); + this.put(243, 55); + this.put(244, 19); + this.put(245, 36); + this.put(246, 35); + this.put(247, 53); + this.put(248, 96); + this.put(249, 101); + this.put(250, 173); + this.put(251, 138); + this.put(252, 110); + this.put(253, 135); + this.put(254, 34); + this.put(255, 232); } - }; + }; - /** - * - */ - public static final int[] REVISION_DELTA_SIZES = {1000, 10000, 100000}; + /** */ + public static final int[] REVISION_DELTA_SIZES = {1000, 10000, 100000}; - /** - * Simple generic class overload to avoid some cast warnings below. - */ - public static class IntHistogram extends Histogram { - private static final long serialVersionUID = 0L; - } + /** Simple generic class overload to avoid some cast warnings below. */ + public static class IntHistogram extends Histogram { + private static final long serialVersionUID = 0L; + } - /** - * - */ - public static final IntHistogram[] REVISION_DELTAS = new IntHistogram[]{ - new IntHistogram() { - { - this.put(-1000, 237); - this.put(-900, 237); - this.put(-800, 252); - this.put(-700, 357); - this.put(-600, 411); - this.put(-500, 538); - this.put(-400, 726); - this.put(-300, 1058); - this.put(-200, 1795); - this.put(-100, 7579); - this.put(0, 121517); - this.put(100, 40064); - this.put(200, 11512); - this.put(300, 7300); - this.put(400, 4931); - this.put(500, 3367); - this.put(600, 2592); - this.put(700, 1957); - this.put(800, 1495); - this.put(900, 1169); - this.put(1000, 1210); - this.put(1100, 750); - this.put(1200, 545); - this.put(1300, 570); - this.put(1400, 657); - this.put(1500, 461); - this.put(1600, 348); - this.put(1700, 635); - this.put(1800, 421); - this.put(1900, 233); - this.put(2000, 243); - this.put(2100, 193); - this.put(2200, 167); - this.put(2300, 159); - this.put(2400, 148); - this.put(2500, 123); - this.put(2600, 96); - this.put(2700, 124); - this.put(2800, 106); - this.put(2900, 93); - this.put(3000, 66); - this.put(3100, 91); - this.put(3200, 93); - this.put(3300, 74); - this.put(3400, 90); - this.put(3500, 67); - this.put(3600, 76); - this.put(3700, 59); - this.put(3800, 53); - this.put(3900, 69); - this.put(4000, 68); - this.put(4100, 59); - this.put(4200, 47); - this.put(4300, 44); - this.put(4400, 55); - this.put(4500, 37); - this.put(4600, 39); - this.put(4700, 56); - this.put(4800, 41); - this.put(4900, 46); - this.put(5000, 47); - this.put(5100, 39); - this.put(5200, 39); - this.put(5300, 43); - this.put(5400, 54); - this.put(5500, 41); - this.put(5600, 17); - this.put(5700, 37); - this.put(5800, 31); - this.put(5900, 30); - this.put(6000, 39); - this.put(6100, 29); - this.put(6200, 40); - this.put(6300, 36); - this.put(6400, 42); - this.put(6500, 39); - this.put(6600, 28); - this.put(6700, 38); - this.put(6800, 34); - this.put(6900, 23); - this.put(7000, 25); - this.put(7100, 32); - this.put(7200, 19); - this.put(7300, 21); - this.put(7400, 23); - this.put(7500, 26); - this.put(7600, 24); - this.put(7700, 18); - this.put(7800, 19); - this.put(7900, 30); - this.put(8000, 21); - this.put(8100, 21); - this.put(8200, 21); - this.put(8300, 13); - this.put(8400, 18); - this.put(8500, 14); - this.put(8600, 19); - this.put(8700, 21); - this.put(8800, 14); - this.put(8900, 19); - this.put(9000, 25); - this.put(9100, 12); - this.put(9200, 16); - this.put(9300, 13); - this.put(9400, 21); - this.put(9500, 18); - this.put(9600, 25); - this.put(9700, 17); - this.put(9800, 15); - this.put(9900, 21); - this.put(10000, 151); - this.put(11000, 143); - this.put(12000, 122); - this.put(13000, 97); - this.put(14000, 103); - this.put(15000, 135); - this.put(16000, 84); - this.put(17000, 63); - this.put(18000, 92); - this.put(19000, 81); - this.put(20000, 98); - this.put(21000, 133); - this.put(22000, 67); - this.put(23000, 63); - this.put(24000, 66); - this.put(25000, 53); - this.put(26000, 85); - this.put(27000, 67); - this.put(28000, 90); - this.put(29000, 60); - this.put(30000, 48); - this.put(31000, 34); - this.put(32000, 35); - this.put(33000, 59); - this.put(34000, 40); - this.put(35000, 56); - this.put(36000, 68); - this.put(37000, 40); - this.put(38000, 37); - this.put(39000, 33); - this.put(40000, 34); - this.put(41000, 28); - this.put(42000, 35); - this.put(43000, 37); - this.put(44000, 34); - this.put(45000, 55); - this.put(46000, 30); - this.put(47000, 34); - this.put(48000, 30); - this.put(49000, 15); - this.put(50000, 14); - this.put(51000, 40); - this.put(52000, 16); - this.put(53000, 36); - this.put(54000, 19); - this.put(55000, 17); - this.put(56000, 20); - this.put(57000, 24); - this.put(58000, 29); - this.put(59000, 36); - this.put(60000, 34); - this.put(61000, 26); - this.put(62000, 20); - this.put(63000, 14); - this.put(64000, 12); - this.put(65000, 17); - this.put(66000, 8); - this.put(67000, 20); - this.put(68000, 17); - this.put(69000, 20); - this.put(70000, 11); - this.put(71000, 8); - this.put(72000, 5); - this.put(73000, 11); - this.put(74000, 20); - this.put(75000, 8); - this.put(76000, 8); - this.put(77000, 29); - this.put(78000, 5); - this.put(79000, 4); - this.put(80000, 7); - this.put(81000, 5); - this.put(82000, 8); - this.put(83000, 4); - this.put(84000, 5); - this.put(85000, 5); - this.put(86000, 10); - this.put(87000, 8); - this.put(88000, 7); - this.put(90000, 1); - this.put(91000, 5); - this.put(92000, 4); - this.put(93000, 16); - this.put(94000, 11); - this.put(95000, 3); - this.put(96000, 5); - this.put(97000, 6); - this.put(98000, 2); - this.put(99000, 5); - this.put(100000, 4); - } - }, - new IntHistogram() { - { - this.put(-10000, 15); - this.put(-9900, 19); - this.put(-9800, 20); - this.put(-9700, 17); - this.put(-9600, 25); - this.put(-9500, 19); - this.put(-9400, 21); - this.put(-9300, 18); - this.put(-9200, 20); - this.put(-9100, 14); - this.put(-9000, 28); - this.put(-8900, 19); - this.put(-8800, 16); - this.put(-8700, 17); - this.put(-8600, 21); - this.put(-8500, 15); - this.put(-8400, 17); - this.put(-8300, 21); - this.put(-8200, 28); - this.put(-8100, 24); - this.put(-8000, 23); - this.put(-7900, 37); - this.put(-7800, 24); - this.put(-7700, 27); - this.put(-7600, 34); - this.put(-7500, 33); - this.put(-7400, 22); - this.put(-7300, 24); - this.put(-7200, 30); - this.put(-7100, 40); - this.put(-7000, 40); - this.put(-6900, 38); - this.put(-6800, 50); - this.put(-6700, 36); - this.put(-6600, 38); - this.put(-6500, 44); - this.put(-6400, 31); - this.put(-6300, 41); - this.put(-6200, 38); - this.put(-6100, 31); - this.put(-6000, 40); - this.put(-5900, 45); - this.put(-5800, 43); - this.put(-5700, 54); - this.put(-5600, 37); - this.put(-5500, 58); - this.put(-5400, 57); - this.put(-5300, 65); - this.put(-5200, 75); - this.put(-5100, 67); - this.put(-5000, 58); - this.put(-4900, 63); - this.put(-4800, 69); - this.put(-4700, 73); - this.put(-4600, 60); - this.put(-4500, 59); - this.put(-4400, 76); - this.put(-4300, 76); - this.put(-4200, 72); - this.put(-4100, 87); - this.put(-4000, 92); - this.put(-3900, 101); - this.put(-3800, 97); - this.put(-3700, 74); - this.put(-3600, 117); - this.put(-3500, 100); - this.put(-3400, 124); - this.put(-3300, 112); - this.put(-3200, 128); - this.put(-3100, 141); - this.put(-3000, 152); - this.put(-2900, 134); - this.put(-2800, 156); - this.put(-2700, 155); - this.put(-2600, 148); - this.put(-2500, 194); - this.put(-2400, 198); - this.put(-2300, 224); - this.put(-2200, 257); - this.put(-2100, 280); - this.put(-2000, 325); - this.put(-1900, 318); - this.put(-1800, 385); - this.put(-1700, 367); - this.put(-1600, 436); - this.put(-1500, 483); - this.put(-1400, 506); - this.put(-1300, 586); - this.put(-1200, 643); - this.put(-1100, 791); - this.put(-1000, 650); - this.put(-900, 721); - this.put(-800, 909); - this.put(-700, 1148); - this.put(-600, 1363); - this.put(-500, 1819); - this.put(-400, 2635); - this.put(-300, 4395); - this.put(-200, 8706); - this.put(-100, 36354); - this.put(0, 344441); - this.put(100, 110948); - this.put(200, 33273); - this.put(300, 18915); - this.put(400, 11943); - this.put(500, 8587); - this.put(600, 6339); - this.put(700, 4763); - this.put(800, 3813); - this.put(900, 2773); - this.put(1000, 2302); - this.put(1100, 1802); - this.put(1200, 1445); - this.put(1300, 1397); - this.put(1400, 1644); - this.put(1500, 1156); - this.put(1600, 728); - this.put(1700, 801); - this.put(1800, 605); - this.put(1900, 485); - this.put(2000, 504); - this.put(2100, 432); - this.put(2200, 324); - this.put(2300, 288); - this.put(2400, 301); - this.put(2500, 312); - this.put(2600, 201); - this.put(2700, 171); - this.put(2800, 134); - this.put(2900, 148); - this.put(3000, 157); - this.put(3100, 126); - this.put(3200, 117); - this.put(3300, 103); - this.put(3400, 112); - this.put(3500, 97); - this.put(3600, 93); - this.put(3700, 77); - this.put(3800, 69); - this.put(3900, 55); - this.put(4000, 86); - this.put(4100, 65); - this.put(4200, 68); - this.put(4300, 74); - this.put(4400, 39); - this.put(4500, 44); - this.put(4600, 51); - this.put(4700, 46); - this.put(4800, 48); - this.put(4900, 41); - this.put(5000, 38); - this.put(5100, 33); - this.put(5200, 59); - this.put(5300, 39); - this.put(5400, 23); - this.put(5500, 39); - this.put(5600, 37); - this.put(5700, 30); - this.put(5800, 34); - this.put(5900, 28); - this.put(6000, 16); - this.put(6100, 25); - this.put(6200, 25); - this.put(6300, 33); - this.put(6400, 23); - this.put(6500, 27); - this.put(6600, 19); - this.put(6700, 27); - this.put(6800, 26); - this.put(6900, 20); - this.put(7000, 19); - this.put(7100, 16); - this.put(7200, 13); - this.put(7300, 10); - this.put(7400, 17); - this.put(7500, 13); - this.put(7600, 18); - this.put(7700, 25); - this.put(7800, 19); - this.put(7900, 8); - this.put(8000, 13); - this.put(8100, 10); - this.put(8200, 12); - this.put(8300, 7); - this.put(8400, 8); - this.put(8500, 8); - this.put(8600, 12); - this.put(8700, 8); - this.put(8800, 9); - this.put(8900, 9); - this.put(9000, 13); - this.put(9100, 4); - this.put(9200, 10); - this.put(9300, 14); - this.put(9400, 13); - this.put(9500, 11); - this.put(9600, 10); - this.put(9700, 5); - this.put(9800, 9); - this.put(9900, 8); - this.put(10000, 63); - this.put(11000, 57); - this.put(12000, 43); - this.put(13000, 45); - this.put(14000, 43); - this.put(15000, 23); - this.put(16000, 26); - this.put(17000, 29); - this.put(18000, 21); - this.put(19000, 20); - this.put(20000, 20); - this.put(21000, 13); - this.put(22000, 21); - this.put(23000, 18); - this.put(24000, 10); - this.put(25000, 10); - this.put(26000, 13); - this.put(27000, 12); - this.put(28000, 13); - this.put(29000, 6); - this.put(30000, 6); - this.put(31000, 11); - this.put(32000, 9); - this.put(33000, 8); - this.put(34000, 8); - this.put(35000, 4); - this.put(36000, 4); - this.put(37000, 1); - this.put(38000, 5); - this.put(39000, 3); - this.put(40000, 3); - this.put(41000, 2); - this.put(42000, 2); - this.put(43000, 6); - this.put(44000, 4); - this.put(45000, 9); - this.put(46000, 6); - this.put(47000, 5); - this.put(48000, 5); - this.put(49000, 5); - this.put(50000, 3); - this.put(51000, 5); - this.put(52000, 4); - this.put(53000, 6); - this.put(54000, 2); - this.put(55000, 1); - this.put(56000, 3); - this.put(57000, 2); - this.put(60000, 2); - this.put(61000, 5); - this.put(63000, 2); - this.put(65000, 1); - this.put(68000, 3); - this.put(69000, 1); - this.put(70000, 1); - this.put(71000, 1); - this.put(72000, 1); - this.put(73000, 4); - this.put(75000, 3); - this.put(76000, 1); - this.put(77000, 2); - this.put(78000, 1); - this.put(80000, 1); - this.put(81000, 5); - this.put(82000, 1); - this.put(83000, 1); - this.put(84000, 2); - this.put(88000, 2); - this.put(91000, 1); - this.put(93000, 3); - this.put(97000, 2); - this.put(99000, 4); - this.put(100000, 1); - } - }, - new IntHistogram() { - { - this.put(-985000, 1); - this.put(-982000, 1); - this.put(-950000, 1); - this.put(-944000, 1); - this.put(-852000, 1); - this.put(-801000, 1); - this.put(-800000, 1); - this.put(-749000, 1); - this.put(-719000, 1); - this.put(-711000, 1); - this.put(-696000, 1); - this.put(-687000, 2); - this.put(-683000, 1); - this.put(-681000, 1); - this.put(-667000, 1); - this.put(-644000, 1); - this.put(-643000, 1); - this.put(-642000, 1); - this.put(-634000, 1); - this.put(-596000, 1); - this.put(-512000, 1); - this.put(-486000, 2); - this.put(-481000, 1); - this.put(-450000, 1); - this.put(-445000, 3); - this.put(-433000, 1); - this.put(-418000, 1); - this.put(-391000, 1); - this.put(-386000, 1); - this.put(-382000, 2); - this.put(-376000, 1); - this.put(-364000, 1); - this.put(-359000, 2); - this.put(-357000, 1); - this.put(-344000, 1); - this.put(-332000, 1); - this.put(-331000, 1); - this.put(-328000, 1); - this.put(-327000, 1); - this.put(-326000, 1); - this.put(-323000, 1); - this.put(-319000, 3); - this.put(-317000, 1); - this.put(-312000, 2); - this.put(-300000, 1); - this.put(-299000, 1); - this.put(-295000, 1); - this.put(-292000, 1); - this.put(-289000, 1); - this.put(-284000, 1); - this.put(-275000, 1); - this.put(-273000, 2); - this.put(-269000, 1); - this.put(-261000, 1); - this.put(-260000, 1); - this.put(-258000, 1); - this.put(-256000, 5); - this.put(-252000, 1); - this.put(-251000, 2); - this.put(-250000, 1); - this.put(-249000, 1); - this.put(-248000, 1); - this.put(-247000, 2); - this.put(-246000, 2); - this.put(-245000, 2); - this.put(-239000, 4); - this.put(-232000, 2); - this.put(-229000, 1); - this.put(-227000, 1); - this.put(-224000, 2); - this.put(-219000, 1); - this.put(-218000, 1); - this.put(-217000, 3); - this.put(-216000, 2); - this.put(-214000, 2); - this.put(-213000, 1); - this.put(-209000, 1); - this.put(-208000, 2); - this.put(-207000, 1); - this.put(-205000, 2); - this.put(-203000, 2); - this.put(-201000, 9); - this.put(-200000, 3); - this.put(-199000, 1); - this.put(-197000, 1); - this.put(-192000, 1); - this.put(-191000, 3); - this.put(-190000, 3); - this.put(-189000, 1); - this.put(-188000, 1); - this.put(-187000, 1); - this.put(-186000, 1); - this.put(-185000, 2); - this.put(-184000, 6); - this.put(-183000, 5); - this.put(-181000, 3); - this.put(-180000, 1); - this.put(-176000, 1); - this.put(-175000, 1); - this.put(-174000, 3); - this.put(-173000, 1); - this.put(-172000, 4); - this.put(-171000, 4); - this.put(-170000, 1); - this.put(-169000, 2); - this.put(-167000, 3); - this.put(-166000, 1); - this.put(-165000, 1); - this.put(-164000, 6); - this.put(-163000, 1); - this.put(-162000, 6); - this.put(-161000, 12); - this.put(-160000, 5); - this.put(-159000, 1); - this.put(-158000, 3); - this.put(-157000, 2); - this.put(-156000, 2); - this.put(-155000, 1); - this.put(-154000, 6); - this.put(-153000, 5); - this.put(-152000, 2); - this.put(-151000, 3); - this.put(-150000, 2); - this.put(-149000, 1); - this.put(-148000, 1); - this.put(-147000, 1); - this.put(-146000, 4); - this.put(-144000, 1); - this.put(-143000, 3); - this.put(-142000, 2); - this.put(-141000, 2); - this.put(-140000, 6); - this.put(-139000, 5); - this.put(-138000, 4); - this.put(-137000, 4); - this.put(-136000, 7); - this.put(-134000, 10); - this.put(-133000, 4); - this.put(-132000, 1); - this.put(-131000, 3); - this.put(-128000, 2); - this.put(-127000, 7); - this.put(-126000, 4); - this.put(-124000, 1); - this.put(-122000, 7); - this.put(-121000, 3); - this.put(-120000, 2); - this.put(-119000, 2); - this.put(-118000, 4); - this.put(-117000, 3); - this.put(-116000, 3); - this.put(-115000, 3); - this.put(-114000, 2); - this.put(-113000, 4); - this.put(-112000, 4); - this.put(-111000, 4); - this.put(-110000, 3); - this.put(-109000, 3); - this.put(-108000, 2); - this.put(-107000, 3); - this.put(-106000, 6); - this.put(-105000, 3); - this.put(-104000, 2); - this.put(-103000, 3); - this.put(-102000, 3); - this.put(-101000, 6); - this.put(-100000, 10); - this.put(-99000, 2); - this.put(-98000, 10); - this.put(-97000, 5); - this.put(-96000, 6); - this.put(-95000, 14); - this.put(-94000, 19); - this.put(-93000, 12); - this.put(-92000, 9); - this.put(-91000, 4); - this.put(-90000, 2); - this.put(-89000, 11); - this.put(-88000, 7); - this.put(-87000, 12); - this.put(-86000, 7); - this.put(-85000, 8); - this.put(-84000, 13); - this.put(-83000, 17); - this.put(-82000, 15); - this.put(-81000, 15); - this.put(-80000, 6); - this.put(-79000, 10); - this.put(-78000, 30); - this.put(-77000, 18); - this.put(-76000, 13); - this.put(-75000, 20); - this.put(-74000, 14); - this.put(-73000, 12); - this.put(-72000, 9); - this.put(-71000, 12); - this.put(-70000, 24); - this.put(-69000, 28); - this.put(-68000, 22); - this.put(-67000, 17); - this.put(-66000, 17); - this.put(-65000, 17); - this.put(-64000, 13); - this.put(-63000, 29); - this.put(-62000, 38); - this.put(-61000, 35); - this.put(-60000, 39); - this.put(-59000, 33); - this.put(-58000, 32); - this.put(-57000, 22); - this.put(-56000, 26); - this.put(-55000, 20); - this.put(-54000, 53); - this.put(-53000, 23); - this.put(-52000, 47); - this.put(-51000, 34); - this.put(-50000, 24); - this.put(-49000, 40); - this.put(-48000, 52); - this.put(-47000, 38); - this.put(-46000, 67); - this.put(-45000, 51); - this.put(-44000, 41); - this.put(-43000, 51); - this.put(-42000, 47); - this.put(-41000, 49); - this.put(-40000, 45); - this.put(-39000, 54); - this.put(-38000, 62); - this.put(-37000, 83); - this.put(-36000, 85); - this.put(-35000, 66); - this.put(-34000, 71); - this.put(-33000, 64); - this.put(-32000, 56); - this.put(-31000, 79); - this.put(-30000, 77); - this.put(-29000, 119); - this.put(-28000, 129); - this.put(-27000, 110); - this.put(-26000, 91); - this.put(-25000, 99); - this.put(-24000, 116); - this.put(-23000, 136); - this.put(-22000, 167); - this.put(-21000, 160); - this.put(-20000, 137); - this.put(-19000, 156); - this.put(-18000, 129); - this.put(-17000, 159); - this.put(-16000, 216); - this.put(-15000, 226); - this.put(-14000, 197); - this.put(-13000, 278); - this.put(-12000, 308); - this.put(-11000, 336); - this.put(-10000, 17); - this.put(-9900, 24); - this.put(-9800, 19); - this.put(-9700, 15); - this.put(-9600, 25); - this.put(-9500, 25); - this.put(-9400, 33); - this.put(-9300, 20); - this.put(-9200, 23); - this.put(-9100, 29); - this.put(-9000, 30); - this.put(-8900, 25); - this.put(-8800, 27); - this.put(-8700, 23); - this.put(-8600, 26); - this.put(-8500, 29); - this.put(-8400, 26); - this.put(-8300, 24); - this.put(-8200, 28); - this.put(-8100, 33); - this.put(-8000, 21); - this.put(-7900, 23); - this.put(-7800, 33); - this.put(-7700, 25); - this.put(-7600, 27); - this.put(-7500, 35); - this.put(-7400, 28); - this.put(-7300, 28); - this.put(-7200, 32); - this.put(-7100, 37); - this.put(-7000, 25); - this.put(-6900, 35); - this.put(-6800, 44); - this.put(-6700, 37); - this.put(-6600, 34); - this.put(-6500, 28); - this.put(-6400, 43); - this.put(-6300, 47); - this.put(-6200, 43); - this.put(-6100, 46); - this.put(-6000, 47); - this.put(-5900, 55); - this.put(-5800, 55); - this.put(-5700, 51); - this.put(-5600, 63); - this.put(-5500, 50); - this.put(-5400, 63); - this.put(-5300, 51); - this.put(-5200, 65); - this.put(-5100, 64); - this.put(-5000, 78); - this.put(-4900, 90); - this.put(-4800, 63); - this.put(-4700, 84); - this.put(-4600, 81); - this.put(-4500, 73); - this.put(-4400, 61); - this.put(-4300, 104); - this.put(-4200, 72); - this.put(-4100, 72); - this.put(-4000, 95); - this.put(-3900, 112); - this.put(-3800, 96); - this.put(-3700, 111); - this.put(-3600, 111); - this.put(-3500, 110); - this.put(-3400, 139); - this.put(-3300, 143); - this.put(-3200, 179); - this.put(-3100, 160); - this.put(-3000, 173); - this.put(-2900, 161); - this.put(-2800, 168); - this.put(-2700, 155); - this.put(-2600, 236); - this.put(-2500, 197); - this.put(-2400, 205); - this.put(-2300, 238); - this.put(-2200, 246); - this.put(-2100, 306); - this.put(-2000, 333); - this.put(-1900, 275); - this.put(-1800, 315); - this.put(-1700, 349); - this.put(-1600, 369); - this.put(-1500, 460); - this.put(-1400, 435); - this.put(-1300, 524); - this.put(-1200, 618); - this.put(-1100, 630); - this.put(-1000, 802); - this.put(-900, 942); - this.put(-800, 1107); - this.put(-700, 1423); - this.put(-600, 1838); - this.put(-500, 2325); - this.put(-400, 3243); - this.put(-300, 5065); - this.put(-200, 9760); - this.put(-100, 34478); - this.put(0, 259217); - this.put(100, 84193); - this.put(200, 35121); - this.put(300, 22719); - this.put(400, 14995); - this.put(500, 10444); - this.put(600, 7718); - this.put(700, 5715); - this.put(800, 4569); - this.put(900, 3470); - this.put(1000, 2788); - this.put(1100, 2287); - this.put(1200, 1907); - this.put(1300, 1698); - this.put(1400, 1632); - this.put(1500, 1232); - this.put(1600, 976); - this.put(1700, 906); - this.put(1800, 770); - this.put(1900, 644); - this.put(2000, 672); - this.put(2100, 584); - this.put(2200, 541); - this.put(2300, 452); - this.put(2400, 401); - this.put(2500, 372); - this.put(2600, 331); - this.put(2700, 279); - this.put(2800, 255); - this.put(2900, 254); - this.put(3000, 216); - this.put(3100, 190); - this.put(3200, 204); - this.put(3300, 178); - this.put(3400, 166); - this.put(3500, 165); - this.put(3600, 147); - this.put(3700, 127); - this.put(3800, 119); - this.put(3900, 126); - this.put(4000, 121); - this.put(4100, 90); - this.put(4200, 90); - this.put(4300, 107); - this.put(4400, 72); - this.put(4500, 89); - this.put(4600, 76); - this.put(4700, 96); - this.put(4800, 59); - this.put(4900, 84); - this.put(5000, 70); - this.put(5100, 53); - this.put(5200, 61); - this.put(5300, 65); - this.put(5400, 51); - this.put(5500, 63); - this.put(5600, 58); - this.put(5700, 43); - this.put(5800, 53); - this.put(5900, 55); - this.put(6000, 48); - this.put(6100, 46); - this.put(6200, 49); - this.put(6300, 43); - this.put(6400, 36); - this.put(6500, 25); - this.put(6600, 29); - this.put(6700, 24); - this.put(6800, 34); - this.put(6900, 27); - this.put(7000, 28); - this.put(7100, 29); - this.put(7200, 27); - this.put(7300, 26); - this.put(7400, 36); - this.put(7500, 38); - this.put(7600, 24); - this.put(7700, 22); - this.put(7800, 23); - this.put(7900, 24); - this.put(8000, 23); - this.put(8100, 28); - this.put(8200, 18); - this.put(8300, 12); - this.put(8400, 26); - this.put(8500, 12); - this.put(8600, 19); - this.put(8700, 17); - this.put(8800, 18); - this.put(8900, 20); - this.put(9000, 17); - this.put(9100, 21); - this.put(9200, 24); - this.put(9300, 15); - this.put(9400, 15); - this.put(9500, 11); - this.put(9600, 16); - this.put(9700, 21); - this.put(9800, 14); - this.put(9900, 17); - this.put(10000, 140); - this.put(11000, 123); - this.put(12000, 120); - this.put(13000, 83); - this.put(14000, 67); - this.put(15000, 53); - this.put(16000, 54); - this.put(17000, 43); - this.put(18000, 37); - this.put(19000, 39); - this.put(20000, 30); - this.put(21000, 30); - this.put(22000, 41); - this.put(23000, 21); - this.put(24000, 12); - this.put(25000, 21); - this.put(26000, 17); - this.put(27000, 15); - this.put(28000, 27); - this.put(29000, 12); - this.put(30000, 8); - this.put(31000, 23); - this.put(32000, 13); - this.put(33000, 11); - this.put(34000, 8); - this.put(35000, 11); - this.put(36000, 8); - this.put(37000, 12); - this.put(38000, 8); - this.put(39000, 17); - this.put(40000, 8); - this.put(41000, 5); - this.put(42000, 9); - this.put(43000, 4); - this.put(44000, 6); - this.put(45000, 1); - this.put(46000, 5); - this.put(47000, 7); - this.put(48000, 3); - this.put(49000, 5); - this.put(50000, 13); - this.put(51000, 1); - this.put(52000, 3); - this.put(53000, 5); - this.put(54000, 3); - this.put(55000, 4); - this.put(57000, 2); - this.put(59000, 2); - this.put(60000, 2); - this.put(61000, 4); - this.put(62000, 4); - this.put(63000, 1); - this.put(64000, 2); - this.put(65000, 1); - this.put(66000, 7); - this.put(67000, 1); - this.put(68000, 2); - this.put(69000, 4); - this.put(70000, 2); - this.put(71000, 1); - this.put(72000, 3); - this.put(73000, 1); - this.put(74000, 1); - this.put(75000, 1); - this.put(76000, 2); - this.put(77000, 1); - this.put(78000, 2); - this.put(79000, 2); - this.put(80000, 1); - this.put(81000, 1); - this.put(82000, 2); - this.put(83000, 11); - this.put(84000, 2); - this.put(85000, 1); - this.put(87000, 3); - this.put(88000, 1); - this.put(89000, 1); - this.put(90000, 1); - this.put(92000, 6); - this.put(93000, 1); - this.put(94000, 2); - this.put(97000, 1); - this.put(98000, 1); - this.put(100000, 1); - } - } - }; + /** */ + public static final IntHistogram[] REVISION_DELTAS = + new IntHistogram[] { + new IntHistogram() { + { + this.put(-1000, 237); + this.put(-900, 237); + this.put(-800, 252); + this.put(-700, 357); + this.put(-600, 411); + this.put(-500, 538); + this.put(-400, 726); + this.put(-300, 1058); + this.put(-200, 1795); + this.put(-100, 7579); + this.put(0, 121517); + this.put(100, 40064); + this.put(200, 11512); + this.put(300, 7300); + this.put(400, 4931); + this.put(500, 3367); + this.put(600, 2592); + this.put(700, 1957); + this.put(800, 1495); + this.put(900, 1169); + this.put(1000, 1210); + this.put(1100, 750); + this.put(1200, 545); + this.put(1300, 570); + this.put(1400, 657); + this.put(1500, 461); + this.put(1600, 348); + this.put(1700, 635); + this.put(1800, 421); + this.put(1900, 233); + this.put(2000, 243); + this.put(2100, 193); + this.put(2200, 167); + this.put(2300, 159); + this.put(2400, 148); + this.put(2500, 123); + this.put(2600, 96); + this.put(2700, 124); + this.put(2800, 106); + this.put(2900, 93); + this.put(3000, 66); + this.put(3100, 91); + this.put(3200, 93); + this.put(3300, 74); + this.put(3400, 90); + this.put(3500, 67); + this.put(3600, 76); + this.put(3700, 59); + this.put(3800, 53); + this.put(3900, 69); + this.put(4000, 68); + this.put(4100, 59); + this.put(4200, 47); + this.put(4300, 44); + this.put(4400, 55); + this.put(4500, 37); + this.put(4600, 39); + this.put(4700, 56); + this.put(4800, 41); + this.put(4900, 46); + this.put(5000, 47); + this.put(5100, 39); + this.put(5200, 39); + this.put(5300, 43); + this.put(5400, 54); + this.put(5500, 41); + this.put(5600, 17); + this.put(5700, 37); + this.put(5800, 31); + this.put(5900, 30); + this.put(6000, 39); + this.put(6100, 29); + this.put(6200, 40); + this.put(6300, 36); + this.put(6400, 42); + this.put(6500, 39); + this.put(6600, 28); + this.put(6700, 38); + this.put(6800, 34); + this.put(6900, 23); + this.put(7000, 25); + this.put(7100, 32); + this.put(7200, 19); + this.put(7300, 21); + this.put(7400, 23); + this.put(7500, 26); + this.put(7600, 24); + this.put(7700, 18); + this.put(7800, 19); + this.put(7900, 30); + this.put(8000, 21); + this.put(8100, 21); + this.put(8200, 21); + this.put(8300, 13); + this.put(8400, 18); + this.put(8500, 14); + this.put(8600, 19); + this.put(8700, 21); + this.put(8800, 14); + this.put(8900, 19); + this.put(9000, 25); + this.put(9100, 12); + this.put(9200, 16); + this.put(9300, 13); + this.put(9400, 21); + this.put(9500, 18); + this.put(9600, 25); + this.put(9700, 17); + this.put(9800, 15); + this.put(9900, 21); + this.put(10000, 151); + this.put(11000, 143); + this.put(12000, 122); + this.put(13000, 97); + this.put(14000, 103); + this.put(15000, 135); + this.put(16000, 84); + this.put(17000, 63); + this.put(18000, 92); + this.put(19000, 81); + this.put(20000, 98); + this.put(21000, 133); + this.put(22000, 67); + this.put(23000, 63); + this.put(24000, 66); + this.put(25000, 53); + this.put(26000, 85); + this.put(27000, 67); + this.put(28000, 90); + this.put(29000, 60); + this.put(30000, 48); + this.put(31000, 34); + this.put(32000, 35); + this.put(33000, 59); + this.put(34000, 40); + this.put(35000, 56); + this.put(36000, 68); + this.put(37000, 40); + this.put(38000, 37); + this.put(39000, 33); + this.put(40000, 34); + this.put(41000, 28); + this.put(42000, 35); + this.put(43000, 37); + this.put(44000, 34); + this.put(45000, 55); + this.put(46000, 30); + this.put(47000, 34); + this.put(48000, 30); + this.put(49000, 15); + this.put(50000, 14); + this.put(51000, 40); + this.put(52000, 16); + this.put(53000, 36); + this.put(54000, 19); + this.put(55000, 17); + this.put(56000, 20); + this.put(57000, 24); + this.put(58000, 29); + this.put(59000, 36); + this.put(60000, 34); + this.put(61000, 26); + this.put(62000, 20); + this.put(63000, 14); + this.put(64000, 12); + this.put(65000, 17); + this.put(66000, 8); + this.put(67000, 20); + this.put(68000, 17); + this.put(69000, 20); + this.put(70000, 11); + this.put(71000, 8); + this.put(72000, 5); + this.put(73000, 11); + this.put(74000, 20); + this.put(75000, 8); + this.put(76000, 8); + this.put(77000, 29); + this.put(78000, 5); + this.put(79000, 4); + this.put(80000, 7); + this.put(81000, 5); + this.put(82000, 8); + this.put(83000, 4); + this.put(84000, 5); + this.put(85000, 5); + this.put(86000, 10); + this.put(87000, 8); + this.put(88000, 7); + this.put(90000, 1); + this.put(91000, 5); + this.put(92000, 4); + this.put(93000, 16); + this.put(94000, 11); + this.put(95000, 3); + this.put(96000, 5); + this.put(97000, 6); + this.put(98000, 2); + this.put(99000, 5); + this.put(100000, 4); + } + }, + new IntHistogram() { + { + this.put(-10000, 15); + this.put(-9900, 19); + this.put(-9800, 20); + this.put(-9700, 17); + this.put(-9600, 25); + this.put(-9500, 19); + this.put(-9400, 21); + this.put(-9300, 18); + this.put(-9200, 20); + this.put(-9100, 14); + this.put(-9000, 28); + this.put(-8900, 19); + this.put(-8800, 16); + this.put(-8700, 17); + this.put(-8600, 21); + this.put(-8500, 15); + this.put(-8400, 17); + this.put(-8300, 21); + this.put(-8200, 28); + this.put(-8100, 24); + this.put(-8000, 23); + this.put(-7900, 37); + this.put(-7800, 24); + this.put(-7700, 27); + this.put(-7600, 34); + this.put(-7500, 33); + this.put(-7400, 22); + this.put(-7300, 24); + this.put(-7200, 30); + this.put(-7100, 40); + this.put(-7000, 40); + this.put(-6900, 38); + this.put(-6800, 50); + this.put(-6700, 36); + this.put(-6600, 38); + this.put(-6500, 44); + this.put(-6400, 31); + this.put(-6300, 41); + this.put(-6200, 38); + this.put(-6100, 31); + this.put(-6000, 40); + this.put(-5900, 45); + this.put(-5800, 43); + this.put(-5700, 54); + this.put(-5600, 37); + this.put(-5500, 58); + this.put(-5400, 57); + this.put(-5300, 65); + this.put(-5200, 75); + this.put(-5100, 67); + this.put(-5000, 58); + this.put(-4900, 63); + this.put(-4800, 69); + this.put(-4700, 73); + this.put(-4600, 60); + this.put(-4500, 59); + this.put(-4400, 76); + this.put(-4300, 76); + this.put(-4200, 72); + this.put(-4100, 87); + this.put(-4000, 92); + this.put(-3900, 101); + this.put(-3800, 97); + this.put(-3700, 74); + this.put(-3600, 117); + this.put(-3500, 100); + this.put(-3400, 124); + this.put(-3300, 112); + this.put(-3200, 128); + this.put(-3100, 141); + this.put(-3000, 152); + this.put(-2900, 134); + this.put(-2800, 156); + this.put(-2700, 155); + this.put(-2600, 148); + this.put(-2500, 194); + this.put(-2400, 198); + this.put(-2300, 224); + this.put(-2200, 257); + this.put(-2100, 280); + this.put(-2000, 325); + this.put(-1900, 318); + this.put(-1800, 385); + this.put(-1700, 367); + this.put(-1600, 436); + this.put(-1500, 483); + this.put(-1400, 506); + this.put(-1300, 586); + this.put(-1200, 643); + this.put(-1100, 791); + this.put(-1000, 650); + this.put(-900, 721); + this.put(-800, 909); + this.put(-700, 1148); + this.put(-600, 1363); + this.put(-500, 1819); + this.put(-400, 2635); + this.put(-300, 4395); + this.put(-200, 8706); + this.put(-100, 36354); + this.put(0, 344441); + this.put(100, 110948); + this.put(200, 33273); + this.put(300, 18915); + this.put(400, 11943); + this.put(500, 8587); + this.put(600, 6339); + this.put(700, 4763); + this.put(800, 3813); + this.put(900, 2773); + this.put(1000, 2302); + this.put(1100, 1802); + this.put(1200, 1445); + this.put(1300, 1397); + this.put(1400, 1644); + this.put(1500, 1156); + this.put(1600, 728); + this.put(1700, 801); + this.put(1800, 605); + this.put(1900, 485); + this.put(2000, 504); + this.put(2100, 432); + this.put(2200, 324); + this.put(2300, 288); + this.put(2400, 301); + this.put(2500, 312); + this.put(2600, 201); + this.put(2700, 171); + this.put(2800, 134); + this.put(2900, 148); + this.put(3000, 157); + this.put(3100, 126); + this.put(3200, 117); + this.put(3300, 103); + this.put(3400, 112); + this.put(3500, 97); + this.put(3600, 93); + this.put(3700, 77); + this.put(3800, 69); + this.put(3900, 55); + this.put(4000, 86); + this.put(4100, 65); + this.put(4200, 68); + this.put(4300, 74); + this.put(4400, 39); + this.put(4500, 44); + this.put(4600, 51); + this.put(4700, 46); + this.put(4800, 48); + this.put(4900, 41); + this.put(5000, 38); + this.put(5100, 33); + this.put(5200, 59); + this.put(5300, 39); + this.put(5400, 23); + this.put(5500, 39); + this.put(5600, 37); + this.put(5700, 30); + this.put(5800, 34); + this.put(5900, 28); + this.put(6000, 16); + this.put(6100, 25); + this.put(6200, 25); + this.put(6300, 33); + this.put(6400, 23); + this.put(6500, 27); + this.put(6600, 19); + this.put(6700, 27); + this.put(6800, 26); + this.put(6900, 20); + this.put(7000, 19); + this.put(7100, 16); + this.put(7200, 13); + this.put(7300, 10); + this.put(7400, 17); + this.put(7500, 13); + this.put(7600, 18); + this.put(7700, 25); + this.put(7800, 19); + this.put(7900, 8); + this.put(8000, 13); + this.put(8100, 10); + this.put(8200, 12); + this.put(8300, 7); + this.put(8400, 8); + this.put(8500, 8); + this.put(8600, 12); + this.put(8700, 8); + this.put(8800, 9); + this.put(8900, 9); + this.put(9000, 13); + this.put(9100, 4); + this.put(9200, 10); + this.put(9300, 14); + this.put(9400, 13); + this.put(9500, 11); + this.put(9600, 10); + this.put(9700, 5); + this.put(9800, 9); + this.put(9900, 8); + this.put(10000, 63); + this.put(11000, 57); + this.put(12000, 43); + this.put(13000, 45); + this.put(14000, 43); + this.put(15000, 23); + this.put(16000, 26); + this.put(17000, 29); + this.put(18000, 21); + this.put(19000, 20); + this.put(20000, 20); + this.put(21000, 13); + this.put(22000, 21); + this.put(23000, 18); + this.put(24000, 10); + this.put(25000, 10); + this.put(26000, 13); + this.put(27000, 12); + this.put(28000, 13); + this.put(29000, 6); + this.put(30000, 6); + this.put(31000, 11); + this.put(32000, 9); + this.put(33000, 8); + this.put(34000, 8); + this.put(35000, 4); + this.put(36000, 4); + this.put(37000, 1); + this.put(38000, 5); + this.put(39000, 3); + this.put(40000, 3); + this.put(41000, 2); + this.put(42000, 2); + this.put(43000, 6); + this.put(44000, 4); + this.put(45000, 9); + this.put(46000, 6); + this.put(47000, 5); + this.put(48000, 5); + this.put(49000, 5); + this.put(50000, 3); + this.put(51000, 5); + this.put(52000, 4); + this.put(53000, 6); + this.put(54000, 2); + this.put(55000, 1); + this.put(56000, 3); + this.put(57000, 2); + this.put(60000, 2); + this.put(61000, 5); + this.put(63000, 2); + this.put(65000, 1); + this.put(68000, 3); + this.put(69000, 1); + this.put(70000, 1); + this.put(71000, 1); + this.put(72000, 1); + this.put(73000, 4); + this.put(75000, 3); + this.put(76000, 1); + this.put(77000, 2); + this.put(78000, 1); + this.put(80000, 1); + this.put(81000, 5); + this.put(82000, 1); + this.put(83000, 1); + this.put(84000, 2); + this.put(88000, 2); + this.put(91000, 1); + this.put(93000, 3); + this.put(97000, 2); + this.put(99000, 4); + this.put(100000, 1); + } + }, + new IntHistogram() { + { + this.put(-985000, 1); + this.put(-982000, 1); + this.put(-950000, 1); + this.put(-944000, 1); + this.put(-852000, 1); + this.put(-801000, 1); + this.put(-800000, 1); + this.put(-749000, 1); + this.put(-719000, 1); + this.put(-711000, 1); + this.put(-696000, 1); + this.put(-687000, 2); + this.put(-683000, 1); + this.put(-681000, 1); + this.put(-667000, 1); + this.put(-644000, 1); + this.put(-643000, 1); + this.put(-642000, 1); + this.put(-634000, 1); + this.put(-596000, 1); + this.put(-512000, 1); + this.put(-486000, 2); + this.put(-481000, 1); + this.put(-450000, 1); + this.put(-445000, 3); + this.put(-433000, 1); + this.put(-418000, 1); + this.put(-391000, 1); + this.put(-386000, 1); + this.put(-382000, 2); + this.put(-376000, 1); + this.put(-364000, 1); + this.put(-359000, 2); + this.put(-357000, 1); + this.put(-344000, 1); + this.put(-332000, 1); + this.put(-331000, 1); + this.put(-328000, 1); + this.put(-327000, 1); + this.put(-326000, 1); + this.put(-323000, 1); + this.put(-319000, 3); + this.put(-317000, 1); + this.put(-312000, 2); + this.put(-300000, 1); + this.put(-299000, 1); + this.put(-295000, 1); + this.put(-292000, 1); + this.put(-289000, 1); + this.put(-284000, 1); + this.put(-275000, 1); + this.put(-273000, 2); + this.put(-269000, 1); + this.put(-261000, 1); + this.put(-260000, 1); + this.put(-258000, 1); + this.put(-256000, 5); + this.put(-252000, 1); + this.put(-251000, 2); + this.put(-250000, 1); + this.put(-249000, 1); + this.put(-248000, 1); + this.put(-247000, 2); + this.put(-246000, 2); + this.put(-245000, 2); + this.put(-239000, 4); + this.put(-232000, 2); + this.put(-229000, 1); + this.put(-227000, 1); + this.put(-224000, 2); + this.put(-219000, 1); + this.put(-218000, 1); + this.put(-217000, 3); + this.put(-216000, 2); + this.put(-214000, 2); + this.put(-213000, 1); + this.put(-209000, 1); + this.put(-208000, 2); + this.put(-207000, 1); + this.put(-205000, 2); + this.put(-203000, 2); + this.put(-201000, 9); + this.put(-200000, 3); + this.put(-199000, 1); + this.put(-197000, 1); + this.put(-192000, 1); + this.put(-191000, 3); + this.put(-190000, 3); + this.put(-189000, 1); + this.put(-188000, 1); + this.put(-187000, 1); + this.put(-186000, 1); + this.put(-185000, 2); + this.put(-184000, 6); + this.put(-183000, 5); + this.put(-181000, 3); + this.put(-180000, 1); + this.put(-176000, 1); + this.put(-175000, 1); + this.put(-174000, 3); + this.put(-173000, 1); + this.put(-172000, 4); + this.put(-171000, 4); + this.put(-170000, 1); + this.put(-169000, 2); + this.put(-167000, 3); + this.put(-166000, 1); + this.put(-165000, 1); + this.put(-164000, 6); + this.put(-163000, 1); + this.put(-162000, 6); + this.put(-161000, 12); + this.put(-160000, 5); + this.put(-159000, 1); + this.put(-158000, 3); + this.put(-157000, 2); + this.put(-156000, 2); + this.put(-155000, 1); + this.put(-154000, 6); + this.put(-153000, 5); + this.put(-152000, 2); + this.put(-151000, 3); + this.put(-150000, 2); + this.put(-149000, 1); + this.put(-148000, 1); + this.put(-147000, 1); + this.put(-146000, 4); + this.put(-144000, 1); + this.put(-143000, 3); + this.put(-142000, 2); + this.put(-141000, 2); + this.put(-140000, 6); + this.put(-139000, 5); + this.put(-138000, 4); + this.put(-137000, 4); + this.put(-136000, 7); + this.put(-134000, 10); + this.put(-133000, 4); + this.put(-132000, 1); + this.put(-131000, 3); + this.put(-128000, 2); + this.put(-127000, 7); + this.put(-126000, 4); + this.put(-124000, 1); + this.put(-122000, 7); + this.put(-121000, 3); + this.put(-120000, 2); + this.put(-119000, 2); + this.put(-118000, 4); + this.put(-117000, 3); + this.put(-116000, 3); + this.put(-115000, 3); + this.put(-114000, 2); + this.put(-113000, 4); + this.put(-112000, 4); + this.put(-111000, 4); + this.put(-110000, 3); + this.put(-109000, 3); + this.put(-108000, 2); + this.put(-107000, 3); + this.put(-106000, 6); + this.put(-105000, 3); + this.put(-104000, 2); + this.put(-103000, 3); + this.put(-102000, 3); + this.put(-101000, 6); + this.put(-100000, 10); + this.put(-99000, 2); + this.put(-98000, 10); + this.put(-97000, 5); + this.put(-96000, 6); + this.put(-95000, 14); + this.put(-94000, 19); + this.put(-93000, 12); + this.put(-92000, 9); + this.put(-91000, 4); + this.put(-90000, 2); + this.put(-89000, 11); + this.put(-88000, 7); + this.put(-87000, 12); + this.put(-86000, 7); + this.put(-85000, 8); + this.put(-84000, 13); + this.put(-83000, 17); + this.put(-82000, 15); + this.put(-81000, 15); + this.put(-80000, 6); + this.put(-79000, 10); + this.put(-78000, 30); + this.put(-77000, 18); + this.put(-76000, 13); + this.put(-75000, 20); + this.put(-74000, 14); + this.put(-73000, 12); + this.put(-72000, 9); + this.put(-71000, 12); + this.put(-70000, 24); + this.put(-69000, 28); + this.put(-68000, 22); + this.put(-67000, 17); + this.put(-66000, 17); + this.put(-65000, 17); + this.put(-64000, 13); + this.put(-63000, 29); + this.put(-62000, 38); + this.put(-61000, 35); + this.put(-60000, 39); + this.put(-59000, 33); + this.put(-58000, 32); + this.put(-57000, 22); + this.put(-56000, 26); + this.put(-55000, 20); + this.put(-54000, 53); + this.put(-53000, 23); + this.put(-52000, 47); + this.put(-51000, 34); + this.put(-50000, 24); + this.put(-49000, 40); + this.put(-48000, 52); + this.put(-47000, 38); + this.put(-46000, 67); + this.put(-45000, 51); + this.put(-44000, 41); + this.put(-43000, 51); + this.put(-42000, 47); + this.put(-41000, 49); + this.put(-40000, 45); + this.put(-39000, 54); + this.put(-38000, 62); + this.put(-37000, 83); + this.put(-36000, 85); + this.put(-35000, 66); + this.put(-34000, 71); + this.put(-33000, 64); + this.put(-32000, 56); + this.put(-31000, 79); + this.put(-30000, 77); + this.put(-29000, 119); + this.put(-28000, 129); + this.put(-27000, 110); + this.put(-26000, 91); + this.put(-25000, 99); + this.put(-24000, 116); + this.put(-23000, 136); + this.put(-22000, 167); + this.put(-21000, 160); + this.put(-20000, 137); + this.put(-19000, 156); + this.put(-18000, 129); + this.put(-17000, 159); + this.put(-16000, 216); + this.put(-15000, 226); + this.put(-14000, 197); + this.put(-13000, 278); + this.put(-12000, 308); + this.put(-11000, 336); + this.put(-10000, 17); + this.put(-9900, 24); + this.put(-9800, 19); + this.put(-9700, 15); + this.put(-9600, 25); + this.put(-9500, 25); + this.put(-9400, 33); + this.put(-9300, 20); + this.put(-9200, 23); + this.put(-9100, 29); + this.put(-9000, 30); + this.put(-8900, 25); + this.put(-8800, 27); + this.put(-8700, 23); + this.put(-8600, 26); + this.put(-8500, 29); + this.put(-8400, 26); + this.put(-8300, 24); + this.put(-8200, 28); + this.put(-8100, 33); + this.put(-8000, 21); + this.put(-7900, 23); + this.put(-7800, 33); + this.put(-7700, 25); + this.put(-7600, 27); + this.put(-7500, 35); + this.put(-7400, 28); + this.put(-7300, 28); + this.put(-7200, 32); + this.put(-7100, 37); + this.put(-7000, 25); + this.put(-6900, 35); + this.put(-6800, 44); + this.put(-6700, 37); + this.put(-6600, 34); + this.put(-6500, 28); + this.put(-6400, 43); + this.put(-6300, 47); + this.put(-6200, 43); + this.put(-6100, 46); + this.put(-6000, 47); + this.put(-5900, 55); + this.put(-5800, 55); + this.put(-5700, 51); + this.put(-5600, 63); + this.put(-5500, 50); + this.put(-5400, 63); + this.put(-5300, 51); + this.put(-5200, 65); + this.put(-5100, 64); + this.put(-5000, 78); + this.put(-4900, 90); + this.put(-4800, 63); + this.put(-4700, 84); + this.put(-4600, 81); + this.put(-4500, 73); + this.put(-4400, 61); + this.put(-4300, 104); + this.put(-4200, 72); + this.put(-4100, 72); + this.put(-4000, 95); + this.put(-3900, 112); + this.put(-3800, 96); + this.put(-3700, 111); + this.put(-3600, 111); + this.put(-3500, 110); + this.put(-3400, 139); + this.put(-3300, 143); + this.put(-3200, 179); + this.put(-3100, 160); + this.put(-3000, 173); + this.put(-2900, 161); + this.put(-2800, 168); + this.put(-2700, 155); + this.put(-2600, 236); + this.put(-2500, 197); + this.put(-2400, 205); + this.put(-2300, 238); + this.put(-2200, 246); + this.put(-2100, 306); + this.put(-2000, 333); + this.put(-1900, 275); + this.put(-1800, 315); + this.put(-1700, 349); + this.put(-1600, 369); + this.put(-1500, 460); + this.put(-1400, 435); + this.put(-1300, 524); + this.put(-1200, 618); + this.put(-1100, 630); + this.put(-1000, 802); + this.put(-900, 942); + this.put(-800, 1107); + this.put(-700, 1423); + this.put(-600, 1838); + this.put(-500, 2325); + this.put(-400, 3243); + this.put(-300, 5065); + this.put(-200, 9760); + this.put(-100, 34478); + this.put(0, 259217); + this.put(100, 84193); + this.put(200, 35121); + this.put(300, 22719); + this.put(400, 14995); + this.put(500, 10444); + this.put(600, 7718); + this.put(700, 5715); + this.put(800, 4569); + this.put(900, 3470); + this.put(1000, 2788); + this.put(1100, 2287); + this.put(1200, 1907); + this.put(1300, 1698); + this.put(1400, 1632); + this.put(1500, 1232); + this.put(1600, 976); + this.put(1700, 906); + this.put(1800, 770); + this.put(1900, 644); + this.put(2000, 672); + this.put(2100, 584); + this.put(2200, 541); + this.put(2300, 452); + this.put(2400, 401); + this.put(2500, 372); + this.put(2600, 331); + this.put(2700, 279); + this.put(2800, 255); + this.put(2900, 254); + this.put(3000, 216); + this.put(3100, 190); + this.put(3200, 204); + this.put(3300, 178); + this.put(3400, 166); + this.put(3500, 165); + this.put(3600, 147); + this.put(3700, 127); + this.put(3800, 119); + this.put(3900, 126); + this.put(4000, 121); + this.put(4100, 90); + this.put(4200, 90); + this.put(4300, 107); + this.put(4400, 72); + this.put(4500, 89); + this.put(4600, 76); + this.put(4700, 96); + this.put(4800, 59); + this.put(4900, 84); + this.put(5000, 70); + this.put(5100, 53); + this.put(5200, 61); + this.put(5300, 65); + this.put(5400, 51); + this.put(5500, 63); + this.put(5600, 58); + this.put(5700, 43); + this.put(5800, 53); + this.put(5900, 55); + this.put(6000, 48); + this.put(6100, 46); + this.put(6200, 49); + this.put(6300, 43); + this.put(6400, 36); + this.put(6500, 25); + this.put(6600, 29); + this.put(6700, 24); + this.put(6800, 34); + this.put(6900, 27); + this.put(7000, 28); + this.put(7100, 29); + this.put(7200, 27); + this.put(7300, 26); + this.put(7400, 36); + this.put(7500, 38); + this.put(7600, 24); + this.put(7700, 22); + this.put(7800, 23); + this.put(7900, 24); + this.put(8000, 23); + this.put(8100, 28); + this.put(8200, 18); + this.put(8300, 12); + this.put(8400, 26); + this.put(8500, 12); + this.put(8600, 19); + this.put(8700, 17); + this.put(8800, 18); + this.put(8900, 20); + this.put(9000, 17); + this.put(9100, 21); + this.put(9200, 24); + this.put(9300, 15); + this.put(9400, 15); + this.put(9500, 11); + this.put(9600, 16); + this.put(9700, 21); + this.put(9800, 14); + this.put(9900, 17); + this.put(10000, 140); + this.put(11000, 123); + this.put(12000, 120); + this.put(13000, 83); + this.put(14000, 67); + this.put(15000, 53); + this.put(16000, 54); + this.put(17000, 43); + this.put(18000, 37); + this.put(19000, 39); + this.put(20000, 30); + this.put(21000, 30); + this.put(22000, 41); + this.put(23000, 21); + this.put(24000, 12); + this.put(25000, 21); + this.put(26000, 17); + this.put(27000, 15); + this.put(28000, 27); + this.put(29000, 12); + this.put(30000, 8); + this.put(31000, 23); + this.put(32000, 13); + this.put(33000, 11); + this.put(34000, 8); + this.put(35000, 11); + this.put(36000, 8); + this.put(37000, 12); + this.put(38000, 8); + this.put(39000, 17); + this.put(40000, 8); + this.put(41000, 5); + this.put(42000, 9); + this.put(43000, 4); + this.put(44000, 6); + this.put(45000, 1); + this.put(46000, 5); + this.put(47000, 7); + this.put(48000, 3); + this.put(49000, 5); + this.put(50000, 13); + this.put(51000, 1); + this.put(52000, 3); + this.put(53000, 5); + this.put(54000, 3); + this.put(55000, 4); + this.put(57000, 2); + this.put(59000, 2); + this.put(60000, 2); + this.put(61000, 4); + this.put(62000, 4); + this.put(63000, 1); + this.put(64000, 2); + this.put(65000, 1); + this.put(66000, 7); + this.put(67000, 1); + this.put(68000, 2); + this.put(69000, 4); + this.put(70000, 2); + this.put(71000, 1); + this.put(72000, 3); + this.put(73000, 1); + this.put(74000, 1); + this.put(75000, 1); + this.put(76000, 2); + this.put(77000, 1); + this.put(78000, 2); + this.put(79000, 2); + this.put(80000, 1); + this.put(81000, 1); + this.put(82000, 2); + this.put(83000, 11); + this.put(84000, 2); + this.put(85000, 1); + this.put(87000, 3); + this.put(88000, 1); + this.put(89000, 1); + this.put(90000, 1); + this.put(92000, 6); + this.put(93000, 1); + this.put(94000, 2); + this.put(97000, 1); + this.put(98000, 1); + this.put(100000, 1); + } + } + }; - /** - * The histogram of the REV_MINOR_EDIT column - */ - public static final Histogram MINOR_EDIT = new Histogram() { + /** The histogram of the REV_MINOR_EDIT column */ + public static final Histogram MINOR_EDIT = + new Histogram() { { - this.put(0, 1142822); - this.put(1, 362171); + this.put(0, 1142822); + this.put(1, 362171); } - }; - + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/TextHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/TextHistograms.java index c7f6ead43..f6a9533a4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/TextHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/TextHistograms.java @@ -21,1524 +21,1522 @@ public abstract class TextHistograms { - /** - * The length of the OLD_TEXT column - */ - public static final Histogram TEXT_LENGTH = new Histogram() { + /** The length of the OLD_TEXT column */ + public static final Histogram TEXT_LENGTH = + new Histogram() { { - this.put(100, 52106); - this.put(200, 32370); - this.put(300, 20377); - this.put(400, 21345); - this.put(500, 21532); - this.put(600, 21124); - this.put(700, 20805); - this.put(800, 19312); - this.put(900, 19080); - this.put(1000, 19137); - this.put(1100, 18852); - this.put(1200, 17861); - this.put(1300, 16929); - this.put(1400, 17723); - this.put(1500, 16713); - this.put(1600, 15420); - this.put(1700, 15267); - this.put(1800, 14782); - this.put(1900, 13870); - this.put(2000, 13838); - this.put(2100, 13498); - this.put(2200, 12667); - this.put(2300, 12383); - this.put(2400, 12217); - this.put(2500, 12394); - this.put(2600, 12306); - this.put(2700, 11977); - this.put(2800, 11427); - this.put(2900, 10639); - this.put(3000, 10339); - this.put(3100, 10086); - this.put(3200, 9851); - this.put(3300, 9722); - this.put(3400, 9155); - this.put(3500, 9124); - this.put(3600, 8879); - this.put(3700, 8676); - this.put(3800, 8335); - this.put(3900, 8158); - this.put(4000, 7984); - this.put(4100, 7844); - this.put(4200, 7415); - this.put(4300, 7234); - this.put(4400, 7199); - this.put(4500, 6958); - this.put(4600, 7457); - this.put(4700, 7099); - this.put(4800, 7175); - this.put(4900, 6776); - this.put(5000, 6573); - this.put(5100, 6525); - this.put(5200, 6019); - this.put(5300, 6246); - this.put(5400, 6315); - this.put(5500, 5942); - this.put(5600, 5772); - this.put(5700, 6040); - this.put(5800, 5892); - this.put(5900, 5610); - this.put(6000, 5420); - this.put(6100, 5507); - this.put(6200, 5418); - this.put(6300, 5229); - this.put(6400, 5426); - this.put(6500, 5226); - this.put(6600, 4980); - this.put(6700, 5067); - this.put(6800, 4889); - this.put(6900, 4712); - this.put(7000, 4442); - this.put(7100, 4274); - this.put(7200, 4510); - this.put(7300, 4370); - this.put(7400, 4684); - this.put(7500, 4323); - this.put(7600, 4232); - this.put(7700, 4595); - this.put(7800, 4563); - this.put(7900, 3973); - this.put(8000, 4124); - this.put(8100, 4165); - this.put(8200, 4190); - this.put(8300, 4046); - this.put(8400, 3943); - this.put(8500, 4054); - this.put(8600, 4014); - this.put(8700, 3770); - this.put(8800, 3736); - this.put(8900, 3656); - this.put(9000, 3604); - this.put(9100, 3411); - this.put(9200, 3634); - this.put(9300, 3506); - this.put(9400, 3655); - this.put(9500, 3288); - this.put(9600, 3052); - this.put(9700, 3305); - this.put(9800, 3176); - this.put(9900, 2962); - this.put(10000, 2882); - this.put(10100, 2926); - this.put(10200, 3069); - this.put(10300, 2876); - this.put(10400, 2897); - this.put(10500, 2821); - this.put(10600, 3081); - this.put(10700, 2832); - this.put(10800, 2837); - this.put(10900, 2950); - this.put(11000, 2938); - this.put(11100, 2907); - this.put(11200, 2987); - this.put(11300, 2833); - this.put(11400, 2602); - this.put(11500, 2653); - this.put(11600, 2738); - this.put(11700, 2590); - this.put(11800, 2531); - this.put(11900, 2468); - this.put(12000, 2409); - this.put(12100, 2364); - this.put(12200, 2533); - this.put(12300, 2400); - this.put(12400, 2504); - this.put(12500, 2360); - this.put(12600, 2251); - this.put(12700, 2164); - this.put(12800, 2131); - this.put(12900, 2205); - this.put(13000, 2147); - this.put(13100, 2300); - this.put(13200, 2353); - this.put(13300, 2317); - this.put(13400, 2210); - this.put(13500, 2229); - this.put(13600, 2152); - this.put(13700, 2234); - this.put(13800, 2197); - this.put(13900, 2003); - this.put(14000, 2059); - this.put(14100, 2027); - this.put(14200, 1974); - this.put(14300, 2029); - this.put(14400, 1989); - this.put(14500, 1913); - this.put(14600, 2002); - this.put(14700, 1986); - this.put(14800, 2041); - this.put(14900, 2134); - this.put(15000, 2059); - this.put(15100, 2051); - this.put(15200, 2181); - this.put(15300, 2098); - this.put(15400, 1817); - this.put(15500, 1997); - this.put(15600, 2191); - this.put(15700, 1798); - this.put(15800, 1821); - this.put(15900, 1861); - this.put(16000, 1762); - this.put(16100, 1817); - this.put(16200, 1816); - this.put(16300, 1648); - this.put(16400, 1542); - this.put(16500, 1682); - this.put(16600, 1586); - this.put(16700, 1483); - this.put(16800, 1621); - this.put(16900, 1684); - this.put(17000, 1819); - this.put(17100, 1802); - this.put(17200, 1796); - this.put(17300, 1631); - this.put(17400, 1652); - this.put(17500, 1599); - this.put(17600, 1764); - this.put(17700, 1653); - this.put(17800, 1573); - this.put(17900, 1587); - this.put(18000, 1756); - this.put(18100, 1729); - this.put(18200, 1731); - this.put(18300, 1599); - this.put(18400, 1593); - this.put(18500, 1553); - this.put(18600, 1439); - this.put(18700, 1424); - this.put(18800, 1375); - this.put(18900, 1530); - this.put(19000, 1392); - this.put(19100, 1457); - this.put(19200, 1461); - this.put(19300, 1502); - this.put(19400, 1494); - this.put(19500, 1716); - this.put(19600, 1542); - this.put(19700, 1447); - this.put(19800, 1356); - this.put(19900, 1469); - this.put(20000, 1371); - this.put(20100, 1467); - this.put(20200, 1484); - this.put(20300, 1504); - this.put(20400, 1467); - this.put(20500, 1486); - this.put(20600, 1363); - this.put(20700, 1468); - this.put(20800, 1497); - this.put(20900, 1393); - this.put(21000, 1294); - this.put(21100, 1351); - this.put(21200, 1352); - this.put(21300, 1306); - this.put(21400, 1259); - this.put(21500, 1302); - this.put(21600, 1132); - this.put(21700, 1126); - this.put(21800, 1125); - this.put(21900, 1151); - this.put(22000, 1083); - this.put(22100, 1051); - this.put(22200, 1090); - this.put(22300, 985); - this.put(22400, 1311); - this.put(22500, 1181); - this.put(22600, 1060); - this.put(22700, 1304); - this.put(22800, 1160); - this.put(22900, 1196); - this.put(23000, 1297); - this.put(23100, 1291); - this.put(23200, 1394); - this.put(23300, 1217); - this.put(23400, 1184); - this.put(23500, 1298); - this.put(23600, 1206); - this.put(23700, 1115); - this.put(23800, 1269); - this.put(23900, 1108); - this.put(24000, 1145); - this.put(24100, 1167); - this.put(24200, 1128); - this.put(24300, 1138); - this.put(24400, 1215); - this.put(24500, 1205); - this.put(24600, 1202); - this.put(24700, 1095); - this.put(24800, 1194); - this.put(24900, 1152); - this.put(25000, 1214); - this.put(25100, 1096); - this.put(25200, 966); - this.put(25300, 1144); - this.put(25400, 1146); - this.put(25500, 917); - this.put(25600, 1213); - this.put(25700, 980); - this.put(25800, 958); - this.put(25900, 964); - this.put(26000, 1106); - this.put(26100, 1131); - this.put(26200, 885); - this.put(26300, 986); - this.put(26400, 1062); - this.put(26500, 1035); - this.put(26600, 1083); - this.put(26700, 1223); - this.put(26800, 1201); - this.put(26900, 1059); - this.put(27000, 955); - this.put(27100, 1106); - this.put(27200, 989); - this.put(27300, 979); - this.put(27400, 1021); - this.put(27500, 1128); - this.put(27600, 1118); - this.put(27700, 1018); - this.put(27800, 1042); - this.put(27900, 988); - this.put(28000, 1030); - this.put(28100, 969); - this.put(28200, 1005); - this.put(28300, 1114); - this.put(28400, 970); - this.put(28500, 1081); - this.put(28600, 900); - this.put(28700, 902); - this.put(28800, 957); - this.put(28900, 992); - this.put(29000, 1080); - this.put(29100, 923); - this.put(29200, 886); - this.put(29300, 932); - this.put(29400, 1000); - this.put(29500, 912); - this.put(29600, 939); - this.put(29700, 888); - this.put(29800, 1051); - this.put(29900, 933); - this.put(30000, 778); - this.put(30100, 879); - this.put(30200, 902); - this.put(30300, 917); - this.put(30400, 991); - this.put(30500, 836); - this.put(30600, 901); - this.put(30700, 780); - this.put(30800, 703); - this.put(30900, 854); - this.put(31000, 860); - this.put(31100, 807); - this.put(31200, 723); - this.put(31300, 764); - this.put(31400, 786); - this.put(31500, 770); - this.put(31600, 728); - this.put(31700, 721); - this.put(31800, 734); - this.put(31900, 726); - this.put(32000, 784); - this.put(32100, 733); - this.put(32200, 880); - this.put(32300, 761); - this.put(32400, 826); - this.put(32500, 861); - this.put(32600, 649); - this.put(32700, 664); - this.put(32800, 693); - this.put(32900, 720); - this.put(33000, 845); - this.put(33100, 836); - this.put(33200, 898); - this.put(33300, 871); - this.put(33400, 775); - this.put(33500, 699); - this.put(33600, 762); - this.put(33700, 756); - this.put(33800, 800); - this.put(33900, 825); - this.put(34000, 812); - this.put(34100, 665); - this.put(34200, 795); - this.put(34300, 712); - this.put(34400, 872); - this.put(34500, 736); - this.put(34600, 873); - this.put(34700, 715); - this.put(34800, 763); - this.put(34900, 746); - this.put(35000, 838); - this.put(35100, 957); - this.put(35200, 908); - this.put(35300, 776); - this.put(35400, 829); - this.put(35500, 755); - this.put(35600, 715); - this.put(35700, 662); - this.put(35800, 638); - this.put(35900, 723); - this.put(36000, 648); - this.put(36100, 567); - this.put(36200, 620); - this.put(36300, 684); - this.put(36400, 595); - this.put(36500, 605); - this.put(36600, 765); - this.put(36700, 632); - this.put(36800, 661); - this.put(36900, 662); - this.put(37000, 562); - this.put(37100, 556); - this.put(37200, 545); - this.put(37300, 597); - this.put(37400, 582); - this.put(37500, 606); - this.put(37600, 564); - this.put(37700, 558); - this.put(37800, 504); - this.put(37900, 533); - this.put(38000, 512); - this.put(38100, 597); - this.put(38200, 447); - this.put(38300, 504); - this.put(38400, 565); - this.put(38500, 528); - this.put(38600, 579); - this.put(38700, 607); - this.put(38800, 448); - this.put(38900, 496); - this.put(39000, 563); - this.put(39100, 459); - this.put(39200, 521); - this.put(39300, 673); - this.put(39400, 456); - this.put(39500, 441); - this.put(39600, 540); - this.put(39700, 521); - this.put(39800, 560); - this.put(39900, 499); - this.put(40000, 652); - this.put(40100, 540); - this.put(40200, 539); - this.put(40300, 521); - this.put(40400, 443); - this.put(40500, 498); - this.put(40600, 509); - this.put(40700, 654); - this.put(40800, 520); - this.put(40900, 502); - this.put(41000, 485); - this.put(41100, 378); - this.put(41200, 393); - this.put(41300, 368); - this.put(41400, 350); - this.put(41500, 383); - this.put(41600, 357); - this.put(41700, 384); - this.put(41800, 442); - this.put(41900, 433); - this.put(42000, 456); - this.put(42100, 704); - this.put(42200, 432); - this.put(42300, 304); - this.put(42400, 354); - this.put(42500, 327); - this.put(42600, 435); - this.put(42700, 488); - this.put(42800, 407); - this.put(42900, 389); - this.put(43000, 453); - this.put(43100, 375); - this.put(43200, 325); - this.put(43300, 365); - this.put(43400, 398); - this.put(43500, 364); - this.put(43600, 424); - this.put(43700, 358); - this.put(43800, 442); - this.put(43900, 511); - this.put(44000, 395); - this.put(44100, 411); - this.put(44200, 441); - this.put(44300, 409); - this.put(44400, 323); - this.put(44500, 396); - this.put(44600, 456); - this.put(44700, 403); - this.put(44800, 420); - this.put(44900, 452); - this.put(45000, 430); - this.put(45100, 387); - this.put(45200, 444); - this.put(45300, 470); - this.put(45400, 432); - this.put(45500, 415); - this.put(45600, 354); - this.put(45700, 611); - this.put(45800, 424); - this.put(45900, 487); - this.put(46000, 547); - this.put(46100, 462); - this.put(46200, 310); - this.put(46300, 353); - this.put(46400, 311); - this.put(46500, 355); - this.put(46600, 373); - this.put(46700, 396); - this.put(46800, 401); - this.put(46900, 387); - this.put(47000, 369); - this.put(47100, 406); - this.put(47200, 331); - this.put(47300, 408); - this.put(47400, 348); - this.put(47500, 353); - this.put(47600, 454); - this.put(47700, 297); - this.put(47800, 342); - this.put(47900, 334); - this.put(48000, 361); - this.put(48100, 374); - this.put(48200, 371); - this.put(48300, 421); - this.put(48400, 400); - this.put(48500, 542); - this.put(48600, 387); - this.put(48700, 329); - this.put(48800, 397); - this.put(48900, 375); - this.put(49000, 354); - this.put(49100, 349); - this.put(49200, 312); - this.put(49300, 359); - this.put(49400, 385); - this.put(49500, 340); - this.put(49600, 284); - this.put(49700, 294); - this.put(49800, 243); - this.put(49900, 306); - this.put(50000, 355); - this.put(50100, 280); - this.put(50200, 318); - this.put(50300, 312); - this.put(50400, 302); - this.put(50500, 309); - this.put(50600, 310); - this.put(50700, 255); - this.put(50800, 287); - this.put(50900, 292); - this.put(51000, 272); - this.put(51100, 361); - this.put(51200, 370); - this.put(51300, 337); - this.put(51400, 323); - this.put(51500, 337); - this.put(51600, 367); - this.put(51700, 370); - this.put(51800, 328); - this.put(51900, 280); - this.put(52000, 294); - this.put(52100, 194); - this.put(52200, 346); - this.put(52300, 335); - this.put(52400, 292); - this.put(52500, 255); - this.put(52600, 244); - this.put(52700, 216); - this.put(52800, 222); - this.put(52900, 230); - this.put(53000, 247); - this.put(53100, 311); - this.put(53200, 294); - this.put(53300, 355); - this.put(53400, 425); - this.put(53500, 348); - this.put(53600, 299); - this.put(53700, 298); - this.put(53800, 348); - this.put(53900, 280); - this.put(54000, 386); - this.put(54100, 352); - this.put(54200, 290); - this.put(54300, 266); - this.put(54400, 240); - this.put(54500, 280); - this.put(54600, 286); - this.put(54700, 267); - this.put(54800, 254); - this.put(54900, 306); - this.put(55000, 251); - this.put(55100, 246); - this.put(55200, 238); - this.put(55300, 236); - this.put(55400, 224); - this.put(55500, 173); - this.put(55600, 177); - this.put(55700, 211); - this.put(55800, 186); - this.put(55900, 219); - this.put(56000, 246); - this.put(56100, 224); - this.put(56200, 247); - this.put(56300, 157); - this.put(56400, 184); - this.put(56500, 204); - this.put(56600, 188); - this.put(56700, 203); - this.put(56800, 187); - this.put(56900, 211); - this.put(57000, 158); - this.put(57100, 218); - this.put(57200, 222); - this.put(57300, 253); - this.put(57400, 298); - this.put(57500, 301); - this.put(57600, 264); - this.put(57700, 196); - this.put(57800, 232); - this.put(57900, 202); - this.put(58000, 215); - this.put(58100, 223); - this.put(58200, 217); - this.put(58300, 227); - this.put(58400, 243); - this.put(58500, 321); - this.put(58600, 326); - this.put(58700, 245); - this.put(58800, 325); - this.put(58900, 276); - this.put(59000, 268); - this.put(59100, 274); - this.put(59200, 291); - this.put(59300, 269); - this.put(59400, 306); - this.put(59500, 218); - this.put(59600, 256); - this.put(59700, 247); - this.put(59800, 388); - this.put(59900, 427); - this.put(60000, 282); - this.put(60100, 266); - this.put(60200, 291); - this.put(60300, 312); - this.put(60400, 294); - this.put(60500, 277); - this.put(60600, 353); - this.put(60700, 350); - this.put(60800, 335); - this.put(60900, 418); - this.put(61000, 305); - this.put(61100, 402); - this.put(61200, 330); - this.put(61300, 282); - this.put(61400, 313); - this.put(61500, 211); - this.put(61600, 281); - this.put(61700, 271); - this.put(61800, 242); - this.put(61900, 285); - this.put(62000, 277); - this.put(62100, 254); - this.put(62200, 264); - this.put(62300, 382); - this.put(62400, 292); - this.put(62500, 292); - this.put(62600, 215); - this.put(62700, 219); - this.put(62800, 236); - this.put(62900, 205); - this.put(63000, 224); - this.put(63100, 246); - this.put(63200, 232); - this.put(63300, 231); - this.put(63400, 212); - this.put(63500, 226); - this.put(63600, 306); - this.put(63700, 228); - this.put(63800, 203); - this.put(63900, 260); - this.put(64000, 260); - this.put(64100, 262); - this.put(64200, 231); - this.put(64300, 346); - this.put(64400, 282); - this.put(64500, 238); - this.put(64600, 168); - this.put(64700, 243); - this.put(64800, 335); - this.put(64900, 282); - this.put(65000, 360); - this.put(65100, 268); - this.put(65200, 271); - this.put(65300, 370); - this.put(65400, 226); - this.put(65500, 240); - this.put(65600, 196); - this.put(65700, 178); - this.put(65800, 224); - this.put(65900, 154); - this.put(66000, 190); - this.put(66100, 173); - this.put(66200, 197); - this.put(66300, 137); - this.put(66400, 209); - this.put(66500, 222); - this.put(66600, 213); - this.put(66700, 152); - this.put(66800, 205); - this.put(66900, 158); - this.put(67000, 179); - this.put(67100, 146); - this.put(67200, 148); - this.put(67300, 230); - this.put(67400, 196); - this.put(67500, 141); - this.put(67600, 190); - this.put(67700, 264); - this.put(67800, 161); - this.put(67900, 124); - this.put(68000, 168); - this.put(68100, 144); - this.put(68200, 146); - this.put(68300, 230); - this.put(68400, 256); - this.put(68500, 175); - this.put(68600, 233); - this.put(68700, 177); - this.put(68800, 213); - this.put(68900, 220); - this.put(69000, 217); - this.put(69100, 296); - this.put(69200, 199); - this.put(69300, 267); - this.put(69400, 310); - this.put(69500, 184); - this.put(69600, 209); - this.put(69700, 246); - this.put(69800, 183); - this.put(69900, 199); - this.put(70000, 162); - this.put(70100, 210); - this.put(70200, 141); - this.put(70300, 135); - this.put(70400, 188); - this.put(70500, 255); - this.put(70600, 195); - this.put(70700, 210); - this.put(70800, 205); - this.put(70900, 301); - this.put(71000, 295); - this.put(71100, 270); - this.put(71200, 179); - this.put(71300, 156); - this.put(71400, 214); - this.put(71500, 289); - this.put(71600, 246); - this.put(71700, 192); - this.put(71800, 176); - this.put(71900, 273); - this.put(72000, 168); - this.put(72100, 196); - this.put(72200, 237); - this.put(72300, 199); - this.put(72400, 178); - this.put(72500, 190); - this.put(72600, 156); - this.put(72700, 131); - this.put(72800, 161); - this.put(72900, 183); - this.put(73000, 204); - this.put(73100, 226); - this.put(73200, 138); - this.put(73300, 144); - this.put(73400, 195); - this.put(73500, 195); - this.put(73600, 112); - this.put(73700, 183); - this.put(73800, 174); - this.put(73900, 194); - this.put(74000, 222); - this.put(74100, 224); - this.put(74200, 181); - this.put(74300, 204); - this.put(74400, 195); - this.put(74500, 153); - this.put(74600, 187); - this.put(74700, 162); - this.put(74800, 152); - this.put(74900, 190); - this.put(75000, 178); - this.put(75100, 203); - this.put(75200, 173); - this.put(75300, 220); - this.put(75400, 260); - this.put(75500, 189); - this.put(75600, 156); - this.put(75700, 158); - this.put(75800, 167); - this.put(75900, 173); - this.put(76000, 110); - this.put(76100, 152); - this.put(76200, 169); - this.put(76300, 213); - this.put(76400, 186); - this.put(76500, 156); - this.put(76600, 152); - this.put(76700, 209); - this.put(76800, 196); - this.put(76900, 198); - this.put(77000, 232); - this.put(77100, 245); - this.put(77200, 262); - this.put(77300, 180); - this.put(77400, 177); - this.put(77500, 173); - this.put(77600, 171); - this.put(77700, 134); - this.put(77800, 217); - this.put(77900, 199); - this.put(78000, 140); - this.put(78100, 120); - this.put(78200, 149); - this.put(78300, 110); - this.put(78400, 117); - this.put(78500, 159); - this.put(78600, 113); - this.put(78700, 128); - this.put(78800, 182); - this.put(78900, 180); - this.put(79000, 162); - this.put(79100, 171); - this.put(79200, 133); - this.put(79300, 193); - this.put(79400, 168); - this.put(79500, 142); - this.put(79600, 102); - this.put(79700, 131); - this.put(79800, 108); - this.put(79900, 126); - this.put(80000, 102); - this.put(80100, 157); - this.put(80200, 124); - this.put(80300, 137); - this.put(80400, 120); - this.put(80500, 116); - this.put(80600, 119); - this.put(80700, 144); - this.put(80800, 159); - this.put(80900, 139); - this.put(81000, 123); - this.put(81100, 139); - this.put(81200, 105); - this.put(81300, 121); - this.put(81400, 154); - this.put(81500, 107); - this.put(81600, 150); - this.put(81700, 115); - this.put(81800, 147); - this.put(81900, 159); - this.put(82000, 141); - this.put(82100, 139); - this.put(82200, 112); - this.put(82300, 153); - this.put(82400, 141); - this.put(82500, 158); - this.put(82600, 126); - this.put(82700, 142); - this.put(82800, 122); - this.put(82900, 121); - this.put(83000, 143); - this.put(83100, 97); - this.put(83200, 173); - this.put(83300, 117); - this.put(83400, 142); - this.put(83500, 188); - this.put(83600, 101); - this.put(83700, 97); - this.put(83800, 116); - this.put(83900, 125); - this.put(84000, 151); - this.put(84100, 115); - this.put(84200, 127); - this.put(84300, 125); - this.put(84400, 128); - this.put(84500, 138); - this.put(84600, 163); - this.put(84700, 159); - this.put(84800, 148); - this.put(84900, 182); - this.put(85000, 161); - this.put(85100, 128); - this.put(85200, 158); - this.put(85300, 172); - this.put(85400, 187); - this.put(85500, 155); - this.put(85600, 155); - this.put(85700, 164); - this.put(85800, 167); - this.put(85900, 144); - this.put(86000, 122); - this.put(86100, 166); - this.put(86200, 168); - this.put(86300, 150); - this.put(86400, 144); - this.put(86500, 167); - this.put(86600, 174); - this.put(86700, 208); - this.put(86800, 188); - this.put(86900, 191); - this.put(87000, 178); - this.put(87100, 156); - this.put(87200, 134); - this.put(87300, 151); - this.put(87400, 134); - this.put(87500, 170); - this.put(87600, 169); - this.put(87700, 153); - this.put(87800, 133); - this.put(87900, 147); - this.put(88000, 135); - this.put(88100, 146); - this.put(88200, 135); - this.put(88300, 161); - this.put(88400, 153); - this.put(88500, 185); - this.put(88600, 117); - this.put(88700, 201); - this.put(88800, 158); - this.put(88900, 163); - this.put(89000, 137); - this.put(89100, 147); - this.put(89200, 122); - this.put(89300, 120); - this.put(89400, 90); - this.put(89500, 135); - this.put(89600, 164); - this.put(89700, 122); - this.put(89800, 132); - this.put(89900, 154); - this.put(90000, 147); - this.put(90100, 158); - this.put(90200, 120); - this.put(90300, 132); - this.put(90400, 180); - this.put(90500, 86); - this.put(90600, 78); - this.put(90700, 103); - this.put(90800, 107); - this.put(90900, 98); - this.put(91000, 111); - this.put(91100, 116); - this.put(91200, 100); - this.put(91300, 82); - this.put(91400, 86); - this.put(91500, 91); - this.put(91600, 144); - this.put(91700, 135); - this.put(91800, 90); - this.put(91900, 125); - this.put(92000, 152); - this.put(92100, 108); - this.put(92200, 141); - this.put(92300, 102); - this.put(92400, 86); - this.put(92500, 93); - this.put(92600, 107); - this.put(92700, 98); - this.put(92800, 130); - this.put(92900, 122); - this.put(93000, 117); - this.put(93100, 87); - this.put(93200, 109); - this.put(93300, 163); - this.put(93400, 175); - this.put(93500, 165); - this.put(93600, 130); - this.put(93700, 176); - this.put(93800, 127); - this.put(93900, 144); - this.put(94000, 84); - this.put(94100, 96); - this.put(94200, 84); - this.put(94300, 76); - this.put(94400, 111); - this.put(94500, 82); - this.put(94600, 53); - this.put(94700, 87); - this.put(94800, 77); - this.put(94900, 78); - this.put(95000, 75); - this.put(95100, 61); - this.put(95200, 110); - this.put(95300, 124); - this.put(95400, 104); - this.put(95500, 84); - this.put(95600, 77); - this.put(95700, 99); - this.put(95800, 81); - this.put(95900, 72); - this.put(96000, 99); - this.put(96100, 103); - this.put(96200, 86); - this.put(96300, 93); - this.put(96400, 102); - this.put(96500, 102); - this.put(96600, 79); - this.put(96700, 91); - this.put(96800, 114); - this.put(96900, 79); - this.put(97000, 118); - this.put(97100, 79); - this.put(97200, 96); - this.put(97300, 124); - this.put(97400, 113); - this.put(97500, 121); - this.put(97600, 67); - this.put(97700, 73); - this.put(97800, 67); - this.put(97900, 68); - this.put(98000, 70); - this.put(98100, 43); - this.put(98200, 72); - this.put(98300, 60); - this.put(98400, 76); - this.put(98500, 58); - this.put(98600, 79); - this.put(98700, 75); - this.put(98800, 76); - this.put(98900, 77); - this.put(99000, 55); - this.put(99100, 83); - this.put(99200, 71); - this.put(99300, 86); - this.put(99400, 60); - this.put(99500, 74); - this.put(99600, 48); - this.put(99700, 61); - this.put(99800, 94); - this.put(99900, 85); - this.put(100000, 372); -// this.put(101000, 660); -// this.put(102000, 513); -// this.put(103000, 500); -// this.put(104000, 573); -// this.put(105000, 573); -// this.put(106000, 450); -// this.put(107000, 471); -// this.put(108000, 496); -// this.put(109000, 471); -// this.put(110000, 424); -// this.put(111000, 322); -// this.put(112000, 374); -// this.put(113000, 332); -// this.put(114000, 361); -// this.put(115000, 330); -// this.put(116000, 388); -// this.put(117000, 336); -// this.put(118000, 417); -// this.put(119000, 348); -// this.put(120000, 273); -// this.put(121000, 305); -// this.put(122000, 255); -// this.put(123000, 220); -// this.put(124000, 253); -// this.put(125000, 272); -// this.put(126000, 261); -// this.put(127000, 274); -// this.put(128000, 251); -// this.put(129000, 232); -// this.put(130000, 233); -// this.put(131000, 296); -// this.put(132000, 276); -// this.put(133000, 294); -// this.put(134000, 260); -// this.put(135000, 240); -// this.put(136000, 247); -// this.put(137000, 231); -// this.put(138000, 245); -// this.put(139000, 189); -// this.put(140000, 239); -// this.put(141000, 216); -// this.put(142000, 247); -// this.put(143000, 280); -// this.put(144000, 310); -// this.put(145000, 335); -// this.put(146000, 281); -// this.put(147000, 271); -// this.put(148000, 277); -// this.put(149000, 196); -// this.put(150000, 200); -// this.put(151000, 204); -// this.put(152000, 277); -// this.put(153000, 245); -// this.put(154000, 325); -// this.put(155000, 353); -// this.put(156000, 454); -// this.put(157000, 253); -// this.put(158000, 201); -// this.put(159000, 215); -// this.put(160000, 233); -// this.put(161000, 438); -// this.put(162000, 397); -// this.put(163000, 283); -// this.put(164000, 185); -// this.put(165000, 250); -// this.put(166000, 120); -// this.put(167000, 114); -// this.put(168000, 122); -// this.put(169000, 169); -// this.put(170000, 142); -// this.put(171000, 165); -// this.put(172000, 249); -// this.put(173000, 147); -// this.put(174000, 156); -// this.put(175000, 157); -// this.put(176000, 162); -// this.put(177000, 164); -// this.put(178000, 172); -// this.put(179000, 156); -// this.put(180000, 128); -// this.put(181000, 133); -// this.put(182000, 125); -// this.put(183000, 144); -// this.put(184000, 105); -// this.put(185000, 96); -// this.put(186000, 101); -// this.put(187000, 117); -// this.put(188000, 83); -// this.put(189000, 84); -// this.put(190000, 61); -// this.put(191000, 82); -// this.put(192000, 86); -// this.put(193000, 80); -// this.put(194000, 111); -// this.put(195000, 114); -// this.put(196000, 102); -// this.put(197000, 122); -// this.put(198000, 84); -// this.put(199000, 109); -// this.put(200000, 123); -// this.put(201000, 102); -// this.put(202000, 114); -// this.put(203000, 113); -// this.put(204000, 133); -// this.put(205000, 132); -// this.put(206000, 96); -// this.put(207000, 92); -// this.put(208000, 96); -// this.put(209000, 90); -// this.put(210000, 83); -// this.put(211000, 76); -// this.put(212000, 104); -// this.put(213000, 85); -// this.put(214000, 92); -// this.put(215000, 90); -// this.put(216000, 97); -// this.put(217000, 102); -// this.put(218000, 90); -// this.put(219000, 83); -// this.put(220000, 70); -// this.put(221000, 52); -// this.put(222000, 70); -// this.put(223000, 72); -// this.put(224000, 76); -// this.put(225000, 83); -// this.put(226000, 76); -// this.put(227000, 107); -// this.put(228000, 81); -// this.put(229000, 78); -// this.put(230000, 87); -// this.put(231000, 61); -// this.put(232000, 73); -// this.put(233000, 70); -// this.put(234000, 71); -// this.put(235000, 69); -// this.put(236000, 51); -// this.put(237000, 54); -// this.put(238000, 60); -// this.put(239000, 48); -// this.put(240000, 38); -// this.put(241000, 38); -// this.put(242000, 47); -// this.put(243000, 53); -// this.put(244000, 53); -// this.put(245000, 44); -// this.put(246000, 57); -// this.put(247000, 60); -// this.put(248000, 45); -// this.put(249000, 43); -// this.put(250000, 45); -// this.put(251000, 55); -// this.put(252000, 52); -// this.put(253000, 52); -// this.put(254000, 39); -// this.put(255000, 41); -// this.put(256000, 41); -// this.put(257000, 38); -// this.put(258000, 30); -// this.put(259000, 23); -// this.put(260000, 45); -// this.put(261000, 31); -// this.put(262000, 48); -// this.put(263000, 51); -// this.put(264000, 36); -// this.put(265000, 39); -// this.put(266000, 31); -// this.put(267000, 33); -// this.put(268000, 32); -// this.put(269000, 30); -// this.put(270000, 43); -// this.put(271000, 33); -// this.put(272000, 37); -// this.put(273000, 28); -// this.put(274000, 30); -// this.put(275000, 36); -// this.put(276000, 33); -// this.put(277000, 33); -// this.put(278000, 25); -// this.put(279000, 23); -// this.put(280000, 24); -// this.put(281000, 15); -// this.put(282000, 22); -// this.put(283000, 28); -// this.put(284000, 18); -// this.put(285000, 16); -// this.put(286000, 22); -// this.put(287000, 23); -// this.put(288000, 31); -// this.put(289000, 20); -// this.put(290000, 25); -// this.put(291000, 31); -// this.put(292000, 23); -// this.put(293000, 24); -// this.put(294000, 20); -// this.put(295000, 42); -// this.put(296000, 27); -// this.put(297000, 20); -// this.put(298000, 20); -// this.put(299000, 31); -// this.put(300000, 15); -// this.put(301000, 24); -// this.put(302000, 19); -// this.put(303000, 17); -// this.put(304000, 10); -// this.put(305000, 15); -// this.put(306000, 17); -// this.put(307000, 22); -// this.put(308000, 44); -// this.put(309000, 33); -// this.put(310000, 19); -// this.put(311000, 26); -// this.put(312000, 46); -// this.put(313000, 26); -// this.put(314000, 19); -// this.put(315000, 12); -// this.put(316000, 16); -// this.put(317000, 17); -// this.put(318000, 19); -// this.put(319000, 20); -// this.put(320000, 10); -// this.put(321000, 25); -// this.put(322000, 22); -// this.put(323000, 26); -// this.put(324000, 22); -// this.put(325000, 13); -// this.put(326000, 21); -// this.put(327000, 22); -// this.put(328000, 24); -// this.put(329000, 15); -// this.put(330000, 20); -// this.put(331000, 27); -// this.put(332000, 25); -// this.put(333000, 21); -// this.put(334000, 27); -// this.put(335000, 23); -// this.put(336000, 16); -// this.put(337000, 30); -// this.put(338000, 20); -// this.put(339000, 22); -// this.put(340000, 22); -// this.put(341000, 17); -// this.put(342000, 11); -// this.put(343000, 25); -// this.put(344000, 17); -// this.put(345000, 13); -// this.put(346000, 16); -// this.put(347000, 12); -// this.put(348000, 18); -// this.put(349000, 13); -// this.put(350000, 9); -// this.put(351000, 13); -// this.put(352000, 13); -// this.put(353000, 26); -// this.put(354000, 19); -// this.put(355000, 18); -// this.put(356000, 19); -// this.put(357000, 15); -// this.put(358000, 10); -// this.put(359000, 21); -// this.put(360000, 16); -// this.put(361000, 14); -// this.put(362000, 20); -// this.put(363000, 13); -// this.put(364000, 15); -// this.put(365000, 26); -// this.put(366000, 22); -// this.put(367000, 20); -// this.put(368000, 8); -// this.put(369000, 12); -// this.put(370000, 11); -// this.put(371000, 23); -// this.put(372000, 22); -// this.put(373000, 7); -// this.put(374000, 6); -// this.put(375000, 10); -// this.put(376000, 8); -// this.put(377000, 12); -// this.put(378000, 13); -// this.put(379000, 10); -// this.put(380000, 19); -// this.put(381000, 23); -// this.put(382000, 31); -// this.put(383000, 9); -// this.put(384000, 17); -// this.put(385000, 16); -// this.put(386000, 16); -// this.put(387000, 12); -// this.put(388000, 16); -// this.put(389000, 14); -// this.put(390000, 18); -// this.put(391000, 9); -// this.put(392000, 9); -// this.put(393000, 15); -// this.put(394000, 9); -// this.put(395000, 7); -// this.put(396000, 4); -// this.put(397000, 9); -// this.put(398000, 11); -// this.put(399000, 5); -// this.put(400000, 7); -// this.put(401000, 4); -// this.put(402000, 9); -// this.put(403000, 6); -// this.put(404000, 7); -// this.put(405000, 17); -// this.put(406000, 7); -// this.put(407000, 17); -// this.put(408000, 6); -// this.put(409000, 9); -// this.put(410000, 6); -// this.put(411000, 10); -// this.put(412000, 7); -// this.put(413000, 4); -// this.put(414000, 5); -// this.put(415000, 10); -// this.put(416000, 12); -// this.put(417000, 13); -// this.put(418000, 6); -// this.put(419000, 9); -// this.put(420000, 12); -// this.put(421000, 5); -// this.put(422000, 3); -// this.put(423000, 7); -// this.put(424000, 10); -// this.put(425000, 6); -// this.put(426000, 4); -// this.put(427000, 11); -// this.put(429000, 1); -// this.put(430000, 4); -// this.put(431000, 2); -// this.put(432000, 2); -// this.put(433000, 3); -// this.put(434000, 3); -// this.put(435000, 2); -// this.put(436000, 6); -// this.put(437000, 7); -// this.put(438000, 3); -// this.put(439000, 4); -// this.put(440000, 5); -// this.put(441000, 2); -// this.put(442000, 4); -// this.put(443000, 2); -// this.put(444000, 7); -// this.put(445000, 5); -// this.put(446000, 3); -// this.put(447000, 3); -// this.put(448000, 4); -// this.put(449000, 3); -// this.put(451000, 1); -// this.put(455000, 1); -// this.put(457000, 2); -// this.put(458000, 1); -// this.put(460000, 1); -// this.put(466000, 1); -// this.put(467000, 1); -// this.put(468000, 2); -// this.put(470000, 2); -// this.put(471000, 2); -// this.put(472000, 1); -// this.put(473000, 2); -// this.put(475000, 1); -// this.put(476000, 2); -// this.put(478000, 1); -// this.put(481000, 4); -// this.put(482000, 4); -// this.put(483000, 4); -// this.put(484000, 6); -// this.put(485000, 3); -// this.put(486000, 6); -// this.put(487000, 7); -// this.put(488000, 3); -// this.put(489000, 2); -// this.put(490000, 1); -// this.put(491000, 1); -// this.put(492000, 9); -// this.put(493000, 15); -// this.put(494000, 2); -// this.put(495000, 8); -// this.put(496000, 13); -// this.put(497000, 1); -// this.put(498000, 2); -// this.put(499000, 1); -// this.put(500000, 2); -// this.put(501000, 1); -// this.put(502000, 5); -// this.put(503000, 3); -// this.put(504000, 3); -// this.put(505000, 3); -// this.put(506000, 1); -// this.put(507000, 3); -// this.put(508000, 3); -// this.put(509000, 9); -// this.put(510000, 6); -// this.put(511000, 2); -// this.put(513000, 1); -// this.put(514000, 6); -// this.put(515000, 1); -// this.put(518000, 1); -// this.put(520000, 1); -// this.put(522000, 1); -// this.put(524000, 2); -// this.put(527000, 1); -// this.put(529000, 1); -// this.put(531000, 1); -// this.put(533000, 1); -// this.put(536000, 1); -// this.put(538000, 1); -// this.put(540000, 1); -// this.put(542000, 1); -// this.put(543000, 1); -// this.put(544000, 1); -// this.put(546000, 1); -// this.put(547000, 1); -// this.put(548000, 1); -// this.put(549000, 1); -// this.put(551000, 1); -// this.put(553000, 1); -// this.put(555000, 1); -// this.put(557000, 1); -// this.put(559000, 2); -// this.put(560000, 1); -// this.put(561000, 3); -// this.put(562000, 1); -// this.put(563000, 1); -// this.put(564000, 7); -// this.put(565000, 1); -// this.put(566000, 2); -// this.put(567000, 1); -// this.put(568000, 1); -// this.put(570000, 1); -// this.put(573000, 1); -// this.put(574000, 1); -// this.put(576000, 1); -// this.put(577000, 1); -// this.put(579000, 3); -// this.put(580000, 1); -// this.put(581000, 1); -// this.put(582000, 2); -// this.put(583000, 3); -// this.put(584000, 2); -// this.put(585000, 1); -// this.put(587000, 1); -// this.put(588000, 1); -// this.put(589000, 1); -// this.put(590000, 1); -// this.put(591000, 1); -// this.put(592000, 2); -// this.put(593000, 1); -// this.put(594000, 5); -// this.put(596000, 1); -// this.put(598000, 1); -// this.put(599000, 3); -// this.put(601000, 2); -// this.put(603000, 1); -// this.put(605000, 2); -// this.put(607000, 1); -// this.put(609000, 1); -// this.put(611000, 1); -// this.put(613000, 1); -// this.put(615000, 1); -// this.put(617000, 1); -// this.put(619000, 1); -// this.put(621000, 1); -// this.put(623000, 1); -// this.put(626000, 1); -// this.put(628000, 1); -// this.put(630000, 1); -// this.put(632000, 1); -// this.put(634000, 1); -// this.put(636000, 1); -// this.put(638000, 1); -// this.put(640000, 1); -// this.put(643000, 1); -// this.put(645000, 2); -// this.put(647000, 5); -// this.put(648000, 1); -// this.put(649000, 1); -// this.put(651000, 4); -// this.put(653000, 7); -// this.put(663000, 1); -// this.put(674000, 2); -// this.put(676000, 1); -// this.put(679000, 1); -// this.put(690000, 1); -// this.put(695000, 1); -// this.put(699000, 2); -// this.put(702000, 1); -// this.put(727000, 1); -// this.put(729000, 1); -// this.put(744000, 1); -// this.put(748000, 2); -// this.put(805000, 1); -// this.put(835000, 1); -// this.put(838000, 3); -// this.put(839000, 3); -// this.put(840000, 6); -// this.put(841000, 1); -// this.put(842000, 3); -// this.put(843000, 4); -// this.put(844000, 4); -// this.put(845000, 1); -// this.put(846000, 4); -// this.put(847000, 3); -// this.put(848000, 2); -// this.put(849000, 2); -// this.put(850000, 1); -// this.put(851000, 1); -// this.put(864000, 1); -// this.put(951000, 1); -// this.put(979000, 1); -// this.put(985000, 1); -// this.put(1040000, 1); + this.put(100, 52106); + this.put(200, 32370); + this.put(300, 20377); + this.put(400, 21345); + this.put(500, 21532); + this.put(600, 21124); + this.put(700, 20805); + this.put(800, 19312); + this.put(900, 19080); + this.put(1000, 19137); + this.put(1100, 18852); + this.put(1200, 17861); + this.put(1300, 16929); + this.put(1400, 17723); + this.put(1500, 16713); + this.put(1600, 15420); + this.put(1700, 15267); + this.put(1800, 14782); + this.put(1900, 13870); + this.put(2000, 13838); + this.put(2100, 13498); + this.put(2200, 12667); + this.put(2300, 12383); + this.put(2400, 12217); + this.put(2500, 12394); + this.put(2600, 12306); + this.put(2700, 11977); + this.put(2800, 11427); + this.put(2900, 10639); + this.put(3000, 10339); + this.put(3100, 10086); + this.put(3200, 9851); + this.put(3300, 9722); + this.put(3400, 9155); + this.put(3500, 9124); + this.put(3600, 8879); + this.put(3700, 8676); + this.put(3800, 8335); + this.put(3900, 8158); + this.put(4000, 7984); + this.put(4100, 7844); + this.put(4200, 7415); + this.put(4300, 7234); + this.put(4400, 7199); + this.put(4500, 6958); + this.put(4600, 7457); + this.put(4700, 7099); + this.put(4800, 7175); + this.put(4900, 6776); + this.put(5000, 6573); + this.put(5100, 6525); + this.put(5200, 6019); + this.put(5300, 6246); + this.put(5400, 6315); + this.put(5500, 5942); + this.put(5600, 5772); + this.put(5700, 6040); + this.put(5800, 5892); + this.put(5900, 5610); + this.put(6000, 5420); + this.put(6100, 5507); + this.put(6200, 5418); + this.put(6300, 5229); + this.put(6400, 5426); + this.put(6500, 5226); + this.put(6600, 4980); + this.put(6700, 5067); + this.put(6800, 4889); + this.put(6900, 4712); + this.put(7000, 4442); + this.put(7100, 4274); + this.put(7200, 4510); + this.put(7300, 4370); + this.put(7400, 4684); + this.put(7500, 4323); + this.put(7600, 4232); + this.put(7700, 4595); + this.put(7800, 4563); + this.put(7900, 3973); + this.put(8000, 4124); + this.put(8100, 4165); + this.put(8200, 4190); + this.put(8300, 4046); + this.put(8400, 3943); + this.put(8500, 4054); + this.put(8600, 4014); + this.put(8700, 3770); + this.put(8800, 3736); + this.put(8900, 3656); + this.put(9000, 3604); + this.put(9100, 3411); + this.put(9200, 3634); + this.put(9300, 3506); + this.put(9400, 3655); + this.put(9500, 3288); + this.put(9600, 3052); + this.put(9700, 3305); + this.put(9800, 3176); + this.put(9900, 2962); + this.put(10000, 2882); + this.put(10100, 2926); + this.put(10200, 3069); + this.put(10300, 2876); + this.put(10400, 2897); + this.put(10500, 2821); + this.put(10600, 3081); + this.put(10700, 2832); + this.put(10800, 2837); + this.put(10900, 2950); + this.put(11000, 2938); + this.put(11100, 2907); + this.put(11200, 2987); + this.put(11300, 2833); + this.put(11400, 2602); + this.put(11500, 2653); + this.put(11600, 2738); + this.put(11700, 2590); + this.put(11800, 2531); + this.put(11900, 2468); + this.put(12000, 2409); + this.put(12100, 2364); + this.put(12200, 2533); + this.put(12300, 2400); + this.put(12400, 2504); + this.put(12500, 2360); + this.put(12600, 2251); + this.put(12700, 2164); + this.put(12800, 2131); + this.put(12900, 2205); + this.put(13000, 2147); + this.put(13100, 2300); + this.put(13200, 2353); + this.put(13300, 2317); + this.put(13400, 2210); + this.put(13500, 2229); + this.put(13600, 2152); + this.put(13700, 2234); + this.put(13800, 2197); + this.put(13900, 2003); + this.put(14000, 2059); + this.put(14100, 2027); + this.put(14200, 1974); + this.put(14300, 2029); + this.put(14400, 1989); + this.put(14500, 1913); + this.put(14600, 2002); + this.put(14700, 1986); + this.put(14800, 2041); + this.put(14900, 2134); + this.put(15000, 2059); + this.put(15100, 2051); + this.put(15200, 2181); + this.put(15300, 2098); + this.put(15400, 1817); + this.put(15500, 1997); + this.put(15600, 2191); + this.put(15700, 1798); + this.put(15800, 1821); + this.put(15900, 1861); + this.put(16000, 1762); + this.put(16100, 1817); + this.put(16200, 1816); + this.put(16300, 1648); + this.put(16400, 1542); + this.put(16500, 1682); + this.put(16600, 1586); + this.put(16700, 1483); + this.put(16800, 1621); + this.put(16900, 1684); + this.put(17000, 1819); + this.put(17100, 1802); + this.put(17200, 1796); + this.put(17300, 1631); + this.put(17400, 1652); + this.put(17500, 1599); + this.put(17600, 1764); + this.put(17700, 1653); + this.put(17800, 1573); + this.put(17900, 1587); + this.put(18000, 1756); + this.put(18100, 1729); + this.put(18200, 1731); + this.put(18300, 1599); + this.put(18400, 1593); + this.put(18500, 1553); + this.put(18600, 1439); + this.put(18700, 1424); + this.put(18800, 1375); + this.put(18900, 1530); + this.put(19000, 1392); + this.put(19100, 1457); + this.put(19200, 1461); + this.put(19300, 1502); + this.put(19400, 1494); + this.put(19500, 1716); + this.put(19600, 1542); + this.put(19700, 1447); + this.put(19800, 1356); + this.put(19900, 1469); + this.put(20000, 1371); + this.put(20100, 1467); + this.put(20200, 1484); + this.put(20300, 1504); + this.put(20400, 1467); + this.put(20500, 1486); + this.put(20600, 1363); + this.put(20700, 1468); + this.put(20800, 1497); + this.put(20900, 1393); + this.put(21000, 1294); + this.put(21100, 1351); + this.put(21200, 1352); + this.put(21300, 1306); + this.put(21400, 1259); + this.put(21500, 1302); + this.put(21600, 1132); + this.put(21700, 1126); + this.put(21800, 1125); + this.put(21900, 1151); + this.put(22000, 1083); + this.put(22100, 1051); + this.put(22200, 1090); + this.put(22300, 985); + this.put(22400, 1311); + this.put(22500, 1181); + this.put(22600, 1060); + this.put(22700, 1304); + this.put(22800, 1160); + this.put(22900, 1196); + this.put(23000, 1297); + this.put(23100, 1291); + this.put(23200, 1394); + this.put(23300, 1217); + this.put(23400, 1184); + this.put(23500, 1298); + this.put(23600, 1206); + this.put(23700, 1115); + this.put(23800, 1269); + this.put(23900, 1108); + this.put(24000, 1145); + this.put(24100, 1167); + this.put(24200, 1128); + this.put(24300, 1138); + this.put(24400, 1215); + this.put(24500, 1205); + this.put(24600, 1202); + this.put(24700, 1095); + this.put(24800, 1194); + this.put(24900, 1152); + this.put(25000, 1214); + this.put(25100, 1096); + this.put(25200, 966); + this.put(25300, 1144); + this.put(25400, 1146); + this.put(25500, 917); + this.put(25600, 1213); + this.put(25700, 980); + this.put(25800, 958); + this.put(25900, 964); + this.put(26000, 1106); + this.put(26100, 1131); + this.put(26200, 885); + this.put(26300, 986); + this.put(26400, 1062); + this.put(26500, 1035); + this.put(26600, 1083); + this.put(26700, 1223); + this.put(26800, 1201); + this.put(26900, 1059); + this.put(27000, 955); + this.put(27100, 1106); + this.put(27200, 989); + this.put(27300, 979); + this.put(27400, 1021); + this.put(27500, 1128); + this.put(27600, 1118); + this.put(27700, 1018); + this.put(27800, 1042); + this.put(27900, 988); + this.put(28000, 1030); + this.put(28100, 969); + this.put(28200, 1005); + this.put(28300, 1114); + this.put(28400, 970); + this.put(28500, 1081); + this.put(28600, 900); + this.put(28700, 902); + this.put(28800, 957); + this.put(28900, 992); + this.put(29000, 1080); + this.put(29100, 923); + this.put(29200, 886); + this.put(29300, 932); + this.put(29400, 1000); + this.put(29500, 912); + this.put(29600, 939); + this.put(29700, 888); + this.put(29800, 1051); + this.put(29900, 933); + this.put(30000, 778); + this.put(30100, 879); + this.put(30200, 902); + this.put(30300, 917); + this.put(30400, 991); + this.put(30500, 836); + this.put(30600, 901); + this.put(30700, 780); + this.put(30800, 703); + this.put(30900, 854); + this.put(31000, 860); + this.put(31100, 807); + this.put(31200, 723); + this.put(31300, 764); + this.put(31400, 786); + this.put(31500, 770); + this.put(31600, 728); + this.put(31700, 721); + this.put(31800, 734); + this.put(31900, 726); + this.put(32000, 784); + this.put(32100, 733); + this.put(32200, 880); + this.put(32300, 761); + this.put(32400, 826); + this.put(32500, 861); + this.put(32600, 649); + this.put(32700, 664); + this.put(32800, 693); + this.put(32900, 720); + this.put(33000, 845); + this.put(33100, 836); + this.put(33200, 898); + this.put(33300, 871); + this.put(33400, 775); + this.put(33500, 699); + this.put(33600, 762); + this.put(33700, 756); + this.put(33800, 800); + this.put(33900, 825); + this.put(34000, 812); + this.put(34100, 665); + this.put(34200, 795); + this.put(34300, 712); + this.put(34400, 872); + this.put(34500, 736); + this.put(34600, 873); + this.put(34700, 715); + this.put(34800, 763); + this.put(34900, 746); + this.put(35000, 838); + this.put(35100, 957); + this.put(35200, 908); + this.put(35300, 776); + this.put(35400, 829); + this.put(35500, 755); + this.put(35600, 715); + this.put(35700, 662); + this.put(35800, 638); + this.put(35900, 723); + this.put(36000, 648); + this.put(36100, 567); + this.put(36200, 620); + this.put(36300, 684); + this.put(36400, 595); + this.put(36500, 605); + this.put(36600, 765); + this.put(36700, 632); + this.put(36800, 661); + this.put(36900, 662); + this.put(37000, 562); + this.put(37100, 556); + this.put(37200, 545); + this.put(37300, 597); + this.put(37400, 582); + this.put(37500, 606); + this.put(37600, 564); + this.put(37700, 558); + this.put(37800, 504); + this.put(37900, 533); + this.put(38000, 512); + this.put(38100, 597); + this.put(38200, 447); + this.put(38300, 504); + this.put(38400, 565); + this.put(38500, 528); + this.put(38600, 579); + this.put(38700, 607); + this.put(38800, 448); + this.put(38900, 496); + this.put(39000, 563); + this.put(39100, 459); + this.put(39200, 521); + this.put(39300, 673); + this.put(39400, 456); + this.put(39500, 441); + this.put(39600, 540); + this.put(39700, 521); + this.put(39800, 560); + this.put(39900, 499); + this.put(40000, 652); + this.put(40100, 540); + this.put(40200, 539); + this.put(40300, 521); + this.put(40400, 443); + this.put(40500, 498); + this.put(40600, 509); + this.put(40700, 654); + this.put(40800, 520); + this.put(40900, 502); + this.put(41000, 485); + this.put(41100, 378); + this.put(41200, 393); + this.put(41300, 368); + this.put(41400, 350); + this.put(41500, 383); + this.put(41600, 357); + this.put(41700, 384); + this.put(41800, 442); + this.put(41900, 433); + this.put(42000, 456); + this.put(42100, 704); + this.put(42200, 432); + this.put(42300, 304); + this.put(42400, 354); + this.put(42500, 327); + this.put(42600, 435); + this.put(42700, 488); + this.put(42800, 407); + this.put(42900, 389); + this.put(43000, 453); + this.put(43100, 375); + this.put(43200, 325); + this.put(43300, 365); + this.put(43400, 398); + this.put(43500, 364); + this.put(43600, 424); + this.put(43700, 358); + this.put(43800, 442); + this.put(43900, 511); + this.put(44000, 395); + this.put(44100, 411); + this.put(44200, 441); + this.put(44300, 409); + this.put(44400, 323); + this.put(44500, 396); + this.put(44600, 456); + this.put(44700, 403); + this.put(44800, 420); + this.put(44900, 452); + this.put(45000, 430); + this.put(45100, 387); + this.put(45200, 444); + this.put(45300, 470); + this.put(45400, 432); + this.put(45500, 415); + this.put(45600, 354); + this.put(45700, 611); + this.put(45800, 424); + this.put(45900, 487); + this.put(46000, 547); + this.put(46100, 462); + this.put(46200, 310); + this.put(46300, 353); + this.put(46400, 311); + this.put(46500, 355); + this.put(46600, 373); + this.put(46700, 396); + this.put(46800, 401); + this.put(46900, 387); + this.put(47000, 369); + this.put(47100, 406); + this.put(47200, 331); + this.put(47300, 408); + this.put(47400, 348); + this.put(47500, 353); + this.put(47600, 454); + this.put(47700, 297); + this.put(47800, 342); + this.put(47900, 334); + this.put(48000, 361); + this.put(48100, 374); + this.put(48200, 371); + this.put(48300, 421); + this.put(48400, 400); + this.put(48500, 542); + this.put(48600, 387); + this.put(48700, 329); + this.put(48800, 397); + this.put(48900, 375); + this.put(49000, 354); + this.put(49100, 349); + this.put(49200, 312); + this.put(49300, 359); + this.put(49400, 385); + this.put(49500, 340); + this.put(49600, 284); + this.put(49700, 294); + this.put(49800, 243); + this.put(49900, 306); + this.put(50000, 355); + this.put(50100, 280); + this.put(50200, 318); + this.put(50300, 312); + this.put(50400, 302); + this.put(50500, 309); + this.put(50600, 310); + this.put(50700, 255); + this.put(50800, 287); + this.put(50900, 292); + this.put(51000, 272); + this.put(51100, 361); + this.put(51200, 370); + this.put(51300, 337); + this.put(51400, 323); + this.put(51500, 337); + this.put(51600, 367); + this.put(51700, 370); + this.put(51800, 328); + this.put(51900, 280); + this.put(52000, 294); + this.put(52100, 194); + this.put(52200, 346); + this.put(52300, 335); + this.put(52400, 292); + this.put(52500, 255); + this.put(52600, 244); + this.put(52700, 216); + this.put(52800, 222); + this.put(52900, 230); + this.put(53000, 247); + this.put(53100, 311); + this.put(53200, 294); + this.put(53300, 355); + this.put(53400, 425); + this.put(53500, 348); + this.put(53600, 299); + this.put(53700, 298); + this.put(53800, 348); + this.put(53900, 280); + this.put(54000, 386); + this.put(54100, 352); + this.put(54200, 290); + this.put(54300, 266); + this.put(54400, 240); + this.put(54500, 280); + this.put(54600, 286); + this.put(54700, 267); + this.put(54800, 254); + this.put(54900, 306); + this.put(55000, 251); + this.put(55100, 246); + this.put(55200, 238); + this.put(55300, 236); + this.put(55400, 224); + this.put(55500, 173); + this.put(55600, 177); + this.put(55700, 211); + this.put(55800, 186); + this.put(55900, 219); + this.put(56000, 246); + this.put(56100, 224); + this.put(56200, 247); + this.put(56300, 157); + this.put(56400, 184); + this.put(56500, 204); + this.put(56600, 188); + this.put(56700, 203); + this.put(56800, 187); + this.put(56900, 211); + this.put(57000, 158); + this.put(57100, 218); + this.put(57200, 222); + this.put(57300, 253); + this.put(57400, 298); + this.put(57500, 301); + this.put(57600, 264); + this.put(57700, 196); + this.put(57800, 232); + this.put(57900, 202); + this.put(58000, 215); + this.put(58100, 223); + this.put(58200, 217); + this.put(58300, 227); + this.put(58400, 243); + this.put(58500, 321); + this.put(58600, 326); + this.put(58700, 245); + this.put(58800, 325); + this.put(58900, 276); + this.put(59000, 268); + this.put(59100, 274); + this.put(59200, 291); + this.put(59300, 269); + this.put(59400, 306); + this.put(59500, 218); + this.put(59600, 256); + this.put(59700, 247); + this.put(59800, 388); + this.put(59900, 427); + this.put(60000, 282); + this.put(60100, 266); + this.put(60200, 291); + this.put(60300, 312); + this.put(60400, 294); + this.put(60500, 277); + this.put(60600, 353); + this.put(60700, 350); + this.put(60800, 335); + this.put(60900, 418); + this.put(61000, 305); + this.put(61100, 402); + this.put(61200, 330); + this.put(61300, 282); + this.put(61400, 313); + this.put(61500, 211); + this.put(61600, 281); + this.put(61700, 271); + this.put(61800, 242); + this.put(61900, 285); + this.put(62000, 277); + this.put(62100, 254); + this.put(62200, 264); + this.put(62300, 382); + this.put(62400, 292); + this.put(62500, 292); + this.put(62600, 215); + this.put(62700, 219); + this.put(62800, 236); + this.put(62900, 205); + this.put(63000, 224); + this.put(63100, 246); + this.put(63200, 232); + this.put(63300, 231); + this.put(63400, 212); + this.put(63500, 226); + this.put(63600, 306); + this.put(63700, 228); + this.put(63800, 203); + this.put(63900, 260); + this.put(64000, 260); + this.put(64100, 262); + this.put(64200, 231); + this.put(64300, 346); + this.put(64400, 282); + this.put(64500, 238); + this.put(64600, 168); + this.put(64700, 243); + this.put(64800, 335); + this.put(64900, 282); + this.put(65000, 360); + this.put(65100, 268); + this.put(65200, 271); + this.put(65300, 370); + this.put(65400, 226); + this.put(65500, 240); + this.put(65600, 196); + this.put(65700, 178); + this.put(65800, 224); + this.put(65900, 154); + this.put(66000, 190); + this.put(66100, 173); + this.put(66200, 197); + this.put(66300, 137); + this.put(66400, 209); + this.put(66500, 222); + this.put(66600, 213); + this.put(66700, 152); + this.put(66800, 205); + this.put(66900, 158); + this.put(67000, 179); + this.put(67100, 146); + this.put(67200, 148); + this.put(67300, 230); + this.put(67400, 196); + this.put(67500, 141); + this.put(67600, 190); + this.put(67700, 264); + this.put(67800, 161); + this.put(67900, 124); + this.put(68000, 168); + this.put(68100, 144); + this.put(68200, 146); + this.put(68300, 230); + this.put(68400, 256); + this.put(68500, 175); + this.put(68600, 233); + this.put(68700, 177); + this.put(68800, 213); + this.put(68900, 220); + this.put(69000, 217); + this.put(69100, 296); + this.put(69200, 199); + this.put(69300, 267); + this.put(69400, 310); + this.put(69500, 184); + this.put(69600, 209); + this.put(69700, 246); + this.put(69800, 183); + this.put(69900, 199); + this.put(70000, 162); + this.put(70100, 210); + this.put(70200, 141); + this.put(70300, 135); + this.put(70400, 188); + this.put(70500, 255); + this.put(70600, 195); + this.put(70700, 210); + this.put(70800, 205); + this.put(70900, 301); + this.put(71000, 295); + this.put(71100, 270); + this.put(71200, 179); + this.put(71300, 156); + this.put(71400, 214); + this.put(71500, 289); + this.put(71600, 246); + this.put(71700, 192); + this.put(71800, 176); + this.put(71900, 273); + this.put(72000, 168); + this.put(72100, 196); + this.put(72200, 237); + this.put(72300, 199); + this.put(72400, 178); + this.put(72500, 190); + this.put(72600, 156); + this.put(72700, 131); + this.put(72800, 161); + this.put(72900, 183); + this.put(73000, 204); + this.put(73100, 226); + this.put(73200, 138); + this.put(73300, 144); + this.put(73400, 195); + this.put(73500, 195); + this.put(73600, 112); + this.put(73700, 183); + this.put(73800, 174); + this.put(73900, 194); + this.put(74000, 222); + this.put(74100, 224); + this.put(74200, 181); + this.put(74300, 204); + this.put(74400, 195); + this.put(74500, 153); + this.put(74600, 187); + this.put(74700, 162); + this.put(74800, 152); + this.put(74900, 190); + this.put(75000, 178); + this.put(75100, 203); + this.put(75200, 173); + this.put(75300, 220); + this.put(75400, 260); + this.put(75500, 189); + this.put(75600, 156); + this.put(75700, 158); + this.put(75800, 167); + this.put(75900, 173); + this.put(76000, 110); + this.put(76100, 152); + this.put(76200, 169); + this.put(76300, 213); + this.put(76400, 186); + this.put(76500, 156); + this.put(76600, 152); + this.put(76700, 209); + this.put(76800, 196); + this.put(76900, 198); + this.put(77000, 232); + this.put(77100, 245); + this.put(77200, 262); + this.put(77300, 180); + this.put(77400, 177); + this.put(77500, 173); + this.put(77600, 171); + this.put(77700, 134); + this.put(77800, 217); + this.put(77900, 199); + this.put(78000, 140); + this.put(78100, 120); + this.put(78200, 149); + this.put(78300, 110); + this.put(78400, 117); + this.put(78500, 159); + this.put(78600, 113); + this.put(78700, 128); + this.put(78800, 182); + this.put(78900, 180); + this.put(79000, 162); + this.put(79100, 171); + this.put(79200, 133); + this.put(79300, 193); + this.put(79400, 168); + this.put(79500, 142); + this.put(79600, 102); + this.put(79700, 131); + this.put(79800, 108); + this.put(79900, 126); + this.put(80000, 102); + this.put(80100, 157); + this.put(80200, 124); + this.put(80300, 137); + this.put(80400, 120); + this.put(80500, 116); + this.put(80600, 119); + this.put(80700, 144); + this.put(80800, 159); + this.put(80900, 139); + this.put(81000, 123); + this.put(81100, 139); + this.put(81200, 105); + this.put(81300, 121); + this.put(81400, 154); + this.put(81500, 107); + this.put(81600, 150); + this.put(81700, 115); + this.put(81800, 147); + this.put(81900, 159); + this.put(82000, 141); + this.put(82100, 139); + this.put(82200, 112); + this.put(82300, 153); + this.put(82400, 141); + this.put(82500, 158); + this.put(82600, 126); + this.put(82700, 142); + this.put(82800, 122); + this.put(82900, 121); + this.put(83000, 143); + this.put(83100, 97); + this.put(83200, 173); + this.put(83300, 117); + this.put(83400, 142); + this.put(83500, 188); + this.put(83600, 101); + this.put(83700, 97); + this.put(83800, 116); + this.put(83900, 125); + this.put(84000, 151); + this.put(84100, 115); + this.put(84200, 127); + this.put(84300, 125); + this.put(84400, 128); + this.put(84500, 138); + this.put(84600, 163); + this.put(84700, 159); + this.put(84800, 148); + this.put(84900, 182); + this.put(85000, 161); + this.put(85100, 128); + this.put(85200, 158); + this.put(85300, 172); + this.put(85400, 187); + this.put(85500, 155); + this.put(85600, 155); + this.put(85700, 164); + this.put(85800, 167); + this.put(85900, 144); + this.put(86000, 122); + this.put(86100, 166); + this.put(86200, 168); + this.put(86300, 150); + this.put(86400, 144); + this.put(86500, 167); + this.put(86600, 174); + this.put(86700, 208); + this.put(86800, 188); + this.put(86900, 191); + this.put(87000, 178); + this.put(87100, 156); + this.put(87200, 134); + this.put(87300, 151); + this.put(87400, 134); + this.put(87500, 170); + this.put(87600, 169); + this.put(87700, 153); + this.put(87800, 133); + this.put(87900, 147); + this.put(88000, 135); + this.put(88100, 146); + this.put(88200, 135); + this.put(88300, 161); + this.put(88400, 153); + this.put(88500, 185); + this.put(88600, 117); + this.put(88700, 201); + this.put(88800, 158); + this.put(88900, 163); + this.put(89000, 137); + this.put(89100, 147); + this.put(89200, 122); + this.put(89300, 120); + this.put(89400, 90); + this.put(89500, 135); + this.put(89600, 164); + this.put(89700, 122); + this.put(89800, 132); + this.put(89900, 154); + this.put(90000, 147); + this.put(90100, 158); + this.put(90200, 120); + this.put(90300, 132); + this.put(90400, 180); + this.put(90500, 86); + this.put(90600, 78); + this.put(90700, 103); + this.put(90800, 107); + this.put(90900, 98); + this.put(91000, 111); + this.put(91100, 116); + this.put(91200, 100); + this.put(91300, 82); + this.put(91400, 86); + this.put(91500, 91); + this.put(91600, 144); + this.put(91700, 135); + this.put(91800, 90); + this.put(91900, 125); + this.put(92000, 152); + this.put(92100, 108); + this.put(92200, 141); + this.put(92300, 102); + this.put(92400, 86); + this.put(92500, 93); + this.put(92600, 107); + this.put(92700, 98); + this.put(92800, 130); + this.put(92900, 122); + this.put(93000, 117); + this.put(93100, 87); + this.put(93200, 109); + this.put(93300, 163); + this.put(93400, 175); + this.put(93500, 165); + this.put(93600, 130); + this.put(93700, 176); + this.put(93800, 127); + this.put(93900, 144); + this.put(94000, 84); + this.put(94100, 96); + this.put(94200, 84); + this.put(94300, 76); + this.put(94400, 111); + this.put(94500, 82); + this.put(94600, 53); + this.put(94700, 87); + this.put(94800, 77); + this.put(94900, 78); + this.put(95000, 75); + this.put(95100, 61); + this.put(95200, 110); + this.put(95300, 124); + this.put(95400, 104); + this.put(95500, 84); + this.put(95600, 77); + this.put(95700, 99); + this.put(95800, 81); + this.put(95900, 72); + this.put(96000, 99); + this.put(96100, 103); + this.put(96200, 86); + this.put(96300, 93); + this.put(96400, 102); + this.put(96500, 102); + this.put(96600, 79); + this.put(96700, 91); + this.put(96800, 114); + this.put(96900, 79); + this.put(97000, 118); + this.put(97100, 79); + this.put(97200, 96); + this.put(97300, 124); + this.put(97400, 113); + this.put(97500, 121); + this.put(97600, 67); + this.put(97700, 73); + this.put(97800, 67); + this.put(97900, 68); + this.put(98000, 70); + this.put(98100, 43); + this.put(98200, 72); + this.put(98300, 60); + this.put(98400, 76); + this.put(98500, 58); + this.put(98600, 79); + this.put(98700, 75); + this.put(98800, 76); + this.put(98900, 77); + this.put(99000, 55); + this.put(99100, 83); + this.put(99200, 71); + this.put(99300, 86); + this.put(99400, 60); + this.put(99500, 74); + this.put(99600, 48); + this.put(99700, 61); + this.put(99800, 94); + this.put(99900, 85); + this.put(100000, 372); + // this.put(101000, 660); + // this.put(102000, 513); + // this.put(103000, 500); + // this.put(104000, 573); + // this.put(105000, 573); + // this.put(106000, 450); + // this.put(107000, 471); + // this.put(108000, 496); + // this.put(109000, 471); + // this.put(110000, 424); + // this.put(111000, 322); + // this.put(112000, 374); + // this.put(113000, 332); + // this.put(114000, 361); + // this.put(115000, 330); + // this.put(116000, 388); + // this.put(117000, 336); + // this.put(118000, 417); + // this.put(119000, 348); + // this.put(120000, 273); + // this.put(121000, 305); + // this.put(122000, 255); + // this.put(123000, 220); + // this.put(124000, 253); + // this.put(125000, 272); + // this.put(126000, 261); + // this.put(127000, 274); + // this.put(128000, 251); + // this.put(129000, 232); + // this.put(130000, 233); + // this.put(131000, 296); + // this.put(132000, 276); + // this.put(133000, 294); + // this.put(134000, 260); + // this.put(135000, 240); + // this.put(136000, 247); + // this.put(137000, 231); + // this.put(138000, 245); + // this.put(139000, 189); + // this.put(140000, 239); + // this.put(141000, 216); + // this.put(142000, 247); + // this.put(143000, 280); + // this.put(144000, 310); + // this.put(145000, 335); + // this.put(146000, 281); + // this.put(147000, 271); + // this.put(148000, 277); + // this.put(149000, 196); + // this.put(150000, 200); + // this.put(151000, 204); + // this.put(152000, 277); + // this.put(153000, 245); + // this.put(154000, 325); + // this.put(155000, 353); + // this.put(156000, 454); + // this.put(157000, 253); + // this.put(158000, 201); + // this.put(159000, 215); + // this.put(160000, 233); + // this.put(161000, 438); + // this.put(162000, 397); + // this.put(163000, 283); + // this.put(164000, 185); + // this.put(165000, 250); + // this.put(166000, 120); + // this.put(167000, 114); + // this.put(168000, 122); + // this.put(169000, 169); + // this.put(170000, 142); + // this.put(171000, 165); + // this.put(172000, 249); + // this.put(173000, 147); + // this.put(174000, 156); + // this.put(175000, 157); + // this.put(176000, 162); + // this.put(177000, 164); + // this.put(178000, 172); + // this.put(179000, 156); + // this.put(180000, 128); + // this.put(181000, 133); + // this.put(182000, 125); + // this.put(183000, 144); + // this.put(184000, 105); + // this.put(185000, 96); + // this.put(186000, 101); + // this.put(187000, 117); + // this.put(188000, 83); + // this.put(189000, 84); + // this.put(190000, 61); + // this.put(191000, 82); + // this.put(192000, 86); + // this.put(193000, 80); + // this.put(194000, 111); + // this.put(195000, 114); + // this.put(196000, 102); + // this.put(197000, 122); + // this.put(198000, 84); + // this.put(199000, 109); + // this.put(200000, 123); + // this.put(201000, 102); + // this.put(202000, 114); + // this.put(203000, 113); + // this.put(204000, 133); + // this.put(205000, 132); + // this.put(206000, 96); + // this.put(207000, 92); + // this.put(208000, 96); + // this.put(209000, 90); + // this.put(210000, 83); + // this.put(211000, 76); + // this.put(212000, 104); + // this.put(213000, 85); + // this.put(214000, 92); + // this.put(215000, 90); + // this.put(216000, 97); + // this.put(217000, 102); + // this.put(218000, 90); + // this.put(219000, 83); + // this.put(220000, 70); + // this.put(221000, 52); + // this.put(222000, 70); + // this.put(223000, 72); + // this.put(224000, 76); + // this.put(225000, 83); + // this.put(226000, 76); + // this.put(227000, 107); + // this.put(228000, 81); + // this.put(229000, 78); + // this.put(230000, 87); + // this.put(231000, 61); + // this.put(232000, 73); + // this.put(233000, 70); + // this.put(234000, 71); + // this.put(235000, 69); + // this.put(236000, 51); + // this.put(237000, 54); + // this.put(238000, 60); + // this.put(239000, 48); + // this.put(240000, 38); + // this.put(241000, 38); + // this.put(242000, 47); + // this.put(243000, 53); + // this.put(244000, 53); + // this.put(245000, 44); + // this.put(246000, 57); + // this.put(247000, 60); + // this.put(248000, 45); + // this.put(249000, 43); + // this.put(250000, 45); + // this.put(251000, 55); + // this.put(252000, 52); + // this.put(253000, 52); + // this.put(254000, 39); + // this.put(255000, 41); + // this.put(256000, 41); + // this.put(257000, 38); + // this.put(258000, 30); + // this.put(259000, 23); + // this.put(260000, 45); + // this.put(261000, 31); + // this.put(262000, 48); + // this.put(263000, 51); + // this.put(264000, 36); + // this.put(265000, 39); + // this.put(266000, 31); + // this.put(267000, 33); + // this.put(268000, 32); + // this.put(269000, 30); + // this.put(270000, 43); + // this.put(271000, 33); + // this.put(272000, 37); + // this.put(273000, 28); + // this.put(274000, 30); + // this.put(275000, 36); + // this.put(276000, 33); + // this.put(277000, 33); + // this.put(278000, 25); + // this.put(279000, 23); + // this.put(280000, 24); + // this.put(281000, 15); + // this.put(282000, 22); + // this.put(283000, 28); + // this.put(284000, 18); + // this.put(285000, 16); + // this.put(286000, 22); + // this.put(287000, 23); + // this.put(288000, 31); + // this.put(289000, 20); + // this.put(290000, 25); + // this.put(291000, 31); + // this.put(292000, 23); + // this.put(293000, 24); + // this.put(294000, 20); + // this.put(295000, 42); + // this.put(296000, 27); + // this.put(297000, 20); + // this.put(298000, 20); + // this.put(299000, 31); + // this.put(300000, 15); + // this.put(301000, 24); + // this.put(302000, 19); + // this.put(303000, 17); + // this.put(304000, 10); + // this.put(305000, 15); + // this.put(306000, 17); + // this.put(307000, 22); + // this.put(308000, 44); + // this.put(309000, 33); + // this.put(310000, 19); + // this.put(311000, 26); + // this.put(312000, 46); + // this.put(313000, 26); + // this.put(314000, 19); + // this.put(315000, 12); + // this.put(316000, 16); + // this.put(317000, 17); + // this.put(318000, 19); + // this.put(319000, 20); + // this.put(320000, 10); + // this.put(321000, 25); + // this.put(322000, 22); + // this.put(323000, 26); + // this.put(324000, 22); + // this.put(325000, 13); + // this.put(326000, 21); + // this.put(327000, 22); + // this.put(328000, 24); + // this.put(329000, 15); + // this.put(330000, 20); + // this.put(331000, 27); + // this.put(332000, 25); + // this.put(333000, 21); + // this.put(334000, 27); + // this.put(335000, 23); + // this.put(336000, 16); + // this.put(337000, 30); + // this.put(338000, 20); + // this.put(339000, 22); + // this.put(340000, 22); + // this.put(341000, 17); + // this.put(342000, 11); + // this.put(343000, 25); + // this.put(344000, 17); + // this.put(345000, 13); + // this.put(346000, 16); + // this.put(347000, 12); + // this.put(348000, 18); + // this.put(349000, 13); + // this.put(350000, 9); + // this.put(351000, 13); + // this.put(352000, 13); + // this.put(353000, 26); + // this.put(354000, 19); + // this.put(355000, 18); + // this.put(356000, 19); + // this.put(357000, 15); + // this.put(358000, 10); + // this.put(359000, 21); + // this.put(360000, 16); + // this.put(361000, 14); + // this.put(362000, 20); + // this.put(363000, 13); + // this.put(364000, 15); + // this.put(365000, 26); + // this.put(366000, 22); + // this.put(367000, 20); + // this.put(368000, 8); + // this.put(369000, 12); + // this.put(370000, 11); + // this.put(371000, 23); + // this.put(372000, 22); + // this.put(373000, 7); + // this.put(374000, 6); + // this.put(375000, 10); + // this.put(376000, 8); + // this.put(377000, 12); + // this.put(378000, 13); + // this.put(379000, 10); + // this.put(380000, 19); + // this.put(381000, 23); + // this.put(382000, 31); + // this.put(383000, 9); + // this.put(384000, 17); + // this.put(385000, 16); + // this.put(386000, 16); + // this.put(387000, 12); + // this.put(388000, 16); + // this.put(389000, 14); + // this.put(390000, 18); + // this.put(391000, 9); + // this.put(392000, 9); + // this.put(393000, 15); + // this.put(394000, 9); + // this.put(395000, 7); + // this.put(396000, 4); + // this.put(397000, 9); + // this.put(398000, 11); + // this.put(399000, 5); + // this.put(400000, 7); + // this.put(401000, 4); + // this.put(402000, 9); + // this.put(403000, 6); + // this.put(404000, 7); + // this.put(405000, 17); + // this.put(406000, 7); + // this.put(407000, 17); + // this.put(408000, 6); + // this.put(409000, 9); + // this.put(410000, 6); + // this.put(411000, 10); + // this.put(412000, 7); + // this.put(413000, 4); + // this.put(414000, 5); + // this.put(415000, 10); + // this.put(416000, 12); + // this.put(417000, 13); + // this.put(418000, 6); + // this.put(419000, 9); + // this.put(420000, 12); + // this.put(421000, 5); + // this.put(422000, 3); + // this.put(423000, 7); + // this.put(424000, 10); + // this.put(425000, 6); + // this.put(426000, 4); + // this.put(427000, 11); + // this.put(429000, 1); + // this.put(430000, 4); + // this.put(431000, 2); + // this.put(432000, 2); + // this.put(433000, 3); + // this.put(434000, 3); + // this.put(435000, 2); + // this.put(436000, 6); + // this.put(437000, 7); + // this.put(438000, 3); + // this.put(439000, 4); + // this.put(440000, 5); + // this.put(441000, 2); + // this.put(442000, 4); + // this.put(443000, 2); + // this.put(444000, 7); + // this.put(445000, 5); + // this.put(446000, 3); + // this.put(447000, 3); + // this.put(448000, 4); + // this.put(449000, 3); + // this.put(451000, 1); + // this.put(455000, 1); + // this.put(457000, 2); + // this.put(458000, 1); + // this.put(460000, 1); + // this.put(466000, 1); + // this.put(467000, 1); + // this.put(468000, 2); + // this.put(470000, 2); + // this.put(471000, 2); + // this.put(472000, 1); + // this.put(473000, 2); + // this.put(475000, 1); + // this.put(476000, 2); + // this.put(478000, 1); + // this.put(481000, 4); + // this.put(482000, 4); + // this.put(483000, 4); + // this.put(484000, 6); + // this.put(485000, 3); + // this.put(486000, 6); + // this.put(487000, 7); + // this.put(488000, 3); + // this.put(489000, 2); + // this.put(490000, 1); + // this.put(491000, 1); + // this.put(492000, 9); + // this.put(493000, 15); + // this.put(494000, 2); + // this.put(495000, 8); + // this.put(496000, 13); + // this.put(497000, 1); + // this.put(498000, 2); + // this.put(499000, 1); + // this.put(500000, 2); + // this.put(501000, 1); + // this.put(502000, 5); + // this.put(503000, 3); + // this.put(504000, 3); + // this.put(505000, 3); + // this.put(506000, 1); + // this.put(507000, 3); + // this.put(508000, 3); + // this.put(509000, 9); + // this.put(510000, 6); + // this.put(511000, 2); + // this.put(513000, 1); + // this.put(514000, 6); + // this.put(515000, 1); + // this.put(518000, 1); + // this.put(520000, 1); + // this.put(522000, 1); + // this.put(524000, 2); + // this.put(527000, 1); + // this.put(529000, 1); + // this.put(531000, 1); + // this.put(533000, 1); + // this.put(536000, 1); + // this.put(538000, 1); + // this.put(540000, 1); + // this.put(542000, 1); + // this.put(543000, 1); + // this.put(544000, 1); + // this.put(546000, 1); + // this.put(547000, 1); + // this.put(548000, 1); + // this.put(549000, 1); + // this.put(551000, 1); + // this.put(553000, 1); + // this.put(555000, 1); + // this.put(557000, 1); + // this.put(559000, 2); + // this.put(560000, 1); + // this.put(561000, 3); + // this.put(562000, 1); + // this.put(563000, 1); + // this.put(564000, 7); + // this.put(565000, 1); + // this.put(566000, 2); + // this.put(567000, 1); + // this.put(568000, 1); + // this.put(570000, 1); + // this.put(573000, 1); + // this.put(574000, 1); + // this.put(576000, 1); + // this.put(577000, 1); + // this.put(579000, 3); + // this.put(580000, 1); + // this.put(581000, 1); + // this.put(582000, 2); + // this.put(583000, 3); + // this.put(584000, 2); + // this.put(585000, 1); + // this.put(587000, 1); + // this.put(588000, 1); + // this.put(589000, 1); + // this.put(590000, 1); + // this.put(591000, 1); + // this.put(592000, 2); + // this.put(593000, 1); + // this.put(594000, 5); + // this.put(596000, 1); + // this.put(598000, 1); + // this.put(599000, 3); + // this.put(601000, 2); + // this.put(603000, 1); + // this.put(605000, 2); + // this.put(607000, 1); + // this.put(609000, 1); + // this.put(611000, 1); + // this.put(613000, 1); + // this.put(615000, 1); + // this.put(617000, 1); + // this.put(619000, 1); + // this.put(621000, 1); + // this.put(623000, 1); + // this.put(626000, 1); + // this.put(628000, 1); + // this.put(630000, 1); + // this.put(632000, 1); + // this.put(634000, 1); + // this.put(636000, 1); + // this.put(638000, 1); + // this.put(640000, 1); + // this.put(643000, 1); + // this.put(645000, 2); + // this.put(647000, 5); + // this.put(648000, 1); + // this.put(649000, 1); + // this.put(651000, 4); + // this.put(653000, 7); + // this.put(663000, 1); + // this.put(674000, 2); + // this.put(676000, 1); + // this.put(679000, 1); + // this.put(690000, 1); + // this.put(695000, 1); + // this.put(699000, 2); + // this.put(702000, 1); + // this.put(727000, 1); + // this.put(729000, 1); + // this.put(744000, 1); + // this.put(748000, 2); + // this.put(805000, 1); + // this.put(835000, 1); + // this.put(838000, 3); + // this.put(839000, 3); + // this.put(840000, 6); + // this.put(841000, 1); + // this.put(842000, 3); + // this.put(843000, 4); + // this.put(844000, 4); + // this.put(845000, 1); + // this.put(846000, 4); + // this.put(847000, 3); + // this.put(848000, 2); + // this.put(849000, 2); + // this.put(850000, 1); + // this.put(851000, 1); + // this.put(864000, 1); + // this.put(951000, 1); + // this.put(979000, 1); + // this.put(985000, 1); + // this.put(1040000, 1); } - }; - + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/UserHistograms.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/UserHistograms.java index 05d161477..e905c977f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/UserHistograms.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/data/UserHistograms.java @@ -21,698 +21,694 @@ public abstract class UserHistograms { - /** - * The length of the USER_NAME column - */ - public static final Histogram NAME_LENGTH = new Histogram() { + /** The length of the USER_NAME column */ + public static final Histogram NAME_LENGTH = + new Histogram() { { - this.put(1, 29); - this.put(2, 151); - this.put(3, 1278); - this.put(4, 2568); - this.put(5, 5384); - this.put(6, 9895); - this.put(7, 12203); - this.put(8, 13861); - this.put(9, 11462); - this.put(10, 10576); - this.put(11, 8101); - this.put(12, 6671); - this.put(13, 4948); - this.put(14, 3770); - this.put(15, 2642); - this.put(16, 1755); - this.put(17, 1009); - this.put(18, 691); - this.put(19, 468); - this.put(20, 372); - this.put(21, 260); - this.put(22, 185); - this.put(23, 107); - this.put(24, 75); - this.put(25, 53); - this.put(26, 52); - this.put(27, 39); - this.put(28, 29); - this.put(29, 27); - this.put(30, 27); - this.put(31, 14); - this.put(32, 12); - this.put(33, 10); - this.put(34, 9); - this.put(35, 7); - this.put(36, 6); - this.put(37, 8); - this.put(38, 6); - this.put(39, 6); - this.put(40, 4); - this.put(41, 1); - this.put(42, 2); - this.put(44, 2); - this.put(45, 1); - this.put(47, 1); - this.put(49, 1); - this.put(50, 1); - this.put(53, 3); - this.put(54, 1); - this.put(56, 2); - this.put(60, 1); - this.put(62, 1); - this.put(63, 1); + this.put(1, 29); + this.put(2, 151); + this.put(3, 1278); + this.put(4, 2568); + this.put(5, 5384); + this.put(6, 9895); + this.put(7, 12203); + this.put(8, 13861); + this.put(9, 11462); + this.put(10, 10576); + this.put(11, 8101); + this.put(12, 6671); + this.put(13, 4948); + this.put(14, 3770); + this.put(15, 2642); + this.put(16, 1755); + this.put(17, 1009); + this.put(18, 691); + this.put(19, 468); + this.put(20, 372); + this.put(21, 260); + this.put(22, 185); + this.put(23, 107); + this.put(24, 75); + this.put(25, 53); + this.put(26, 52); + this.put(27, 39); + this.put(28, 29); + this.put(29, 27); + this.put(30, 27); + this.put(31, 14); + this.put(32, 12); + this.put(33, 10); + this.put(34, 9); + this.put(35, 7); + this.put(36, 6); + this.put(37, 8); + this.put(38, 6); + this.put(39, 6); + this.put(40, 4); + this.put(41, 1); + this.put(42, 2); + this.put(44, 2); + this.put(45, 1); + this.put(47, 1); + this.put(49, 1); + this.put(50, 1); + this.put(53, 3); + this.put(54, 1); + this.put(56, 2); + this.put(60, 1); + this.put(62, 1); + this.put(63, 1); } - }; + }; - /** - * The length of the USER_REAL_NAME column - */ - public static final Histogram REAL_NAME_LENGTH = new Histogram() { + /** The length of the USER_REAL_NAME column */ + public static final Histogram REAL_NAME_LENGTH = + new Histogram() { { - this.put(1, 29); - this.put(2, 151); - this.put(3, 1278); - this.put(4, 2568); - this.put(5, 5384); - this.put(6, 9895); - this.put(7, 12203); - this.put(8, 13861); - this.put(9, 11462); - this.put(10, 10576); - this.put(11, 8101); - this.put(12, 6671); - this.put(13, 4948); - this.put(14, 3770); - this.put(15, 2642); - this.put(16, 1755); - this.put(17, 1009); - this.put(18, 691); - this.put(19, 468); - this.put(20, 372); - this.put(21, 260); - this.put(22, 185); - this.put(23, 107); - this.put(24, 75); - this.put(25, 53); - this.put(26, 52); - this.put(27, 39); - this.put(28, 29); - this.put(29, 27); - this.put(30, 27); - this.put(31, 14); - this.put(32, 12); - this.put(33, 10); - this.put(34, 9); - this.put(35, 7); - this.put(36, 6); - this.put(37, 8); - this.put(38, 6); - this.put(39, 6); - this.put(40, 4); - this.put(41, 1); - this.put(42, 2); - this.put(44, 2); - this.put(45, 1); - this.put(47, 1); - this.put(49, 1); - this.put(50, 1); - this.put(53, 3); - this.put(54, 1); - this.put(56, 2); - this.put(60, 1); - this.put(62, 1); - this.put(63, 1); + this.put(1, 29); + this.put(2, 151); + this.put(3, 1278); + this.put(4, 2568); + this.put(5, 5384); + this.put(6, 9895); + this.put(7, 12203); + this.put(8, 13861); + this.put(9, 11462); + this.put(10, 10576); + this.put(11, 8101); + this.put(12, 6671); + this.put(13, 4948); + this.put(14, 3770); + this.put(15, 2642); + this.put(16, 1755); + this.put(17, 1009); + this.put(18, 691); + this.put(19, 468); + this.put(20, 372); + this.put(21, 260); + this.put(22, 185); + this.put(23, 107); + this.put(24, 75); + this.put(25, 53); + this.put(26, 52); + this.put(27, 39); + this.put(28, 29); + this.put(29, 27); + this.put(30, 27); + this.put(31, 14); + this.put(32, 12); + this.put(33, 10); + this.put(34, 9); + this.put(35, 7); + this.put(36, 6); + this.put(37, 8); + this.put(38, 6); + this.put(39, 6); + this.put(40, 4); + this.put(41, 1); + this.put(42, 2); + this.put(44, 2); + this.put(45, 1); + this.put(47, 1); + this.put(49, 1); + this.put(50, 1); + this.put(53, 3); + this.put(54, 1); + this.put(56, 2); + this.put(60, 1); + this.put(62, 1); + this.put(63, 1); } - }; + }; - /** - * The histogram of the number of users per revision updates - */ - public static final Histogram REVISION_COUNT = new Histogram() { + /** The histogram of the number of users per revision updates */ + public static final Histogram REVISION_COUNT = + new Histogram() { { - this.put(1, 41764); - this.put(2, 16092); - this.put(3, 8401); - this.put(4, 5159); - this.put(5, 3562); - this.put(6, 2673); - this.put(7, 2115); - this.put(8, 1514); - this.put(9, 1388); - this.put(10, 1144); - this.put(11, 961); - this.put(12, 830); - this.put(13, 728); - this.put(14, 668); - this.put(15, 547); - this.put(16, 516); - this.put(17, 477); - this.put(18, 427); - this.put(19, 392); - this.put(20, 364); - this.put(21, 328); - this.put(22, 306); - this.put(23, 278); - this.put(24, 259); - this.put(25, 273); - this.put(26, 236); - this.put(27, 223); - this.put(28, 212); - this.put(29, 207); - this.put(30, 199); - this.put(31, 181); - this.put(32, 161); - this.put(33, 172); - this.put(34, 147); - this.put(35, 148); - this.put(36, 144); - this.put(37, 131); - this.put(38, 121); - this.put(39, 118); - this.put(40, 137); - this.put(41, 108); - this.put(42, 106); - this.put(43, 101); - this.put(44, 87); - this.put(45, 102); - this.put(46, 99); - this.put(47, 82); - this.put(48, 83); - this.put(49, 88); - this.put(50, 77); - this.put(51, 68); - this.put(52, 77); - this.put(53, 63); - this.put(54, 65); - this.put(55, 72); - this.put(56, 73); - this.put(57, 58); - this.put(58, 54); - this.put(59, 47); - this.put(60, 59); - this.put(61, 53); - this.put(62, 57); - this.put(63, 59); - this.put(64, 57); - this.put(65, 53); - this.put(66, 40); - this.put(67, 44); - this.put(68, 49); - this.put(69, 38); - this.put(70, 42); - this.put(71, 53); - this.put(72, 50); - this.put(73, 40); - this.put(74, 44); - this.put(75, 50); - this.put(76, 46); - this.put(77, 45); - this.put(78, 32); - this.put(79, 37); - this.put(80, 30); - this.put(81, 34); - this.put(82, 24); - this.put(83, 34); - this.put(84, 27); - this.put(85, 27); - this.put(86, 37); - this.put(87, 28); - this.put(88, 23); - this.put(89, 26); - this.put(90, 27); - this.put(91, 19); - this.put(92, 30); - this.put(93, 34); - this.put(94, 31); - this.put(95, 28); - this.put(96, 26); - this.put(97, 31); - this.put(98, 23); - this.put(99, 33); - this.put(100, 30); - this.put(101, 22); - this.put(102, 31); - this.put(103, 21); - this.put(104, 29); - this.put(105, 23); - this.put(106, 26); - this.put(107, 21); - this.put(108, 28); - this.put(109, 28); - this.put(110, 17); - this.put(111, 18); - this.put(112, 18); - this.put(113, 17); - this.put(114, 12); - this.put(115, 25); - this.put(116, 17); - this.put(117, 15); - this.put(118, 20); - this.put(119, 19); - this.put(120, 20); - this.put(121, 18); - this.put(122, 19); - this.put(123, 16); - this.put(124, 17); - this.put(125, 14); - this.put(126, 12); - this.put(127, 11); - this.put(128, 12); - this.put(129, 19); - this.put(130, 15); - this.put(131, 21); - this.put(132, 6); - this.put(133, 14); - this.put(134, 13); - this.put(135, 17); - this.put(136, 12); - this.put(137, 12); - this.put(138, 12); - this.put(139, 15); - this.put(140, 13); - this.put(141, 11); - this.put(142, 11); - this.put(143, 8); - this.put(144, 7); - this.put(145, 14); - this.put(146, 12); - this.put(147, 18); - this.put(148, 13); - this.put(149, 13); - this.put(150, 12); - this.put(151, 15); - this.put(152, 13); - this.put(153, 12); - this.put(154, 5); - this.put(155, 13); - this.put(156, 10); - this.put(157, 7); - this.put(158, 5); - this.put(159, 4); - this.put(160, 14); - this.put(161, 9); - this.put(162, 6); - this.put(163, 8); - this.put(164, 4); - this.put(165, 11); - this.put(166, 8); - this.put(167, 13); - this.put(168, 11); - this.put(169, 8); - this.put(170, 11); - this.put(171, 7); - this.put(172, 10); - this.put(173, 5); - this.put(174, 4); - this.put(175, 9); - this.put(176, 8); - this.put(177, 5); - this.put(178, 8); - this.put(179, 8); - this.put(180, 6); - this.put(181, 4); - this.put(182, 10); - this.put(183, 9); - this.put(184, 10); - this.put(185, 6); - this.put(186, 4); - this.put(187, 6); - this.put(188, 8); - this.put(189, 6); - this.put(190, 10); - this.put(191, 4); - this.put(192, 5); - this.put(193, 7); - this.put(194, 8); - this.put(195, 5); - this.put(196, 9); - this.put(197, 10); - this.put(198, 8); - this.put(199, 7); - this.put(200, 5); - this.put(201, 3); - this.put(202, 14); - this.put(203, 5); - this.put(204, 13); - this.put(205, 3); - this.put(206, 6); - this.put(207, 5); - this.put(208, 8); - this.put(209, 6); - this.put(210, 6); - this.put(211, 5); - this.put(212, 3); - this.put(213, 9); - this.put(214, 4); - this.put(215, 3); - this.put(216, 5); - this.put(217, 5); - this.put(218, 5); - this.put(219, 6); - this.put(220, 3); - this.put(221, 8); - this.put(222, 6); - this.put(223, 8); - this.put(224, 5); - this.put(225, 7); - this.put(226, 3); - this.put(227, 2); - this.put(228, 7); - this.put(229, 3); - this.put(230, 3); - this.put(231, 6); - this.put(232, 6); - this.put(233, 7); - this.put(234, 6); - this.put(235, 4); - this.put(236, 1); - this.put(237, 2); - this.put(238, 8); - this.put(239, 6); - this.put(240, 7); - this.put(241, 3); - this.put(242, 6); - this.put(243, 4); - this.put(244, 5); - this.put(245, 3); - this.put(246, 5); - this.put(247, 5); - this.put(248, 3); - this.put(249, 5); - this.put(250, 5); - this.put(251, 2); - this.put(252, 2); - this.put(253, 4); - this.put(254, 3); - this.put(255, 5); - this.put(256, 3); - this.put(257, 4); - this.put(258, 3); - this.put(259, 1); - this.put(260, 2); - this.put(261, 4); - this.put(262, 3); - this.put(263, 4); - this.put(264, 4); - this.put(265, 2); - this.put(266, 1); - this.put(267, 4); - this.put(268, 4); - this.put(269, 2); - this.put(270, 6); - this.put(271, 2); - this.put(272, 1); - this.put(273, 2); - this.put(274, 2); - this.put(275, 2); - this.put(276, 4); - this.put(277, 3); - this.put(278, 4); - this.put(279, 2); - this.put(280, 5); - this.put(281, 1); - this.put(282, 5); - this.put(284, 3); - this.put(286, 3); - this.put(287, 4); - this.put(288, 2); - this.put(289, 3); - this.put(290, 4); - this.put(291, 2); - this.put(292, 5); - this.put(293, 4); - this.put(294, 3); - this.put(295, 2); - this.put(296, 4); - this.put(297, 3); - this.put(298, 2); - this.put(299, 3); - this.put(300, 2); - this.put(301, 2); - this.put(302, 1); - this.put(304, 3); - this.put(305, 1); - this.put(306, 1); - this.put(307, 1); - this.put(308, 2); - this.put(310, 3); - this.put(311, 1); - this.put(312, 5); - this.put(313, 2); - this.put(314, 1); - this.put(315, 3); - this.put(316, 1); - this.put(317, 1); - this.put(318, 1); - this.put(319, 3); - this.put(321, 1); - this.put(322, 1); - this.put(323, 1); - this.put(324, 5); - this.put(326, 2); - this.put(327, 2); - this.put(329, 2); - this.put(330, 3); - this.put(331, 2); - this.put(332, 4); - this.put(333, 3); - this.put(334, 3); - this.put(335, 2); - this.put(336, 3); - this.put(337, 2); - this.put(339, 3); - this.put(340, 3); - this.put(341, 2); - this.put(342, 2); - this.put(344, 2); - this.put(345, 1); - this.put(346, 1); - this.put(347, 1); - this.put(349, 2); - this.put(350, 3); - this.put(351, 2); - this.put(352, 2); - this.put(353, 3); - this.put(355, 2); - this.put(356, 1); - this.put(357, 1); - this.put(358, 1); - this.put(359, 4); - this.put(360, 3); - this.put(363, 2); - this.put(364, 2); - this.put(365, 2); - this.put(366, 2); - this.put(367, 2); - this.put(370, 1); - this.put(373, 2); - this.put(374, 2); - this.put(376, 1); - this.put(377, 1); - this.put(378, 1); - this.put(379, 1); - this.put(380, 2); - this.put(383, 2); - this.put(386, 4); - this.put(387, 2); - this.put(388, 3); - this.put(389, 1); - this.put(390, 2); - this.put(393, 1); - this.put(395, 1); - this.put(396, 1); - this.put(397, 1); - this.put(399, 2); - this.put(401, 2); - this.put(403, 3); - this.put(404, 1); - this.put(408, 3); - this.put(412, 1); - this.put(414, 3); - this.put(415, 2); - this.put(416, 1); - this.put(417, 1); - this.put(418, 1); - this.put(419, 1); - this.put(422, 1); - this.put(423, 1); - this.put(424, 2); - this.put(425, 2); - this.put(426, 2); - this.put(428, 1); - this.put(429, 2); - this.put(430, 2); - this.put(431, 1); - this.put(433, 1); - this.put(435, 2); - this.put(437, 1); - this.put(438, 2); - this.put(439, 2); - this.put(440, 2); - this.put(443, 1); - this.put(444, 1); - this.put(445, 1); - this.put(447, 1); - this.put(449, 3); - this.put(451, 1); - this.put(452, 1); - this.put(453, 2); - this.put(456, 1); - this.put(458, 1); - this.put(459, 1); - this.put(460, 1); - this.put(461, 3); - this.put(462, 2); - this.put(464, 2); - this.put(465, 1); - this.put(467, 1); - this.put(470, 1); - this.put(479, 1); - this.put(481, 1); - this.put(483, 2); - this.put(485, 1); - this.put(486, 1); - this.put(490, 2); - this.put(492, 1); - this.put(495, 1); - this.put(497, 1); - this.put(498, 1); - this.put(502, 1); - this.put(510, 1); - this.put(515, 1); - this.put(521, 1); - this.put(527, 2); - this.put(528, 2); - this.put(530, 2); - this.put(533, 1); - this.put(536, 4); - this.put(538, 2); - this.put(540, 1); - this.put(542, 1); - this.put(543, 2); - this.put(544, 1); - this.put(547, 1); - this.put(548, 1); - this.put(555, 2); - this.put(556, 1); - this.put(559, 1); - this.put(560, 1); - this.put(561, 2); - this.put(563, 1); - this.put(564, 1); - this.put(566, 1); - this.put(570, 1); - this.put(572, 1); - this.put(573, 1); - this.put(578, 1); - this.put(592, 1); - this.put(595, 1); - this.put(599, 1); - this.put(600, 2); - this.put(604, 1); - this.put(605, 1); - this.put(607, 1); - this.put(608, 1); - this.put(612, 1); - this.put(613, 1); - this.put(617, 1); - this.put(620, 1); - this.put(626, 2); - this.put(627, 1); - this.put(629, 1); - this.put(632, 1); - this.put(633, 1); - this.put(635, 1); - this.put(636, 1); - this.put(640, 1); - this.put(641, 1); - this.put(642, 1); - this.put(644, 1); - this.put(645, 1); - this.put(651, 1); - this.put(659, 1); - this.put(671, 1); - this.put(672, 1); - this.put(675, 1); - this.put(680, 1); - this.put(681, 2); - this.put(682, 1); - this.put(684, 1); - this.put(688, 1); - this.put(692, 1); - this.put(701, 1); - this.put(702, 1); - this.put(703, 2); - this.put(718, 1); - this.put(722, 1); - this.put(728, 1); - this.put(742, 2); - this.put(758, 1); - this.put(768, 1); - this.put(773, 1); - this.put(775, 1); - this.put(777, 1); - this.put(780, 1); - this.put(786, 1); - this.put(790, 1); - this.put(794, 1); - this.put(795, 1); - this.put(796, 1); - this.put(806, 1); - this.put(807, 1); - this.put(814, 1); - this.put(834, 1); - this.put(857, 1); - this.put(858, 1); - this.put(863, 1); - this.put(873, 1); - this.put(903, 1); - this.put(931, 1); - this.put(966, 1); - this.put(982, 1); - this.put(988, 2); - this.put(992, 1); - this.put(1033, 1); - this.put(1038, 1); - this.put(1055, 2); - this.put(1077, 1); - this.put(1086, 1); - this.put(1095, 1); - this.put(1098, 1); - this.put(1137, 1); - this.put(1143, 1); - this.put(1151, 1); - this.put(1180, 1); - this.put(1207, 1); - this.put(1240, 1); - this.put(1264, 1); - this.put(1282, 1); - this.put(1292, 1); - this.put(1299, 1); - this.put(1355, 1); - this.put(1433, 1); - this.put(1468, 1); - this.put(1482, 1); - this.put(1531, 1); - this.put(1580, 1); - this.put(1614, 1); - this.put(1668, 1); - this.put(1828, 1); - this.put(1885, 1); - this.put(2135, 1); - this.put(2235, 1); - this.put(2250, 1); - this.put(2442, 1); - this.put(2460, 1); - this.put(2566, 1); - this.put(2714, 1); - this.put(2932, 1); - this.put(2954, 1); - this.put(3275, 1); - this.put(3407, 1); - this.put(4581, 1); - this.put(5466, 1); - this.put(7454, 1); - this.put(9742, 1); + this.put(1, 41764); + this.put(2, 16092); + this.put(3, 8401); + this.put(4, 5159); + this.put(5, 3562); + this.put(6, 2673); + this.put(7, 2115); + this.put(8, 1514); + this.put(9, 1388); + this.put(10, 1144); + this.put(11, 961); + this.put(12, 830); + this.put(13, 728); + this.put(14, 668); + this.put(15, 547); + this.put(16, 516); + this.put(17, 477); + this.put(18, 427); + this.put(19, 392); + this.put(20, 364); + this.put(21, 328); + this.put(22, 306); + this.put(23, 278); + this.put(24, 259); + this.put(25, 273); + this.put(26, 236); + this.put(27, 223); + this.put(28, 212); + this.put(29, 207); + this.put(30, 199); + this.put(31, 181); + this.put(32, 161); + this.put(33, 172); + this.put(34, 147); + this.put(35, 148); + this.put(36, 144); + this.put(37, 131); + this.put(38, 121); + this.put(39, 118); + this.put(40, 137); + this.put(41, 108); + this.put(42, 106); + this.put(43, 101); + this.put(44, 87); + this.put(45, 102); + this.put(46, 99); + this.put(47, 82); + this.put(48, 83); + this.put(49, 88); + this.put(50, 77); + this.put(51, 68); + this.put(52, 77); + this.put(53, 63); + this.put(54, 65); + this.put(55, 72); + this.put(56, 73); + this.put(57, 58); + this.put(58, 54); + this.put(59, 47); + this.put(60, 59); + this.put(61, 53); + this.put(62, 57); + this.put(63, 59); + this.put(64, 57); + this.put(65, 53); + this.put(66, 40); + this.put(67, 44); + this.put(68, 49); + this.put(69, 38); + this.put(70, 42); + this.put(71, 53); + this.put(72, 50); + this.put(73, 40); + this.put(74, 44); + this.put(75, 50); + this.put(76, 46); + this.put(77, 45); + this.put(78, 32); + this.put(79, 37); + this.put(80, 30); + this.put(81, 34); + this.put(82, 24); + this.put(83, 34); + this.put(84, 27); + this.put(85, 27); + this.put(86, 37); + this.put(87, 28); + this.put(88, 23); + this.put(89, 26); + this.put(90, 27); + this.put(91, 19); + this.put(92, 30); + this.put(93, 34); + this.put(94, 31); + this.put(95, 28); + this.put(96, 26); + this.put(97, 31); + this.put(98, 23); + this.put(99, 33); + this.put(100, 30); + this.put(101, 22); + this.put(102, 31); + this.put(103, 21); + this.put(104, 29); + this.put(105, 23); + this.put(106, 26); + this.put(107, 21); + this.put(108, 28); + this.put(109, 28); + this.put(110, 17); + this.put(111, 18); + this.put(112, 18); + this.put(113, 17); + this.put(114, 12); + this.put(115, 25); + this.put(116, 17); + this.put(117, 15); + this.put(118, 20); + this.put(119, 19); + this.put(120, 20); + this.put(121, 18); + this.put(122, 19); + this.put(123, 16); + this.put(124, 17); + this.put(125, 14); + this.put(126, 12); + this.put(127, 11); + this.put(128, 12); + this.put(129, 19); + this.put(130, 15); + this.put(131, 21); + this.put(132, 6); + this.put(133, 14); + this.put(134, 13); + this.put(135, 17); + this.put(136, 12); + this.put(137, 12); + this.put(138, 12); + this.put(139, 15); + this.put(140, 13); + this.put(141, 11); + this.put(142, 11); + this.put(143, 8); + this.put(144, 7); + this.put(145, 14); + this.put(146, 12); + this.put(147, 18); + this.put(148, 13); + this.put(149, 13); + this.put(150, 12); + this.put(151, 15); + this.put(152, 13); + this.put(153, 12); + this.put(154, 5); + this.put(155, 13); + this.put(156, 10); + this.put(157, 7); + this.put(158, 5); + this.put(159, 4); + this.put(160, 14); + this.put(161, 9); + this.put(162, 6); + this.put(163, 8); + this.put(164, 4); + this.put(165, 11); + this.put(166, 8); + this.put(167, 13); + this.put(168, 11); + this.put(169, 8); + this.put(170, 11); + this.put(171, 7); + this.put(172, 10); + this.put(173, 5); + this.put(174, 4); + this.put(175, 9); + this.put(176, 8); + this.put(177, 5); + this.put(178, 8); + this.put(179, 8); + this.put(180, 6); + this.put(181, 4); + this.put(182, 10); + this.put(183, 9); + this.put(184, 10); + this.put(185, 6); + this.put(186, 4); + this.put(187, 6); + this.put(188, 8); + this.put(189, 6); + this.put(190, 10); + this.put(191, 4); + this.put(192, 5); + this.put(193, 7); + this.put(194, 8); + this.put(195, 5); + this.put(196, 9); + this.put(197, 10); + this.put(198, 8); + this.put(199, 7); + this.put(200, 5); + this.put(201, 3); + this.put(202, 14); + this.put(203, 5); + this.put(204, 13); + this.put(205, 3); + this.put(206, 6); + this.put(207, 5); + this.put(208, 8); + this.put(209, 6); + this.put(210, 6); + this.put(211, 5); + this.put(212, 3); + this.put(213, 9); + this.put(214, 4); + this.put(215, 3); + this.put(216, 5); + this.put(217, 5); + this.put(218, 5); + this.put(219, 6); + this.put(220, 3); + this.put(221, 8); + this.put(222, 6); + this.put(223, 8); + this.put(224, 5); + this.put(225, 7); + this.put(226, 3); + this.put(227, 2); + this.put(228, 7); + this.put(229, 3); + this.put(230, 3); + this.put(231, 6); + this.put(232, 6); + this.put(233, 7); + this.put(234, 6); + this.put(235, 4); + this.put(236, 1); + this.put(237, 2); + this.put(238, 8); + this.put(239, 6); + this.put(240, 7); + this.put(241, 3); + this.put(242, 6); + this.put(243, 4); + this.put(244, 5); + this.put(245, 3); + this.put(246, 5); + this.put(247, 5); + this.put(248, 3); + this.put(249, 5); + this.put(250, 5); + this.put(251, 2); + this.put(252, 2); + this.put(253, 4); + this.put(254, 3); + this.put(255, 5); + this.put(256, 3); + this.put(257, 4); + this.put(258, 3); + this.put(259, 1); + this.put(260, 2); + this.put(261, 4); + this.put(262, 3); + this.put(263, 4); + this.put(264, 4); + this.put(265, 2); + this.put(266, 1); + this.put(267, 4); + this.put(268, 4); + this.put(269, 2); + this.put(270, 6); + this.put(271, 2); + this.put(272, 1); + this.put(273, 2); + this.put(274, 2); + this.put(275, 2); + this.put(276, 4); + this.put(277, 3); + this.put(278, 4); + this.put(279, 2); + this.put(280, 5); + this.put(281, 1); + this.put(282, 5); + this.put(284, 3); + this.put(286, 3); + this.put(287, 4); + this.put(288, 2); + this.put(289, 3); + this.put(290, 4); + this.put(291, 2); + this.put(292, 5); + this.put(293, 4); + this.put(294, 3); + this.put(295, 2); + this.put(296, 4); + this.put(297, 3); + this.put(298, 2); + this.put(299, 3); + this.put(300, 2); + this.put(301, 2); + this.put(302, 1); + this.put(304, 3); + this.put(305, 1); + this.put(306, 1); + this.put(307, 1); + this.put(308, 2); + this.put(310, 3); + this.put(311, 1); + this.put(312, 5); + this.put(313, 2); + this.put(314, 1); + this.put(315, 3); + this.put(316, 1); + this.put(317, 1); + this.put(318, 1); + this.put(319, 3); + this.put(321, 1); + this.put(322, 1); + this.put(323, 1); + this.put(324, 5); + this.put(326, 2); + this.put(327, 2); + this.put(329, 2); + this.put(330, 3); + this.put(331, 2); + this.put(332, 4); + this.put(333, 3); + this.put(334, 3); + this.put(335, 2); + this.put(336, 3); + this.put(337, 2); + this.put(339, 3); + this.put(340, 3); + this.put(341, 2); + this.put(342, 2); + this.put(344, 2); + this.put(345, 1); + this.put(346, 1); + this.put(347, 1); + this.put(349, 2); + this.put(350, 3); + this.put(351, 2); + this.put(352, 2); + this.put(353, 3); + this.put(355, 2); + this.put(356, 1); + this.put(357, 1); + this.put(358, 1); + this.put(359, 4); + this.put(360, 3); + this.put(363, 2); + this.put(364, 2); + this.put(365, 2); + this.put(366, 2); + this.put(367, 2); + this.put(370, 1); + this.put(373, 2); + this.put(374, 2); + this.put(376, 1); + this.put(377, 1); + this.put(378, 1); + this.put(379, 1); + this.put(380, 2); + this.put(383, 2); + this.put(386, 4); + this.put(387, 2); + this.put(388, 3); + this.put(389, 1); + this.put(390, 2); + this.put(393, 1); + this.put(395, 1); + this.put(396, 1); + this.put(397, 1); + this.put(399, 2); + this.put(401, 2); + this.put(403, 3); + this.put(404, 1); + this.put(408, 3); + this.put(412, 1); + this.put(414, 3); + this.put(415, 2); + this.put(416, 1); + this.put(417, 1); + this.put(418, 1); + this.put(419, 1); + this.put(422, 1); + this.put(423, 1); + this.put(424, 2); + this.put(425, 2); + this.put(426, 2); + this.put(428, 1); + this.put(429, 2); + this.put(430, 2); + this.put(431, 1); + this.put(433, 1); + this.put(435, 2); + this.put(437, 1); + this.put(438, 2); + this.put(439, 2); + this.put(440, 2); + this.put(443, 1); + this.put(444, 1); + this.put(445, 1); + this.put(447, 1); + this.put(449, 3); + this.put(451, 1); + this.put(452, 1); + this.put(453, 2); + this.put(456, 1); + this.put(458, 1); + this.put(459, 1); + this.put(460, 1); + this.put(461, 3); + this.put(462, 2); + this.put(464, 2); + this.put(465, 1); + this.put(467, 1); + this.put(470, 1); + this.put(479, 1); + this.put(481, 1); + this.put(483, 2); + this.put(485, 1); + this.put(486, 1); + this.put(490, 2); + this.put(492, 1); + this.put(495, 1); + this.put(497, 1); + this.put(498, 1); + this.put(502, 1); + this.put(510, 1); + this.put(515, 1); + this.put(521, 1); + this.put(527, 2); + this.put(528, 2); + this.put(530, 2); + this.put(533, 1); + this.put(536, 4); + this.put(538, 2); + this.put(540, 1); + this.put(542, 1); + this.put(543, 2); + this.put(544, 1); + this.put(547, 1); + this.put(548, 1); + this.put(555, 2); + this.put(556, 1); + this.put(559, 1); + this.put(560, 1); + this.put(561, 2); + this.put(563, 1); + this.put(564, 1); + this.put(566, 1); + this.put(570, 1); + this.put(572, 1); + this.put(573, 1); + this.put(578, 1); + this.put(592, 1); + this.put(595, 1); + this.put(599, 1); + this.put(600, 2); + this.put(604, 1); + this.put(605, 1); + this.put(607, 1); + this.put(608, 1); + this.put(612, 1); + this.put(613, 1); + this.put(617, 1); + this.put(620, 1); + this.put(626, 2); + this.put(627, 1); + this.put(629, 1); + this.put(632, 1); + this.put(633, 1); + this.put(635, 1); + this.put(636, 1); + this.put(640, 1); + this.put(641, 1); + this.put(642, 1); + this.put(644, 1); + this.put(645, 1); + this.put(651, 1); + this.put(659, 1); + this.put(671, 1); + this.put(672, 1); + this.put(675, 1); + this.put(680, 1); + this.put(681, 2); + this.put(682, 1); + this.put(684, 1); + this.put(688, 1); + this.put(692, 1); + this.put(701, 1); + this.put(702, 1); + this.put(703, 2); + this.put(718, 1); + this.put(722, 1); + this.put(728, 1); + this.put(742, 2); + this.put(758, 1); + this.put(768, 1); + this.put(773, 1); + this.put(775, 1); + this.put(777, 1); + this.put(780, 1); + this.put(786, 1); + this.put(790, 1); + this.put(794, 1); + this.put(795, 1); + this.put(796, 1); + this.put(806, 1); + this.put(807, 1); + this.put(814, 1); + this.put(834, 1); + this.put(857, 1); + this.put(858, 1); + this.put(863, 1); + this.put(873, 1); + this.put(903, 1); + this.put(931, 1); + this.put(966, 1); + this.put(982, 1); + this.put(988, 2); + this.put(992, 1); + this.put(1033, 1); + this.put(1038, 1); + this.put(1055, 2); + this.put(1077, 1); + this.put(1086, 1); + this.put(1095, 1); + this.put(1098, 1); + this.put(1137, 1); + this.put(1143, 1); + this.put(1151, 1); + this.put(1180, 1); + this.put(1207, 1); + this.put(1240, 1); + this.put(1264, 1); + this.put(1282, 1); + this.put(1292, 1); + this.put(1299, 1); + this.put(1355, 1); + this.put(1433, 1); + this.put(1468, 1); + this.put(1482, 1); + this.put(1531, 1); + this.put(1580, 1); + this.put(1614, 1); + this.put(1668, 1); + this.put(1828, 1); + this.put(1885, 1); + this.put(2135, 1); + this.put(2235, 1); + this.put(2250, 1); + this.put(2442, 1); + this.put(2460, 1); + this.put(2566, 1); + this.put(2714, 1); + this.put(2932, 1); + this.put(2954, 1); + this.put(3275, 1); + this.put(3407, 1); + this.put(4581, 1); + this.put(5466, 1); + this.put(7454, 1); + this.put(9742, 1); } - }; - + }; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/AddWatchList.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/AddWatchList.java index 4cbf08384..032f8017e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/AddWatchList.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/AddWatchList.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.procedures; import com.oltpbenchmark.api.Procedure; @@ -23,75 +22,75 @@ import com.oltpbenchmark.benchmarks.wikipedia.WikipediaConstants; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TimeUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class AddWatchList extends Procedure { - private static final Logger LOG = LoggerFactory.getLogger(AddWatchList.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public SQLStmt insertWatchList = new SQLStmt( - "INSERT INTO " + WikipediaConstants.TABLENAME_WATCHLIST + " (" + - "wl_user, wl_namespace, wl_title, wl_notificationtimestamp" + - ") VALUES (" + - "?,?,?,NULL" + - ")" - ); - - public SQLStmt setUserTouched = new SQLStmt( - "UPDATE " + WikipediaConstants.TABLENAME_USER + - " SET user_touched = ? WHERE user_id = ?" - ); - - // ----------------------------------------------------------------- - // RUN - // ----------------------------------------------------------------- - - public void run(Connection conn, int userId, int nameSpace, String pageTitle) throws SQLException { - if (userId > 0) { - - try (PreparedStatement ps = this.getPreparedStatement(conn, insertWatchList)) { - ps.setInt(1, userId); - ps.setInt(2, nameSpace); - ps.setString(3, pageTitle); - ps.executeUpdate(); - } - catch (SQLException e) { - if (SQLUtil.isDuplicateKeyException(e)) { - LOG.debug(e.toString()); - throw new UserAbortException("User " + userId + " already has " + pageTitle + " in their watchlist"); - } - else { - throw e; - } - } - - if (nameSpace == 0) { - - // if regular page, also add a line of - // watchlist for the corresponding talk page - try (PreparedStatement ps = this.getPreparedStatement(conn, insertWatchList)) { - ps.setInt(1, userId); - ps.setInt(2, 1); - ps.setString(3, pageTitle); - ps.executeUpdate(); - } + private static final Logger LOG = LoggerFactory.getLogger(AddWatchList.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public SQLStmt insertWatchList = + new SQLStmt( + "INSERT INTO " + + WikipediaConstants.TABLENAME_WATCHLIST + + " (" + + "wl_user, wl_namespace, wl_title, wl_notificationtimestamp" + + ") VALUES (" + + "?,?,?,NULL" + + ")"); + + public SQLStmt setUserTouched = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_USER + + " SET user_touched = ? WHERE user_id = ?"); + + // ----------------------------------------------------------------- + // RUN + // ----------------------------------------------------------------- + + public void run(Connection conn, int userId, int nameSpace, String pageTitle) + throws SQLException { + if (userId > 0) { + + try (PreparedStatement ps = this.getPreparedStatement(conn, insertWatchList)) { + ps.setInt(1, userId); + ps.setInt(2, nameSpace); + ps.setString(3, pageTitle); + ps.executeUpdate(); + } catch (SQLException e) { + if (SQLUtil.isDuplicateKeyException(e)) { + LOG.debug(e.toString()); + throw new UserAbortException( + "User " + userId + " already has " + pageTitle + " in their watchlist"); + } else { + throw e; + } + } - } + if (nameSpace == 0) { - try (PreparedStatement ps = this.getPreparedStatement(conn, setUserTouched)) { - ps.setString(1, TimeUtil.getCurrentTimeString14()); - ps.setInt(2, userId); - ps.executeUpdate(); - } + // if regular page, also add a line of + // watchlist for the corresponding talk page + try (PreparedStatement ps = this.getPreparedStatement(conn, insertWatchList)) { + ps.setInt(1, userId); + ps.setInt(2, 1); + ps.setString(3, pageTitle); + ps.executeUpdate(); } - } + } + try (PreparedStatement ps = this.getPreparedStatement(conn, setUserTouched)) { + ps.setString(1, TimeUtil.getCurrentTimeString14()); + ps.setInt(2, userId); + ps.executeUpdate(); + } + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java index bd4a4648d..17e83571f 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAnonymous.java @@ -15,140 +15,148 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.wikipedia.WikipediaConstants; import com.oltpbenchmark.benchmarks.wikipedia.util.Article; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class GetPageAnonymous extends Procedure { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(GetPageAnonymous.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public SQLStmt selectPage = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE + - " WHERE page_namespace = ? AND page_title = ? LIMIT 1" - ); - public SQLStmt selectPageRestriction = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS + - " WHERE pr_page = ?" - ); - // XXX this is hard for translation - public SQLStmt selectIpBlocks = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_IPBLOCKS + - " WHERE ipb_address = ?" - ); - public SQLStmt selectPageRevision = new SQLStmt( - "SELECT * " + - " FROM " + WikipediaConstants.TABLENAME_PAGE + ", " + - WikipediaConstants.TABLENAME_REVISION + - " WHERE page_id = rev_page " + - " AND rev_page = ? " + - " AND page_id = ? " + - " AND rev_id = page_latest LIMIT 1" - ); - public SQLStmt selectText = new SQLStmt( - "SELECT old_text, old_flags FROM " + WikipediaConstants.TABLENAME_TEXT + - " WHERE old_id = ? LIMIT 1" - ); - - // ----------------------------------------------------------------- - // RUN - // ----------------------------------------------------------------- - - public Article run(Connection conn, boolean forSelect, String userIp, - int pageNamespace, String pageTitle) throws UserAbortException, SQLException { - int param = 1; - - int pageId; - try (PreparedStatement st = this.getPreparedStatement(conn, selectPage)) { - st.setInt(param++, pageNamespace); - st.setString(param++, pageTitle); - try (ResultSet rs = st.executeQuery()) { - if (!rs.next()) { - String msg = String.format("Invalid Page: Namespace:%d / Title:\"%s\"", pageNamespace, pageTitle); - throw new UserAbortException(msg); - } - pageId = rs.getInt(1); - } + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(GetPageAnonymous.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public SQLStmt selectPage = + new SQLStmt( + "SELECT * FROM " + + WikipediaConstants.TABLENAME_PAGE + + " WHERE page_namespace = ? AND page_title = ? LIMIT 1"); + public SQLStmt selectPageRestriction = + new SQLStmt( + "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS + " WHERE pr_page = ?"); + // XXX this is hard for translation + public SQLStmt selectIpBlocks = + new SQLStmt( + "SELECT * FROM " + WikipediaConstants.TABLENAME_IPBLOCKS + " WHERE ipb_address = ?"); + public SQLStmt selectPageRevision = + new SQLStmt( + "SELECT * " + + " FROM " + + WikipediaConstants.TABLENAME_PAGE + + ", " + + WikipediaConstants.TABLENAME_REVISION + + " WHERE page_id = rev_page " + + " AND rev_page = ? " + + " AND page_id = ? " + + " AND rev_id = page_latest LIMIT 1"); + public SQLStmt selectText = + new SQLStmt( + "SELECT old_text, old_flags FROM " + + WikipediaConstants.TABLENAME_TEXT + + " WHERE old_id = ? LIMIT 1"); + + // ----------------------------------------------------------------- + // RUN + // ----------------------------------------------------------------- + + public Article run( + Connection conn, boolean forSelect, String userIp, int pageNamespace, String pageTitle) + throws UserAbortException, SQLException { + int param = 1; + + int pageId; + try (PreparedStatement st = this.getPreparedStatement(conn, selectPage)) { + st.setInt(param++, pageNamespace); + st.setString(param++, pageTitle); + try (ResultSet rs = st.executeQuery()) { + if (!rs.next()) { + String msg = + String.format("Invalid Page: Namespace:%d / Title:\"%s\"", pageNamespace, pageTitle); + throw new UserAbortException(msg); } + pageId = rs.getInt(1); + } + } - try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRestriction)) { - st.setInt(1, pageId); - try (ResultSet rs = st.executeQuery()) { - while (rs.next()) { - rs.getBytes(1); - } - } + try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRestriction)) { + st.setInt(1, pageId); + try (ResultSet rs = st.executeQuery()) { + while (rs.next()) { + rs.getBytes(1); } - // check using blocking of a user by either the IP address or the - // user_name - - try (PreparedStatement st = this.getPreparedStatement(conn, selectIpBlocks)) { - st.setString(1, userIp); - try (ResultSet rs = st.executeQuery()) { - while (rs.next()) { - rs.getBytes(11); - - } - } + } + } + // check using blocking of a user by either the IP address or the + // user_name + + try (PreparedStatement st = this.getPreparedStatement(conn, selectIpBlocks)) { + st.setString(1, userIp); + try (ResultSet rs = st.executeQuery()) { + while (rs.next()) { + rs.getBytes(11); } + } + } - long revisionId; - long textId; - - - try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRevision)) { - st.setInt(1, pageId); - st.setInt(2, pageId); - try (ResultSet rs = st.executeQuery()) { - if (!rs.next()) { - String msg = String.format("Invalid Page: Namespace:%d / Title:\"%s\" / PageId:%d", - pageNamespace, pageTitle, pageId); - throw new UserAbortException(msg); - } - - revisionId = rs.getLong("rev_id"); - textId = rs.getLong("rev_text_id"); - } + long revisionId; + long textId; + + try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRevision)) { + st.setInt(1, pageId); + st.setInt(2, pageId); + try (ResultSet rs = st.executeQuery()) { + if (!rs.next()) { + String msg = + String.format( + "Invalid Page: Namespace:%d / Title:\"%s\" / PageId:%d", + pageNamespace, pageTitle, pageId); + throw new UserAbortException(msg); } - // NOTE: the following is our variation of wikipedia... the original did - // not contain old_page column! - // sql = - // "SELECT old_text,old_flags FROM `text` WHERE old_id = '"+textId+"' AND old_page = '"+pageId+"' LIMIT 1"; - - Article a = null; - - try (PreparedStatement st = this.getPreparedStatement(conn, selectText)) { - st.setLong(1, textId); - try (ResultSet rs = st.executeQuery()) { - if (!rs.next()) { - String msg = "No such text: " + textId + " for page_id:" + pageId + " page_namespace: " + pageNamespace + " page_title:" + pageTitle; - throw new UserAbortException(msg); - } + revisionId = rs.getLong("rev_id"); + textId = rs.getLong("rev_text_id"); + } + } - if (!forSelect) { - a = new Article(userIp, pageId, rs.getString("old_text"), textId, revisionId); - } + // NOTE: the following is our variation of wikipedia... the original did + // not contain old_page column! + // sql = + // "SELECT old_text,old_flags FROM `text` WHERE old_id = '"+textId+"' AND old_page = + // '"+pageId+"' LIMIT 1"; + + Article a = null; + + try (PreparedStatement st = this.getPreparedStatement(conn, selectText)) { + st.setLong(1, textId); + try (ResultSet rs = st.executeQuery()) { + if (!rs.next()) { + String msg = + "No such text: " + + textId + + " for page_id:" + + pageId + + " page_namespace: " + + pageNamespace + + " page_title:" + + pageTitle; + throw new UserAbortException(msg); + } - } + if (!forSelect) { + a = new Article(userIp, pageId, rs.getString("old_text"), textId, revisionId); } - return a; + } } - + return a; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java index 43f4701d4..b9508c92c 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/GetPageAuthenticated.java @@ -15,14 +15,12 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.wikipedia.WikipediaConstants; import com.oltpbenchmark.benchmarks.wikipedia.util.Article; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -30,155 +28,175 @@ public class GetPageAuthenticated extends Procedure { - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - - public SQLStmt selectPage = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE + - " WHERE page_namespace = ? AND page_title = ? LIMIT 1" - ); - public SQLStmt selectPageRestriction = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS + - " WHERE pr_page = ?" - ); - public SQLStmt selectIpBlocks = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_IPBLOCKS + - " WHERE ipb_user = ?" - ); - public SQLStmt selectPageRevision = new SQLStmt( - "SELECT * " + - " FROM " + WikipediaConstants.TABLENAME_PAGE + ", " + - WikipediaConstants.TABLENAME_REVISION + - " WHERE page_id = rev_page " + - " AND rev_page = ? " + - " AND page_id = ? " + - " AND rev_id = page_latest LIMIT 1" - ); - public SQLStmt selectText = new SQLStmt( - "SELECT old_text,old_flags FROM " + WikipediaConstants.TABLENAME_TEXT + - " WHERE old_id = ? LIMIT 1" - ); - public SQLStmt selectUser = new SQLStmt( - "SELECT * FROM " + WikipediaConstants.TABLENAME_USER + - " WHERE user_id = ? LIMIT 1" - ); - public SQLStmt selectGroup = new SQLStmt( - "SELECT ug_group FROM " + WikipediaConstants.TABLENAME_USER_GROUPS + - " WHERE ug_user = ?" - ); - - // ----------------------------------------------------------------- - // RUN - // ----------------------------------------------------------------- - - public Article run(Connection conn, boolean forSelect, String userIp, int userId, int nameSpace, String pageTitle) throws SQLException { - // ======================================================= - // LOADING BASIC DATA: txn1 - // ======================================================= - // Retrieve the user data, if the user is logged in - - // FIXME TOO FREQUENTLY SELECTING BY USER_ID - String userText = userIp; - try (PreparedStatement st = this.getPreparedStatement(conn, selectUser)) { - if (userId > 0) { - st.setInt(1, userId); - try (ResultSet rs = st.executeQuery()) { - if (rs.next()) { - userText = rs.getString("user_name"); - } else { - throw new UserAbortException("Invalid UserId: " + userId); - } - } - // Fetch all groups the user might belong to (access control - // information) - try (PreparedStatement selectGroupsStatement = this.getPreparedStatement(conn, selectGroup)) { - selectGroupsStatement.setInt(1, userId); - try (ResultSet rs = st.executeQuery()) { - while (rs.next()) { - String userGroupName = rs.getString(1); - assert userGroupName != null; - } - } - } + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + + public SQLStmt selectPage = + new SQLStmt( + "SELECT * FROM " + + WikipediaConstants.TABLENAME_PAGE + + " WHERE page_namespace = ? AND page_title = ? LIMIT 1"); + public SQLStmt selectPageRestriction = + new SQLStmt( + "SELECT * FROM " + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS + " WHERE pr_page = ?"); + public SQLStmt selectIpBlocks = + new SQLStmt("SELECT * FROM " + WikipediaConstants.TABLENAME_IPBLOCKS + " WHERE ipb_user = ?"); + public SQLStmt selectPageRevision = + new SQLStmt( + "SELECT * " + + " FROM " + + WikipediaConstants.TABLENAME_PAGE + + ", " + + WikipediaConstants.TABLENAME_REVISION + + " WHERE page_id = rev_page " + + " AND rev_page = ? " + + " AND page_id = ? " + + " AND rev_id = page_latest LIMIT 1"); + public SQLStmt selectText = + new SQLStmt( + "SELECT old_text,old_flags FROM " + + WikipediaConstants.TABLENAME_TEXT + + " WHERE old_id = ? LIMIT 1"); + public SQLStmt selectUser = + new SQLStmt( + "SELECT * FROM " + WikipediaConstants.TABLENAME_USER + " WHERE user_id = ? LIMIT 1"); + public SQLStmt selectGroup = + new SQLStmt( + "SELECT ug_group FROM " + + WikipediaConstants.TABLENAME_USER_GROUPS + + " WHERE ug_user = ?"); + + // ----------------------------------------------------------------- + // RUN + // ----------------------------------------------------------------- + + public Article run( + Connection conn, + boolean forSelect, + String userIp, + int userId, + int nameSpace, + String pageTitle) + throws SQLException { + // ======================================================= + // LOADING BASIC DATA: txn1 + // ======================================================= + // Retrieve the user data, if the user is logged in + + // FIXME TOO FREQUENTLY SELECTING BY USER_ID + String userText = userIp; + try (PreparedStatement st = this.getPreparedStatement(conn, selectUser)) { + if (userId > 0) { + st.setInt(1, userId); + try (ResultSet rs = st.executeQuery()) { + if (rs.next()) { + userText = rs.getString("user_name"); + } else { + throw new UserAbortException("Invalid UserId: " + userId); + } + } + // Fetch all groups the user might belong to (access control + // information) + try (PreparedStatement selectGroupsStatement = + this.getPreparedStatement(conn, selectGroup)) { + selectGroupsStatement.setInt(1, userId); + try (ResultSet rs = st.executeQuery()) { + while (rs.next()) { + String userGroupName = rs.getString(1); + assert userGroupName != null; } + } } + } + } - int pageId; - try (PreparedStatement st = this.getPreparedStatement(conn, selectPage)) { - st.setInt(1, nameSpace); - st.setString(2, pageTitle); - try (ResultSet rs = st.executeQuery()) { - - if (!rs.next()) { - throw new UserAbortException("INVALID page namespace/title:" + nameSpace + "/" + pageTitle); - } - pageId = rs.getInt("page_id"); + int pageId; + try (PreparedStatement st = this.getPreparedStatement(conn, selectPage)) { + st.setInt(1, nameSpace); + st.setString(2, pageTitle); + try (ResultSet rs = st.executeQuery()) { - } + if (!rs.next()) { + throw new UserAbortException( + "INVALID page namespace/title:" + nameSpace + "/" + pageTitle); } + pageId = rs.getInt("page_id"); + } + } - try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRestriction)) { - st.setInt(1, pageId); - try (ResultSet rs = st.executeQuery()) { - while (rs.next()) { - byte[] pr_type = rs.getBytes(1); - assert pr_type != null; - } - } + try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRestriction)) { + st.setInt(1, pageId); + try (ResultSet rs = st.executeQuery()) { + while (rs.next()) { + byte[] pr_type = rs.getBytes(1); + assert pr_type != null; } + } + } - // check using blocking of a user by either the IP address or the - // user_name - try (PreparedStatement st = this.getPreparedStatement(conn, selectIpBlocks)) { - st.setInt(1, userId); - try (ResultSet rs = st.executeQuery()) { - while (rs.next()) { - byte[] ipb_expiry = rs.getBytes(11); - assert ipb_expiry != null; - } - } + // check using blocking of a user by either the IP address or the + // user_name + try (PreparedStatement st = this.getPreparedStatement(conn, selectIpBlocks)) { + st.setInt(1, userId); + try (ResultSet rs = st.executeQuery()) { + while (rs.next()) { + byte[] ipb_expiry = rs.getBytes(11); + assert ipb_expiry != null; } + } + } - long revisionId; - long textId; - - try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRevision)) { - st.setInt(1, pageId); - st.setInt(2, pageId); - try (ResultSet rs = st.executeQuery()) { - if (!rs.next()) { - throw new UserAbortException("no such revision: page_id:" + pageId + " page_namespace: " + nameSpace + " page_title:" + pageTitle); - } - - revisionId = rs.getLong("rev_id"); - textId = rs.getLong("rev_text_id"); - - } + long revisionId; + long textId; + + try (PreparedStatement st = this.getPreparedStatement(conn, selectPageRevision)) { + st.setInt(1, pageId); + st.setInt(2, pageId); + try (ResultSet rs = st.executeQuery()) { + if (!rs.next()) { + throw new UserAbortException( + "no such revision: page_id:" + + pageId + + " page_namespace: " + + nameSpace + + " page_title:" + + pageTitle); } - // NOTE: the following is our variation of wikipedia... the original did - // not contain old_page column! - // sql = - // "SELECT old_text,old_flags FROM `text` WHERE old_id = '"+textId+"' AND old_page = '"+pageId+"' LIMIT 1"; - - - Article a = null; - try (PreparedStatement st = this.getPreparedStatement(conn, selectText)) { - st.setLong(1, textId); - try (ResultSet rs = st.executeQuery()) { - if (!rs.next()) { - throw new UserAbortException("no such text: " + textId + " for page_id:" + pageId + " page_namespace: " + nameSpace + " page_title:" + pageTitle); - } - - if (!forSelect) { - a = new Article(userText, pageId, rs.getString("old_text"), textId, revisionId); - } + revisionId = rs.getLong("rev_id"); + textId = rs.getLong("rev_text_id"); + } + } - } + // NOTE: the following is our variation of wikipedia... the original did + // not contain old_page column! + // sql = + // "SELECT old_text,old_flags FROM `text` WHERE old_id = '"+textId+"' AND old_page = + // '"+pageId+"' LIMIT 1"; + + Article a = null; + try (PreparedStatement st = this.getPreparedStatement(conn, selectText)) { + st.setLong(1, textId); + try (ResultSet rs = st.executeQuery()) { + if (!rs.next()) { + throw new UserAbortException( + "no such text: " + + textId + + " for page_id:" + + pageId + + " page_namespace: " + + nameSpace + + " page_title:" + + pageTitle); } - return a; + if (!forSelect) { + a = new Article(userText, pageId, rs.getString("old_text"), textId, revisionId); + } + } } + return a; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/RemoveWatchList.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/RemoveWatchList.java index 708f31982..f79c22a75 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/RemoveWatchList.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/RemoveWatchList.java @@ -15,56 +15,57 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.wikipedia.WikipediaConstants; import com.oltpbenchmark.util.TimeUtil; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class RemoveWatchList extends Procedure { - public SQLStmt removeWatchList = new SQLStmt( - "DELETE FROM " + WikipediaConstants.TABLENAME_WATCHLIST + - " WHERE wl_user = ? AND wl_namespace = ? AND wl_title = ?" - ); - public SQLStmt setUserTouched = new SQLStmt( - "UPDATE " + WikipediaConstants.TABLENAME_USER + - " SET user_touched = ? " + - " WHERE user_id = ? " - ); + public SQLStmt removeWatchList = + new SQLStmt( + "DELETE FROM " + + WikipediaConstants.TABLENAME_WATCHLIST + + " WHERE wl_user = ? AND wl_namespace = ? AND wl_title = ?"); + public SQLStmt setUserTouched = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_USER + + " SET user_touched = ? " + + " WHERE user_id = ? "); - public void run(Connection conn, int userId, int nameSpace, String pageTitle) throws SQLException { + public void run(Connection conn, int userId, int nameSpace, String pageTitle) + throws SQLException { - if (userId > 0) { - try (PreparedStatement ps = this.getPreparedStatement(conn, removeWatchList)) { - ps.setInt(1, userId); - ps.setInt(2, nameSpace); - ps.setString(3, pageTitle); - ps.executeUpdate(); - } + if (userId > 0) { + try (PreparedStatement ps = this.getPreparedStatement(conn, removeWatchList)) { + ps.setInt(1, userId); + ps.setInt(2, nameSpace); + ps.setString(3, pageTitle); + ps.executeUpdate(); + } - if (nameSpace == 0) { - // if regular page, also remove a line of - // watchlist for the corresponding talk page - try (PreparedStatement ps = this.getPreparedStatement(conn, removeWatchList)) { - ps.setInt(1, userId); - ps.setInt(2, 1); - ps.setString(3, pageTitle); - ps.executeUpdate(); - } - } - - try (PreparedStatement ps = this.getPreparedStatement(conn, setUserTouched)) { - ps.setString(1, TimeUtil.getCurrentTimeString14()); - ps.setInt(2, userId); - ps.executeUpdate(); - } + if (nameSpace == 0) { + // if regular page, also remove a line of + // watchlist for the corresponding talk page + try (PreparedStatement ps = this.getPreparedStatement(conn, removeWatchList)) { + ps.setInt(1, userId); + ps.setInt(2, 1); + ps.setString(3, pageTitle); + ps.executeUpdate(); } + } + + try (PreparedStatement ps = this.getPreparedStatement(conn, setUserTouched)) { + ps.setString(1, TimeUtil.getCurrentTimeString14()); + ps.setInt(2, userId); + ps.executeUpdate(); + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java index bf0cee39f..f4c5faf4a 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/procedures/UpdatePage.java @@ -15,221 +15,316 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.procedures; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.wikipedia.WikipediaConstants; import com.oltpbenchmark.util.TimeUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class UpdatePage extends Procedure { - @SuppressWarnings("unused") - private static final Logger LOG = LoggerFactory.getLogger(UpdatePage.class); - - // ----------------------------------------------------------------- - // STATEMENTS - // ----------------------------------------------------------------- - public SQLStmt insertText = new SQLStmt("INSERT INTO " + WikipediaConstants.TABLENAME_TEXT + " (" + "old_page,old_text,old_flags" + ") VALUES (" + "?,?,?" + ")"); - public SQLStmt insertRevision = new SQLStmt("INSERT INTO " + WikipediaConstants.TABLENAME_REVISION + " (" + "rev_page, " + "rev_text_id, " + "rev_comment, " + "rev_minor_edit, " + "rev_user, " + "rev_user_text, " + "rev_timestamp, " + "rev_deleted, " + "rev_len, " + "rev_parent_id" + ") VALUES (" + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?" + ")"); - public SQLStmt updatePage = new SQLStmt("UPDATE " + WikipediaConstants.TABLENAME_PAGE + " SET page_latest = ?, page_touched = ?, page_is_new = 0, page_is_redirect = 0, page_len = ? " + " WHERE page_id = ?"); - public SQLStmt insertRecentChanges = new SQLStmt("INSERT INTO " + WikipediaConstants.TABLENAME_RECENTCHANGES + " (" + "rc_timestamp, " + "rc_cur_time, " + "rc_namespace, " + "rc_title, " + "rc_type, " + "rc_minor, " + "rc_cur_id, " + "rc_user, " + "rc_user_text, " + "rc_comment, " + "rc_this_oldid, " + "rc_last_oldid, " + "rc_bot, " + "rc_moved_to_ns, " + "rc_moved_to_title, " + "rc_ip, " + "rc_old_len, " + "rc_new_len " + ") VALUES (" + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" + ")"); - public SQLStmt selectWatchList = new SQLStmt("SELECT wl_user FROM " + WikipediaConstants.TABLENAME_WATCHLIST + " WHERE wl_title = ?" + " AND wl_namespace = ?" + " AND wl_user != ?" + " AND wl_notificationtimestamp IS NULL"); - public SQLStmt updateWatchList = new SQLStmt("UPDATE " + WikipediaConstants.TABLENAME_WATCHLIST + " SET wl_notificationtimestamp = ? " + " WHERE wl_title = ?" + " AND wl_namespace = ?" + " AND wl_user = ?"); - public SQLStmt selectUser = new SQLStmt("SELECT * FROM " + WikipediaConstants.TABLENAME_USER + " WHERE user_id = ?"); - public SQLStmt insertLogging = new SQLStmt("INSERT INTO " + WikipediaConstants.TABLENAME_LOGGING + " (" + "log_type, log_action, log_timestamp, log_user, log_user_text, " + "log_namespace, log_title, log_page, log_comment, log_params" + ") VALUES (" + "'patrol','patrol',?,?,?,?,?,?,'',?" + ")"); - public SQLStmt updateUserEdit = new SQLStmt("UPDATE " + WikipediaConstants.TABLENAME_USER + " SET user_editcount=user_editcount+1" + " WHERE user_id = ?"); - public SQLStmt updateUserTouched = new SQLStmt("UPDATE " + WikipediaConstants.TABLENAME_USER + " SET user_touched = ?" + " WHERE user_id = ?"); - - // ----------------------------------------------------------------- - // RUN - // ----------------------------------------------------------------- - - public void run(Connection conn, long textId, int pageId, String pageTitle, String pageText, int pageNamespace, int userId, String userIp, String userText, long revisionId, String revComment, int revMinorEdit) throws SQLException { - - final String timestamp = TimeUtil.getCurrentTimeString14(); - - // INSERT NEW TEXT - long nextTextId; - long nextRevId; - - try (PreparedStatement ps = this.getPreparedStatementReturnKeys(conn, insertText, new int[]{1})) { - int param = 1; - ps.setInt(param++, pageId); - ps.setString(param++, pageText); - ps.setString(param++, "utf-8"); //This is an error - execute(conn, ps); - - try (ResultSet rs = ps.getGeneratedKeys()) { - rs.next(); - nextTextId = rs.getLong(1); - } - } - - - // INSERT NEW REVISION - - try (PreparedStatement ps = this.getPreparedStatementReturnKeys(conn, insertRevision, new int[]{1})) { - int param = 1; - ps.setInt(param++, pageId); // rev_page - ps.setLong(param++, nextTextId); // rev_text_id - ps.setString(param++, revComment.substring(0, Math.min(revComment.length(), 255-1))); // rev_comment - ps.setInt(param++, revMinorEdit); // rev_minor_edit // this is an error - ps.setInt(param++, userId); // rev_user - ps.setString(param++, userText); // rev_user_text - ps.setString(param++, timestamp); // rev_timestamp - ps.setInt(param++, 0); // rev_deleted // this is an error - ps.setInt(param++, pageText.length()); // rev_len - ps.setLong(param++, revisionId); // rev_parent_id // this is an error - execute(conn, ps); - - try (ResultSet rs = ps.getGeneratedKeys()) { - rs.next(); - nextRevId = rs.getLong(1); - } - } - - - // I'm removing AND page_latest = "+a.revisionId+" from the query, since - // it creates sometimes problem with the data, and page_id is a PK - // anyway - try (PreparedStatement ps = this.getPreparedStatement(conn, updatePage)) { - int param = 1; - ps.setLong(param++, nextRevId); - ps.setString(param++, timestamp); - ps.setInt(param++, pageText.length()); - ps.setInt(param++, pageId); - execute(conn, ps); - } + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(UpdatePage.class); + + // ----------------------------------------------------------------- + // STATEMENTS + // ----------------------------------------------------------------- + public SQLStmt insertText = + new SQLStmt( + "INSERT INTO " + + WikipediaConstants.TABLENAME_TEXT + + " (" + + "old_page,old_text,old_flags" + + ") VALUES (" + + "?,?,?" + + ")"); + public SQLStmt insertRevision = + new SQLStmt( + "INSERT INTO " + + WikipediaConstants.TABLENAME_REVISION + + " (" + + "rev_page, " + + "rev_text_id, " + + "rev_comment, " + + "rev_minor_edit, " + + "rev_user, " + + "rev_user_text, " + + "rev_timestamp, " + + "rev_deleted, " + + "rev_len, " + + "rev_parent_id" + + ") VALUES (" + + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?" + + ")"); + public SQLStmt updatePage = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_PAGE + + " SET page_latest = ?, page_touched = ?, page_is_new = 0, page_is_redirect = 0, page_len = ? " + + " WHERE page_id = ?"); + public SQLStmt insertRecentChanges = + new SQLStmt( + "INSERT INTO " + + WikipediaConstants.TABLENAME_RECENTCHANGES + + " (" + + "rc_timestamp, " + + "rc_cur_time, " + + "rc_namespace, " + + "rc_title, " + + "rc_type, " + + "rc_minor, " + + "rc_cur_id, " + + "rc_user, " + + "rc_user_text, " + + "rc_comment, " + + "rc_this_oldid, " + + "rc_last_oldid, " + + "rc_bot, " + + "rc_moved_to_ns, " + + "rc_moved_to_title, " + + "rc_ip, " + + "rc_old_len, " + + "rc_new_len " + + ") VALUES (" + + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" + + ")"); + public SQLStmt selectWatchList = + new SQLStmt( + "SELECT wl_user FROM " + + WikipediaConstants.TABLENAME_WATCHLIST + + " WHERE wl_title = ?" + + " AND wl_namespace = ?" + + " AND wl_user != ?" + + " AND wl_notificationtimestamp IS NULL"); + public SQLStmt updateWatchList = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_WATCHLIST + + " SET wl_notificationtimestamp = ? " + + " WHERE wl_title = ?" + + " AND wl_namespace = ?" + + " AND wl_user = ?"); + public SQLStmt selectUser = + new SQLStmt("SELECT * FROM " + WikipediaConstants.TABLENAME_USER + " WHERE user_id = ?"); + public SQLStmt insertLogging = + new SQLStmt( + "INSERT INTO " + + WikipediaConstants.TABLENAME_LOGGING + + " (" + + "log_type, log_action, log_timestamp, log_user, log_user_text, " + + "log_namespace, log_title, log_page, log_comment, log_params" + + ") VALUES (" + + "'patrol','patrol',?,?,?,?,?,?,'',?" + + ")"); + public SQLStmt updateUserEdit = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_USER + + " SET user_editcount=user_editcount+1" + + " WHERE user_id = ?"); + public SQLStmt updateUserTouched = + new SQLStmt( + "UPDATE " + + WikipediaConstants.TABLENAME_USER + + " SET user_touched = ?" + + " WHERE user_id = ?"); + + // ----------------------------------------------------------------- + // RUN + // ----------------------------------------------------------------- + + public void run( + Connection conn, + long textId, + int pageId, + String pageTitle, + String pageText, + int pageNamespace, + int userId, + String userIp, + String userText, + long revisionId, + String revComment, + int revMinorEdit) + throws SQLException { + + final String timestamp = TimeUtil.getCurrentTimeString14(); + + // INSERT NEW TEXT + long nextTextId; + long nextRevId; + + try (PreparedStatement ps = + this.getPreparedStatementReturnKeys(conn, insertText, new int[] {1})) { + int param = 1; + ps.setInt(param++, pageId); + ps.setString(param++, pageText); + ps.setString(param++, "utf-8"); // This is an error + execute(conn, ps); + + try (ResultSet rs = ps.getGeneratedKeys()) { + rs.next(); + nextTextId = rs.getLong(1); + } + } - try (PreparedStatement ps = this.getPreparedStatement(conn, insertRecentChanges)) { - int param = 1; - ps.setString(param++, timestamp); // rc_timestamp - ps.setString(param++, timestamp); // rc_cur_time - ps.setInt(param++, pageNamespace); // rc_namespace - ps.setString(param++, pageTitle); // rc_title - ps.setInt(param++, 0); // rc_type - ps.setInt(param++, 0); // rc_minor - ps.setInt(param++, pageId); // rc_cur_id - ps.setInt(param++, userId); // rc_user - ps.setString(param++, userText); // rc_user_text - ps.setString(param++, revComment); // rc_comment - ps.setLong(param++, nextTextId); // rc_this_oldid - ps.setLong(param++, textId); // rc_last_oldid - ps.setInt(param++, 0); // rc_bot - ps.setInt(param++, 0); // rc_moved_to_ns - ps.setString(param++, ""); // rc_moved_to_title - ps.setString(param++, userIp); // rc_ip - ps.setInt(param++, pageText.length());// rc_old_len - ps.setInt(param++, pageText.length());// rc_new_len - execute(conn, ps); - } + // INSERT NEW REVISION + + try (PreparedStatement ps = + this.getPreparedStatementReturnKeys(conn, insertRevision, new int[] {1})) { + int param = 1; + ps.setInt(param++, pageId); // rev_page + ps.setLong(param++, nextTextId); // rev_text_id + ps.setString( + param++, revComment.substring(0, Math.min(revComment.length(), 255 - 1))); // rev_comment + ps.setInt(param++, revMinorEdit); // rev_minor_edit // this is an error + ps.setInt(param++, userId); // rev_user + ps.setString(param++, userText); // rev_user_text + ps.setString(param++, timestamp); // rev_timestamp + ps.setInt(param++, 0); // rev_deleted // this is an error + ps.setInt(param++, pageText.length()); // rev_len + ps.setLong(param++, revisionId); // rev_parent_id // this is an error + execute(conn, ps); + + try (ResultSet rs = ps.getGeneratedKeys()) { + rs.next(); + nextRevId = rs.getLong(1); + } + } - // REMOVED - // sql="INSERT INTO `cu_changes` () VALUES ();"; - // st.addBatch(sql); - - // SELECT WATCHING USERS - ArrayList wlUser = new ArrayList<>(); - try (PreparedStatement ps = this.getPreparedStatement(conn, selectWatchList)) { - int param = 1; - ps.setString(param++, pageTitle); - ps.setInt(param++, pageNamespace); - ps.setInt(param++, userId); - try (ResultSet rs = ps.executeQuery()) { - - while (rs.next()) { - wlUser.add(rs.getInt(1)); - } - } - } + // I'm removing AND page_latest = "+a.revisionId+" from the query, since + // it creates sometimes problem with the data, and page_id is a PK + // anyway + try (PreparedStatement ps = this.getPreparedStatement(conn, updatePage)) { + int param = 1; + ps.setLong(param++, nextRevId); + ps.setString(param++, timestamp); + ps.setInt(param++, pageText.length()); + ps.setInt(param++, pageId); + execute(conn, ps); + } - // ===================================================================== - // UPDATING WATCHLIST: txn3 (not always, only if someone is watching the - // page, might be part of txn2) - // ===================================================================== - if (!wlUser.isEmpty()) { - - - try (PreparedStatement ps = this.getPreparedStatement(conn, updateWatchList)) { - int param = 1; - ps.setString(param++, timestamp); - ps.setString(param++, pageTitle); - ps.setInt(param++, pageNamespace); - for (Integer otherUserId : wlUser) { - ps.setInt(param, otherUserId); - ps.addBatch(); - } - executeBatch(conn, ps); - } - - - // ===================================================================== - // UPDATING USER AND LOGGING STUFF: txn4 (might still be part of - // txn2) - // ===================================================================== - - // This seems to be executed only if the page is watched, and once - - try (PreparedStatement ps = this.getPreparedStatement(conn, selectUser)) { - int param = 1; - for (Integer otherUserId : wlUser) { - ps.setInt(param, otherUserId); - try (ResultSet rs = ps.executeQuery()) { - rs.next(); - } - } - } - } + try (PreparedStatement ps = this.getPreparedStatement(conn, insertRecentChanges)) { + int param = 1; + ps.setString(param++, timestamp); // rc_timestamp + ps.setString(param++, timestamp); // rc_cur_time + ps.setInt(param++, pageNamespace); // rc_namespace + ps.setString(param++, pageTitle); // rc_title + ps.setInt(param++, 0); // rc_type + ps.setInt(param++, 0); // rc_minor + ps.setInt(param++, pageId); // rc_cur_id + ps.setInt(param++, userId); // rc_user + ps.setString(param++, userText); // rc_user_text + ps.setString(param++, revComment); // rc_comment + ps.setLong(param++, nextTextId); // rc_this_oldid + ps.setLong(param++, textId); // rc_last_oldid + ps.setInt(param++, 0); // rc_bot + ps.setInt(param++, 0); // rc_moved_to_ns + ps.setString(param++, ""); // rc_moved_to_title + ps.setString(param++, userIp); // rc_ip + ps.setInt(param++, pageText.length()); // rc_old_len + ps.setInt(param++, pageText.length()); // rc_new_len + execute(conn, ps); + } - // This is always executed, sometimes as a separate transaction, - // sometimes together with the previous one - - try (PreparedStatement ps = this.getPreparedStatement(conn, insertLogging)) { - int param = 1; - ps.setString(param++, timestamp); - ps.setInt(param++, userId); - ps.setString(param++, pageTitle); - ps.setInt(param++, pageNamespace); - ps.setString(param++, userText); - ps.setInt(param++, pageId); - ps.setString(param++, String.format("%d\n%d\n%d", nextRevId, revisionId, 1)); - execute(conn, ps); + // REMOVED + // sql="INSERT INTO `cu_changes` () VALUES ();"; + // st.addBatch(sql); + + // SELECT WATCHING USERS + ArrayList wlUser = new ArrayList<>(); + try (PreparedStatement ps = this.getPreparedStatement(conn, selectWatchList)) { + int param = 1; + ps.setString(param++, pageTitle); + ps.setInt(param++, pageNamespace); + ps.setInt(param++, userId); + try (ResultSet rs = ps.executeQuery()) { + + while (rs.next()) { + wlUser.add(rs.getInt(1)); } + } + } - try (PreparedStatement ps = this.getPreparedStatement(conn, updateUserEdit)) { - int param = 1; - ps.setInt(param++, userId); - execute(conn, ps); + // ===================================================================== + // UPDATING WATCHLIST: txn3 (not always, only if someone is watching the + // page, might be part of txn2) + // ===================================================================== + if (!wlUser.isEmpty()) { + + try (PreparedStatement ps = this.getPreparedStatement(conn, updateWatchList)) { + int param = 1; + ps.setString(param++, timestamp); + ps.setString(param++, pageTitle); + ps.setInt(param++, pageNamespace); + for (Integer otherUserId : wlUser) { + ps.setInt(param, otherUserId); + ps.addBatch(); } - - try (PreparedStatement ps = this.getPreparedStatement(conn, updateUserTouched)) { - int param = 1; - ps.setString(param++, timestamp); - ps.setInt(param++, userId); - execute(conn, ps); + executeBatch(conn, ps); + } + + // ===================================================================== + // UPDATING USER AND LOGGING STUFF: txn4 (might still be part of + // txn2) + // ===================================================================== + + // This seems to be executed only if the page is watched, and once + + try (PreparedStatement ps = this.getPreparedStatement(conn, selectUser)) { + int param = 1; + for (Integer otherUserId : wlUser) { + ps.setInt(param, otherUserId); + try (ResultSet rs = ps.executeQuery()) { + rs.next(); + } } + } } - public void execute(Connection conn, PreparedStatement p) throws SQLException { + // This is always executed, sometimes as a separate transaction, + // sometimes together with the previous one + + try (PreparedStatement ps = this.getPreparedStatement(conn, insertLogging)) { + int param = 1; + ps.setString(param++, timestamp); + ps.setInt(param++, userId); + ps.setString(param++, pageTitle); + ps.setInt(param++, pageNamespace); + ps.setString(param++, userText); + ps.setInt(param++, pageId); + ps.setString(param++, String.format("%d\n%d\n%d", nextRevId, revisionId, 1)); + execute(conn, ps); + } - p.execute(); + try (PreparedStatement ps = this.getPreparedStatement(conn, updateUserEdit)) { + int param = 1; + ps.setInt(param++, userId); + execute(conn, ps); + } + try (PreparedStatement ps = this.getPreparedStatement(conn, updateUserTouched)) { + int param = 1; + ps.setString(param++, timestamp); + ps.setInt(param++, userId); + execute(conn, ps); } + } - public void executeBatch(Connection conn, PreparedStatement p) throws SQLException { + public void execute(Connection conn, PreparedStatement p) throws SQLException { - p.executeBatch(); - - } -} + p.execute(); + } + public void executeBatch(Connection conn, PreparedStatement p) throws SQLException { + p.executeBatch(); + } +} diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/Article.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/Article.java index 680864c8c..d5a6d8ce4 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/Article.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/Article.java @@ -15,25 +15,22 @@ * */ - package com.oltpbenchmark.benchmarks.wikipedia.util; public class Article { - public String userText; - public int pageId; - public String oldText; - public long textId; - public long revisionId; - - public Article(String userText, int pageId, String oldText, long textId, - long revisionId) { - super(); - this.userText = userText; - this.pageId = pageId; - this.oldText = oldText; - this.textId = textId; - this.revisionId = revisionId; - } + public String userText; + public int pageId; + public String oldText; + public long textId; + public long revisionId; + public Article(String userText, int pageId, String oldText, long textId, long revisionId) { + super(); + this.userText = userText; + this.pageId = pageId; + this.oldText = oldText; + this.textId = textId; + this.revisionId = revisionId; + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/WikipediaUtil.java b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/WikipediaUtil.java index 3f93f5e6e..0400aa4b8 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/WikipediaUtil.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/wikipedia/util/WikipediaUtil.java @@ -20,26 +20,25 @@ import com.oltpbenchmark.benchmarks.wikipedia.data.PageHistograms; import com.oltpbenchmark.util.RandomDistribution.FlatHistogram; import com.oltpbenchmark.util.TextGenerator; - import java.util.Random; public abstract class WikipediaUtil { - public static String generatePageTitle(Random rand, int page_id) { - // Yo we need to do this to ensure that for a given page_id, we always get back the same title. - // This is a hack for now (as it will break the option in the config file. - // But from what I can tell it works. - rand.setSeed(page_id); - FlatHistogram h_titleLength = new FlatHistogram<>(rand, PageHistograms.TITLE_LENGTH); - // HACK: Always append the page id to the title - // so that it's guaranteed to be unique. - // Otherwise we can get collisions with larger scale factors. - int titleLength = h_titleLength.nextValue(); - return TextGenerator.randomStr(rand, titleLength) + " [" + page_id + "]"; - } + public static String generatePageTitle(Random rand, int page_id) { + // Yo we need to do this to ensure that for a given page_id, we always get back the same title. + // This is a hack for now (as it will break the option in the config file. + // But from what I can tell it works. + rand.setSeed(page_id); + FlatHistogram h_titleLength = new FlatHistogram<>(rand, PageHistograms.TITLE_LENGTH); + // HACK: Always append the page id to the title + // so that it's guaranteed to be unique. + // Otherwise we can get collisions with larger scale factors. + int titleLength = h_titleLength.nextValue(); + return TextGenerator.randomStr(rand, titleLength) + " [" + page_id + "]"; + } - public static int generatePageNamespace(Random rand, int page_id) { - FlatHistogram h_namespace = new FlatHistogram<>(rand, PageHistograms.NAMESPACE); - return h_namespace.nextInt(); - } + public static int generatePageNamespace(Random rand, int page_id) { + FlatHistogram h_namespace = new FlatHistogram<>(rand, PageHistograms.NAMESPACE); + return h_namespace.nextInt(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBBenchmark.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBBenchmark.java index 7a472c3ab..b0a861e6b 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBBenchmark.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBBenchmark.java @@ -24,87 +24,82 @@ import com.oltpbenchmark.benchmarks.ycsb.procedures.InsertRecord; import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public final class YCSBBenchmark extends BenchmarkModule { - private static final Logger LOG = LoggerFactory.getLogger(YCSBBenchmark.class); - - /** - * The length in characters of each field - */ - protected final int fieldSize; + private static final Logger LOG = LoggerFactory.getLogger(YCSBBenchmark.class); - /** - * The constant used in the zipfian distribution (to modify the skew) - */ - protected final double skewFactor; + /** The length in characters of each field */ + protected final int fieldSize; - public YCSBBenchmark(WorkloadConfiguration workConf) { - super(workConf); + /** The constant used in the zipfian distribution (to modify the skew) */ + protected final double skewFactor; - int fieldSize = YCSBConstants.MAX_FIELD_SIZE; - if (workConf.getXmlConfig() != null && workConf.getXmlConfig().containsKey("fieldSize")) { - fieldSize = Math.min(workConf.getXmlConfig().getInt("fieldSize"), YCSBConstants.MAX_FIELD_SIZE); - } - this.fieldSize = fieldSize; - if (this.fieldSize <= 0) { - throw new RuntimeException("Invalid YCSB fieldSize '" + this.fieldSize + "'"); - } + public YCSBBenchmark(WorkloadConfiguration workConf) { + super(workConf); - double skewFactor = 0.99; - if (workConf.getXmlConfig() != null && workConf.getXmlConfig().containsKey("skewFactor")) { - skewFactor = workConf.getXmlConfig().getDouble("skewFactor"); - if (skewFactor <= 0 || skewFactor >= 1) { - throw new RuntimeException("Invalid YCSB skewFactor '" + skewFactor + "'"); - } - } - this.skewFactor = skewFactor; + int fieldSize = YCSBConstants.MAX_FIELD_SIZE; + if (workConf.getXmlConfig() != null && workConf.getXmlConfig().containsKey("fieldSize")) { + fieldSize = + Math.min(workConf.getXmlConfig().getInt("fieldSize"), YCSBConstants.MAX_FIELD_SIZE); } - - @Override - protected List> makeWorkersImpl() { - List> workers = new ArrayList<>(); - try { - // LOADING FROM THE DATABASE IMPORTANT INFORMATION - // LIST OF USERS - Table t = this.getCatalog().getTable("USERTABLE"); - String userCount = SQLUtil.getMaxColSQL(this.workConf.getDatabaseType(), t, "ycsb_key"); - - try (Connection metaConn = this.makeConnection(); - Statement stmt = metaConn.createStatement(); - ResultSet res = stmt.executeQuery(userCount)) { - int init_record_count = 0; - while (res.next()) { - init_record_count = res.getInt(1); - } - - for (int i = 0; i < workConf.getTerminals(); ++i) { - workers.add(new YCSBWorker(this, i, init_record_count + 1)); - } - } - } catch (SQLException e) { - LOG.error(e.getMessage(), e); - } - return workers; + this.fieldSize = fieldSize; + if (this.fieldSize <= 0) { + throw new RuntimeException("Invalid YCSB fieldSize '" + this.fieldSize + "'"); } - @Override - protected Loader makeLoaderImpl() { - return new YCSBLoader(this); + double skewFactor = 0.99; + if (workConf.getXmlConfig() != null && workConf.getXmlConfig().containsKey("skewFactor")) { + skewFactor = workConf.getXmlConfig().getDouble("skewFactor"); + if (skewFactor <= 0 || skewFactor >= 1) { + throw new RuntimeException("Invalid YCSB skewFactor '" + skewFactor + "'"); + } } + this.skewFactor = skewFactor; + } + + @Override + protected List> makeWorkersImpl() { + List> workers = new ArrayList<>(); + try { + // LOADING FROM THE DATABASE IMPORTANT INFORMATION + // LIST OF USERS + Table t = this.getCatalog().getTable("USERTABLE"); + String userCount = SQLUtil.getMaxColSQL(this.workConf.getDatabaseType(), t, "ycsb_key"); + + try (Connection metaConn = this.makeConnection(); + Statement stmt = metaConn.createStatement(); + ResultSet res = stmt.executeQuery(userCount)) { + int init_record_count = 0; + while (res.next()) { + init_record_count = res.getInt(1); + } - @Override - protected Package getProcedurePackageImpl() { - return InsertRecord.class.getPackage(); + for (int i = 0; i < workConf.getTerminals(); ++i) { + workers.add(new YCSBWorker(this, i, init_record_count + 1)); + } + } + } catch (SQLException e) { + LOG.error(e.getMessage(), e); } - + return workers; + } + + @Override + protected Loader makeLoaderImpl() { + return new YCSBLoader(this); + } + + @Override + protected Package getProcedurePackageImpl() { + return InsertRecord.class.getPackage(); + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBConstants.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBConstants.java index 7b14a61a9..2e8227b07 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBConstants.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBConstants.java @@ -19,23 +19,20 @@ public abstract class YCSBConstants { - public static final int RECORD_COUNT = 1000; + public static final int RECORD_COUNT = 1000; - public static final int NUM_FIELDS = 10; + public static final int NUM_FIELDS = 10; - /** - * The max size of each field in the USERTABLE. - * NOTE: If you increase this value here in the code, then you must update all the DDL files. - */ - public static final int MAX_FIELD_SIZE = 100; // chars + /** + * The max size of each field in the USERTABLE. NOTE: If you increase this value here in the code, + * then you must update all the DDL files. + */ + public static final int MAX_FIELD_SIZE = 100; // chars - /** - * How many records will each thread load. - */ - public static final int THREAD_BATCH_SIZE = 50000; + /** How many records will each thread load. */ + public static final int THREAD_BATCH_SIZE = 50000; - public static final int MAX_SCAN = 1000; - - public static final String TABLE_NAME = "usertable"; + public static final int MAX_SCAN = 1000; + public static final String TABLE_NAME = "usertable"; } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java index 707874ae5..6c7314643 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBLoader.java @@ -22,7 +22,6 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -30,71 +29,70 @@ import java.util.List; class YCSBLoader extends Loader { - private final int num_record; + private final int num_record; - public YCSBLoader(YCSBBenchmark benchmark) { - super(benchmark); - this.num_record = (int) Math.round(YCSBConstants.RECORD_COUNT * this.scaleFactor); - if (LOG.isDebugEnabled()) { - LOG.debug("# of RECORDS: {}", this.num_record); - } + public YCSBLoader(YCSBBenchmark benchmark) { + super(benchmark); + this.num_record = (int) Math.round(YCSBConstants.RECORD_COUNT * this.scaleFactor); + if (LOG.isDebugEnabled()) { + LOG.debug("# of RECORDS: {}", this.num_record); } + } - @Override - public List createLoaderThreads() { - List threads = new ArrayList<>(); - int count = 0; - while (count < this.num_record) { - final int start = count; - final int stop = Math.min(start + YCSBConstants.THREAD_BATCH_SIZE, this.num_record); - threads.add(new LoaderThread(this.benchmark) { - @Override - public void load(Connection conn) throws SQLException { - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("YCSBLoadThread[%d, %d]", start, stop)); - } - loadRecords(conn, start, stop); - } - }); - count = stop; - } - return (threads); + @Override + public List createLoaderThreads() { + List threads = new ArrayList<>(); + int count = 0; + while (count < this.num_record) { + final int start = count; + final int stop = Math.min(start + YCSBConstants.THREAD_BATCH_SIZE, this.num_record); + threads.add( + new LoaderThread(this.benchmark) { + @Override + public void load(Connection conn) throws SQLException { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("YCSBLoadThread[%d, %d]", start, stop)); + } + loadRecords(conn, start, stop); + } + }); + count = stop; } + return (threads); + } - private void loadRecords(Connection conn, int start, int stop) throws SQLException { - Table catalog_tbl = benchmark.getCatalog().getTable("USERTABLE"); - + private void loadRecords(Connection conn, int start, int stop) throws SQLException { + Table catalog_tbl = benchmark.getCatalog().getTable("USERTABLE"); - String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); - try (PreparedStatement stmt = conn.prepareStatement(sql)) { - long total = 0; - int batch = 0; - for (int i = start; i < stop; i++) { - stmt.setInt(1, i); - for (int j = 0; j < YCSBConstants.NUM_FIELDS; j++) { - stmt.setString(j + 2, TextGenerator.randomStr(rng(), benchmark.fieldSize)); - } - stmt.addBatch(); - total++; - if (++batch >= workConf.getBatchSize()) { - stmt.executeBatch(); + String sql = SQLUtil.getInsertSQL(catalog_tbl, this.getDatabaseType()); + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + long total = 0; + int batch = 0; + for (int i = start; i < stop; i++) { + stmt.setInt(1, i); + for (int j = 0; j < YCSBConstants.NUM_FIELDS; j++) { + stmt.setString(j + 2, TextGenerator.randomStr(rng(), benchmark.fieldSize)); + } + stmt.addBatch(); + total++; + if (++batch >= workConf.getBatchSize()) { + stmt.executeBatch(); - batch = 0; - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Records Loaded %d / %d", total, this.num_record)); - } - } - } - if (batch > 0) { - stmt.executeBatch(); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("Records Loaded %d / %d", total, this.num_record)); - } - } + batch = 0; + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Records Loaded %d / %d", total, this.num_record)); + } } + } + if (batch > 0) { + stmt.executeBatch(); if (LOG.isDebugEnabled()) { - LOG.debug("Finished loading {}", catalog_tbl.getName()); + LOG.debug(String.format("Records Loaded %d / %d", total, this.num_record)); } + } } - + if (LOG.isDebugEnabled()) { + LOG.debug("Finished loading {}", catalog_tbl.getName()); + } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java index 1d2ba38c6..eb6227fa5 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/YCSBWorker.java @@ -26,121 +26,122 @@ import com.oltpbenchmark.distributions.ZipfianGenerator; import com.oltpbenchmark.types.TransactionStatus; import com.oltpbenchmark.util.TextGenerator; - import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; /** - * YCSBWorker Implementation - * I forget who really wrote this but I fixed it up in 2016... + * YCSBWorker Implementation I forget who really wrote this but I fixed it up in 2016... * * @author pavlo */ class YCSBWorker extends Worker { - private final ZipfianGenerator readRecord; - private static CounterGenerator insertRecord; - private final ZipfianGenerator randScan; - - private final char[] data; - private final String[] params = new String[YCSBConstants.NUM_FIELDS]; - private final String[] results = new String[YCSBConstants.NUM_FIELDS]; - - private final UpdateRecord procUpdateRecord; - private final ScanRecord procScanRecord; - private final ReadRecord procReadRecord; - private final ReadModifyWriteRecord procReadModifyWriteRecord; - private final InsertRecord procInsertRecord; - private final DeleteRecord procDeleteRecord; - - public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) { - super(benchmarkModule, id); - this.data = new char[benchmarkModule.fieldSize]; - this.readRecord = new ZipfianGenerator(rng(), init_record_count, benchmarkModule.skewFactor);// pool for read keys - this.randScan = new ZipfianGenerator(rng(), YCSBConstants.MAX_SCAN, benchmarkModule.skewFactor); - - synchronized (YCSBWorker.class) { - // We must know where to start inserting - if (insertRecord == null) { - insertRecord = new CounterGenerator(init_record_count); - } - } - - // This is a minor speed-up to avoid having to invoke the hashmap look-up - // everytime we want to execute a txn. This is important to do on - // a client machine with not a lot of cores - this.procUpdateRecord = this.getProcedure(UpdateRecord.class); - this.procScanRecord = this.getProcedure(ScanRecord.class); - this.procReadRecord = this.getProcedure(ReadRecord.class); - this.procReadModifyWriteRecord = this.getProcedure(ReadModifyWriteRecord.class); - this.procInsertRecord = this.getProcedure(InsertRecord.class); - this.procDeleteRecord = this.getProcedure(DeleteRecord.class); + private final ZipfianGenerator readRecord; + private static CounterGenerator insertRecord; + private final ZipfianGenerator randScan; + + private final char[] data; + private final String[] params = new String[YCSBConstants.NUM_FIELDS]; + private final String[] results = new String[YCSBConstants.NUM_FIELDS]; + + private final UpdateRecord procUpdateRecord; + private final ScanRecord procScanRecord; + private final ReadRecord procReadRecord; + private final ReadModifyWriteRecord procReadModifyWriteRecord; + private final InsertRecord procInsertRecord; + private final DeleteRecord procDeleteRecord; + + public YCSBWorker(YCSBBenchmark benchmarkModule, int id, int init_record_count) { + super(benchmarkModule, id); + this.data = new char[benchmarkModule.fieldSize]; + this.readRecord = + new ZipfianGenerator( + rng(), init_record_count, benchmarkModule.skewFactor); // pool for read keys + this.randScan = new ZipfianGenerator(rng(), YCSBConstants.MAX_SCAN, benchmarkModule.skewFactor); + + synchronized (YCSBWorker.class) { + // We must know where to start inserting + if (insertRecord == null) { + insertRecord = new CounterGenerator(init_record_count); + } } - @Override - protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) throws UserAbortException, SQLException { - Class procClass = nextTrans.getProcedureClass(); - - if (procClass.equals(DeleteRecord.class)) { - deleteRecord(conn); - } else if (procClass.equals(InsertRecord.class)) { - insertRecord(conn); - } else if (procClass.equals(ReadModifyWriteRecord.class)) { - readModifyWriteRecord(conn); - } else if (procClass.equals(ReadRecord.class)) { - readRecord(conn); - } else if (procClass.equals(ScanRecord.class)) { - scanRecord(conn); - } else if (procClass.equals(UpdateRecord.class)) { - updateRecord(conn); - } - return (TransactionStatus.SUCCESS); + // This is a minor speed-up to avoid having to invoke the hashmap look-up + // everytime we want to execute a txn. This is important to do on + // a client machine with not a lot of cores + this.procUpdateRecord = this.getProcedure(UpdateRecord.class); + this.procScanRecord = this.getProcedure(ScanRecord.class); + this.procReadRecord = this.getProcedure(ReadRecord.class); + this.procReadModifyWriteRecord = this.getProcedure(ReadModifyWriteRecord.class); + this.procInsertRecord = this.getProcedure(InsertRecord.class); + this.procDeleteRecord = this.getProcedure(DeleteRecord.class); + } + + @Override + protected TransactionStatus executeWork(Connection conn, TransactionType nextTrans) + throws UserAbortException, SQLException { + Class procClass = nextTrans.getProcedureClass(); + + if (procClass.equals(DeleteRecord.class)) { + deleteRecord(conn); + } else if (procClass.equals(InsertRecord.class)) { + insertRecord(conn); + } else if (procClass.equals(ReadModifyWriteRecord.class)) { + readModifyWriteRecord(conn); + } else if (procClass.equals(ReadRecord.class)) { + readRecord(conn); + } else if (procClass.equals(ScanRecord.class)) { + scanRecord(conn); + } else if (procClass.equals(UpdateRecord.class)) { + updateRecord(conn); } + return (TransactionStatus.SUCCESS); + } - private void updateRecord(Connection conn) throws SQLException { + private void updateRecord(Connection conn) throws SQLException { - int keyname = readRecord.nextInt(); - this.buildParameters(); - this.procUpdateRecord.run(conn, keyname, this.params); - } + int keyname = readRecord.nextInt(); + this.buildParameters(); + this.procUpdateRecord.run(conn, keyname, this.params); + } - private void scanRecord(Connection conn) throws SQLException { + private void scanRecord(Connection conn) throws SQLException { - int keyname = readRecord.nextInt(); - int count = randScan.nextInt(); - this.procScanRecord.run(conn, keyname, count, new ArrayList<>()); - } + int keyname = readRecord.nextInt(); + int count = randScan.nextInt(); + this.procScanRecord.run(conn, keyname, count, new ArrayList<>()); + } - private void readRecord(Connection conn) throws SQLException { + private void readRecord(Connection conn) throws SQLException { - int keyname = readRecord.nextInt(); - this.procReadRecord.run(conn, keyname, this.results); - } + int keyname = readRecord.nextInt(); + this.procReadRecord.run(conn, keyname, this.results); + } - private void readModifyWriteRecord(Connection conn) throws SQLException { + private void readModifyWriteRecord(Connection conn) throws SQLException { - int keyname = readRecord.nextInt(); - this.buildParameters(); - this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results); - } + int keyname = readRecord.nextInt(); + this.buildParameters(); + this.procReadModifyWriteRecord.run(conn, keyname, this.params, this.results); + } - private void insertRecord(Connection conn) throws SQLException { + private void insertRecord(Connection conn) throws SQLException { - int keyname = insertRecord.nextInt(); - this.buildParameters(); - this.procInsertRecord.run(conn, keyname, this.params); - } + int keyname = insertRecord.nextInt(); + this.buildParameters(); + this.procInsertRecord.run(conn, keyname, this.params); + } - private void deleteRecord(Connection conn) throws SQLException { + private void deleteRecord(Connection conn) throws SQLException { - int keyname = readRecord.nextInt(); - this.procDeleteRecord.run(conn, keyname); - } + int keyname = readRecord.nextInt(); + this.procDeleteRecord.run(conn, keyname); + } - private void buildParameters() { - for (int i = 0; i < this.params.length; i++) { - this.params[i] = new String(TextGenerator.randomFastChars(rng(), this.data)); - } + private void buildParameters() { + for (int i = 0; i < this.params.length; i++) { + this.params[i] = new String(TextGenerator.randomFastChars(rng(), this.data)); } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/DeleteRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/DeleteRecord.java index b2823528b..bdd3fd4da 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/DeleteRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/DeleteRecord.java @@ -17,26 +17,22 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class DeleteRecord extends Procedure { - public final SQLStmt deleteStmt = new SQLStmt( - "DELETE FROM " + TABLE_NAME + " where YCSB_KEY=?" - ); + public final SQLStmt deleteStmt = new SQLStmt("DELETE FROM " + TABLE_NAME + " where YCSB_KEY=?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, deleteStmt)) { - stmt.setInt(1, keyname); - stmt.executeUpdate(); - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, deleteStmt)) { + stmt.setInt(1, keyname); + stmt.executeUpdate(); } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/InsertRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/InsertRecord.java index 023539164..17fc62c45 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/InsertRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/InsertRecord.java @@ -17,29 +17,26 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class InsertRecord extends Procedure { - public final SQLStmt insertStmt = new SQLStmt( - "INSERT INTO " + TABLE_NAME + " VALUES (?,?,?,?,?,?,?,?,?,?,?)" - ); + public final SQLStmt insertStmt = + new SQLStmt("INSERT INTO " + TABLE_NAME + " VALUES (?,?,?,?,?,?,?,?,?,?,?)"); - // FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, String[] vals) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, this.insertStmt)) { - stmt.setInt(1, keyname); - for (int i = 0; i < vals.length; i++) { - stmt.setString(i + 2, vals[i]); - } - stmt.executeUpdate(); - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, String[] vals) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, this.insertStmt)) { + stmt.setInt(1, keyname); + for (int i = 0; i < vals.length; i++) { + stmt.setString(i + 2, vals[i]); + } + stmt.executeUpdate(); } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadModifyWriteRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadModifyWriteRecord.java index 0ed568920..fe5263567 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadModifyWriteRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadModifyWriteRecord.java @@ -17,52 +17,50 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class ReadModifyWriteRecord extends Procedure { - public final SQLStmt selectStmt = new SQLStmt( - "SELECT * FROM " + TABLE_NAME + " where YCSB_KEY=? FOR UPDATE" - ); - public final SQLStmt updateAllStmt = new SQLStmt( - "UPDATE " + TABLE_NAME + " SET FIELD1=?,FIELD2=?,FIELD3=?,FIELD4=?,FIELD5=?," + - "FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?" - ); + public final SQLStmt selectStmt = + new SQLStmt("SELECT * FROM " + TABLE_NAME + " where YCSB_KEY=? FOR UPDATE"); + public final SQLStmt updateAllStmt = + new SQLStmt( + "UPDATE " + + TABLE_NAME + + " SET FIELD1=?,FIELD2=?,FIELD3=?,FIELD4=?,FIELD5=?," + + "FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, String[] fields, String[] results) throws SQLException { - - // Fetch it! - try (PreparedStatement stmt = this.getPreparedStatement(conn, selectStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 0; i < YCSBConstants.NUM_FIELDS; i++) { - results[i] = r.getString(i + 1); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, String[] fields, String[] results) + throws SQLException { + // Fetch it! + try (PreparedStatement stmt = this.getPreparedStatement(conn, selectStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 0; i < YCSBConstants.NUM_FIELDS; i++) { + results[i] = r.getString(i + 1); + } } + } + } - // Update that mofo - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateAllStmt)) { - stmt.setInt(11, keyname); - - for (int i = 0; i < fields.length; i++) { - stmt.setString(i + 1, fields[i]); - } - stmt.executeUpdate(); - } + // Update that mofo + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateAllStmt)) { + stmt.setInt(11, keyname); + for (int i = 0; i < fields.length; i++) { + stmt.setString(i + 1, fields[i]); + } + stmt.executeUpdate(); } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadRecord.java index 445ae89de..49b43f144 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ReadRecord.java @@ -17,34 +17,30 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class ReadRecord extends Procedure { - public final SQLStmt readStmt = new SQLStmt( - "SELECT * FROM " + TABLE_NAME + " WHERE YCSB_KEY=?" - ); + public final SQLStmt readStmt = new SQLStmt("SELECT * FROM " + TABLE_NAME + " WHERE YCSB_KEY=?"); - //FIXME: The value in ysqb is a byteiterator - public void run(Connection conn, int keyname, String[] results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { - stmt.setInt(1, keyname); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - for (int i = 0; i < YCSBConstants.NUM_FIELDS; i++) { - results[i] = r.getString(i + 1); - } - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int keyname, String[] results) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, readStmt)) { + stmt.setInt(1, keyname); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + for (int i = 0; i < YCSBConstants.NUM_FIELDS; i++) { + results[i] = r.getString(i + 1); + } } + } } - + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ScanRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ScanRecord.java index 96e6c0fba..3e52a382e 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ScanRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/ScanRecord.java @@ -17,37 +17,36 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; import com.oltpbenchmark.benchmarks.ycsb.YCSBConstants; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class ScanRecord extends Procedure { - public final SQLStmt scanStmt = new SQLStmt( - "SELECT * FROM " + TABLE_NAME + " WHERE YCSB_KEY>? AND YCSB_KEY? AND YCSB_KEY results) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, scanStmt)) { - stmt.setInt(1, start); - stmt.setInt(2, start + count); - try (ResultSet r = stmt.executeQuery()) { - while (r.next()) { - String[] data = new String[YCSBConstants.NUM_FIELDS]; - for (int i = 0; i < data.length; i++) { - data[i] = r.getString(i + 1); - } - results.add(data); - } - } + // FIXME: The value in ysqb is a byteiterator + public void run(Connection conn, int start, int count, List results) + throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, scanStmt)) { + stmt.setInt(1, start); + stmt.setInt(2, start + count); + try (ResultSet r = stmt.executeQuery()) { + while (r.next()) { + String[] data = new String[YCSBConstants.NUM_FIELDS]; + for (int i = 0; i < data.length; i++) { + data[i] = r.getString(i + 1); + } + results.add(data); } + } } + } } diff --git a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/UpdateRecord.java b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/UpdateRecord.java index e993e843d..dbc9fefa2 100644 --- a/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/UpdateRecord.java +++ b/src/main/java/com/oltpbenchmark/benchmarks/ycsb/procedures/UpdateRecord.java @@ -17,31 +17,31 @@ package com.oltpbenchmark.benchmarks.ycsb.procedures; +import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; + import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.SQLStmt; - import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; -import static com.oltpbenchmark.benchmarks.ycsb.YCSBConstants.TABLE_NAME; - public class UpdateRecord extends Procedure { - public final SQLStmt updateAllStmt = new SQLStmt( - "UPDATE " + TABLE_NAME + " SET FIELD1=?,FIELD2=?,FIELD3=?,FIELD4=?,FIELD5=?," + - "FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?" - ); - - public void run(Connection conn, int keyname, String[] vals) throws SQLException { - try (PreparedStatement stmt = this.getPreparedStatement(conn, updateAllStmt)) { - - stmt.setInt(11, keyname); - for (int i = 0; i < vals.length; i++) { - stmt.setString(i + 1, vals[i]); - } - stmt.executeUpdate(); - } + public final SQLStmt updateAllStmt = + new SQLStmt( + "UPDATE " + + TABLE_NAME + + " SET FIELD1=?,FIELD2=?,FIELD3=?,FIELD4=?,FIELD5=?," + + "FIELD6=?,FIELD7=?,FIELD8=?,FIELD9=?,FIELD10=? WHERE YCSB_KEY=?"); + + public void run(Connection conn, int keyname, String[] vals) throws SQLException { + try (PreparedStatement stmt = this.getPreparedStatement(conn, updateAllStmt)) { + + stmt.setInt(11, keyname); + for (int i = 0; i < vals.length; i++) { + stmt.setString(i + 1, vals[i]); + } + stmt.executeUpdate(); } + } } - diff --git a/src/main/java/com/oltpbenchmark/catalog/AbstractCatalog.java b/src/main/java/com/oltpbenchmark/catalog/AbstractCatalog.java index eb6799569..ed6edcad7 100644 --- a/src/main/java/com/oltpbenchmark/catalog/AbstractCatalog.java +++ b/src/main/java/com/oltpbenchmark/catalog/AbstractCatalog.java @@ -6,12 +6,14 @@ /** * An abstraction over a database's catalog. * - * Concretely, this abstraction supports two types of catalogs: - * - "real" catalogs, which query the table directly; - * - catalogs backed by an in-memory instance of HSQLDB, in case the DBMS is unable to support certain SQL queries. + *

Concretely, this abstraction supports two types of catalogs: - "real" catalogs, which query + * the table directly; - catalogs backed by an in-memory instance of HSQLDB, in case the DBMS is + * unable to support certain SQL queries. */ public interface AbstractCatalog { - Collection getTables(); - Table getTable(String tableName); - void close() throws SQLException; + Collection
getTables(); + + Table getTable(String tableName); + + void close() throws SQLException; } diff --git a/src/main/java/com/oltpbenchmark/catalog/AbstractCatalogObject.java b/src/main/java/com/oltpbenchmark/catalog/AbstractCatalogObject.java index b3b9820a3..172e71a5a 100644 --- a/src/main/java/com/oltpbenchmark/catalog/AbstractCatalogObject.java +++ b/src/main/java/com/oltpbenchmark/catalog/AbstractCatalogObject.java @@ -26,49 +26,47 @@ * @author pavlo */ public abstract class AbstractCatalogObject implements Serializable { - static final long serialVersionUID = 0; + static final long serialVersionUID = 0; - protected final String name; - protected final String separator; + protected final String name; + protected final String separator; - public AbstractCatalogObject(String name, String separator) { - this.name = name; - this.separator = separator; - } - - public String getName() { - return name; - } + public AbstractCatalogObject(String name, String separator) { + this.name = name; + this.separator = separator; + } - public String getSeparator() { - return separator; - } + public String getName() { + return name; + } - public final String getEscapedName() { + public String getSeparator() { + return separator; + } - if (separator != null) { - return separator + this.name + separator; - } else { - return this.name; - } + public final String getEscapedName() { + if (separator != null) { + return separator + this.name + separator; + } else { + return this.name; } + } - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AbstractCatalogObject that = (AbstractCatalogObject) o; - return Objects.equals(name, that.name) && - Objects.equals(separator, that.separator); + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public int hashCode() { - return Objects.hash(name, separator); + if (o == null || getClass() != o.getClass()) { + return false; } + AbstractCatalogObject that = (AbstractCatalogObject) o; + return Objects.equals(name, that.name) && Objects.equals(separator, that.separator); + } + + @Override + public int hashCode() { + return Objects.hash(name, separator); + } } diff --git a/src/main/java/com/oltpbenchmark/catalog/Catalog.java b/src/main/java/com/oltpbenchmark/catalog/Catalog.java index 57a0a5c7c..9b8f4917e 100644 --- a/src/main/java/com/oltpbenchmark/catalog/Catalog.java +++ b/src/main/java/com/oltpbenchmark/catalog/Catalog.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.catalog; import java.sql.SQLException; @@ -27,30 +26,29 @@ */ public final class Catalog implements AbstractCatalog { - private final Map tables; + private final Map tables; - public Catalog(Map tables) { - this.tables = tables; - } + public Catalog(Map tables) { + this.tables = tables; + } - @Override - public Collection
getTables() { - return (this.tables.values()); - } - - @Override - public Table getTable(String tableName) { - for (Table table : tables.values()) { - if (table.getName().equalsIgnoreCase(tableName)) { - return table; - } - } - throw new IllegalArgumentException(String.format("no table found with name [%s]", tableName)); - } + @Override + public Collection
getTables() { + return (this.tables.values()); + } - @Override - public void close() throws SQLException { - // No-op. + @Override + public Table getTable(String tableName) { + for (Table table : tables.values()) { + if (table.getName().equalsIgnoreCase(tableName)) { + return table; + } } + throw new IllegalArgumentException(String.format("no table found with name [%s]", tableName)); + } + @Override + public void close() throws SQLException { + // No-op. + } } diff --git a/src/main/java/com/oltpbenchmark/catalog/Column.java b/src/main/java/com/oltpbenchmark/catalog/Column.java index 5e58a1441..7d91c71cc 100644 --- a/src/main/java/com/oltpbenchmark/catalog/Column.java +++ b/src/main/java/com/oltpbenchmark/catalog/Column.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.catalog; import java.util.Objects; @@ -26,72 +25,73 @@ * @author pavlo */ public class Column extends AbstractCatalogObject { - private static final long serialVersionUID = 1L; - - private final Table table; - private final int type; - private final Integer size; - private final boolean nullable; - - private Column foreignKey = null; - - public Column(String name, String separator, Table table, int type, Integer size, boolean nullable) { - super(name, separator); - this.table = table; - this.type = type; - this.size = size; - this.nullable = nullable; - } - - public Table getTable() { - return table; - } - - public int getType() { - return type; - } - - public Integer getSize() { - return size; + private static final long serialVersionUID = 1L; + + private final Table table; + private final int type; + private final Integer size; + private final boolean nullable; + + private Column foreignKey = null; + + public Column( + String name, String separator, Table table, int type, Integer size, boolean nullable) { + super(name, separator); + this.table = table; + this.type = type; + this.size = size; + this.nullable = nullable; + } + + public Table getTable() { + return table; + } + + public int getType() { + return type; + } + + public Integer getSize() { + return size; + } + + public boolean isNullable() { + return nullable; + } + + public Column getForeignKey() { + return foreignKey; + } + + public void setForeignKey(Column foreignKey) { + this.foreignKey = foreignKey; + } + + public int getIndex() { + return this.table.getColumnIndex(this); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - public boolean isNullable() { - return nullable; - } - - public Column getForeignKey() { - return foreignKey; - } - - public void setForeignKey(Column foreignKey) { - this.foreignKey = foreignKey; + if (o == null || getClass() != o.getClass()) { + return false; } - - public int getIndex() { - return this.table.getColumnIndex(this); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - if (!super.equals(o)) { - return false; - } - Column column = (Column) o; - return type == column.type && - nullable == column.nullable && - Objects.equals(table, column.table) && - Objects.equals(size, column.size) && - Objects.equals(foreignKey, column.foreignKey); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), table.name, type, size, nullable, foreignKey); + if (!super.equals(o)) { + return false; } + Column column = (Column) o; + return type == column.type + && nullable == column.nullable + && Objects.equals(table, column.table) + && Objects.equals(size, column.size) + && Objects.equals(foreignKey, column.foreignKey); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), table.name, type, size, nullable, foreignKey); + } } diff --git a/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java b/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java index 876dcf530..8823d8d0c 100644 --- a/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java +++ b/src/main/java/com/oltpbenchmark/catalog/HSQLDBCatalog.java @@ -4,8 +4,6 @@ import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.types.SortDirectionType; import com.oltpbenchmark.util.Pair; -import org.apache.commons.io.IOUtils; - import java.io.IOException; import java.net.URL; import java.nio.charset.Charset; @@ -14,224 +12,234 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.apache.commons.io.IOUtils; public final class HSQLDBCatalog implements AbstractCatalog { - private static final String DB_CONNECTION = "jdbc:hsqldb:mem:"; - private static final String DB_JDBC = "org.hsqldb.jdbcDriver"; - private static final DatabaseType DB_TYPE = DatabaseType.HSQLDB; + private static final String DB_CONNECTION = "jdbc:hsqldb:mem:"; + private static final String DB_JDBC = "org.hsqldb.jdbcDriver"; + private static final DatabaseType DB_TYPE = DatabaseType.HSQLDB; - private final BenchmarkModule benchmarkModule; + private final BenchmarkModule benchmarkModule; - private final Map tables = new HashMap<>(); // original table name -> table - private final Map originalTableNames; // HSQLDB uppercase table name -> original table name + private final Map tables = new HashMap<>(); // original table name -> table + private final Map + originalTableNames; // HSQLDB uppercase table name -> original table name - private static final Random rand = new Random(); + private static final Random rand = new Random(); - /** - * Connection to the HSQLDB instance. - */ - private final Connection conn; + /** Connection to the HSQLDB instance. */ + private final Connection conn; - public HSQLDBCatalog(BenchmarkModule benchmarkModule) { - this.benchmarkModule = benchmarkModule; - String dbName = String.format("catalog-%s-%d.db", this.benchmarkModule.getBenchmarkName(), rand.nextInt()); + public HSQLDBCatalog(BenchmarkModule benchmarkModule) { + this.benchmarkModule = benchmarkModule; + String dbName = + String.format("catalog-%s-%d.db", this.benchmarkModule.getBenchmarkName(), rand.nextInt()); - Connection conn; - try { - Class.forName(DB_JDBC); - conn = DriverManager.getConnection(DB_CONNECTION + dbName + ";sql.syntax_mys=true", null, null); - } catch (ClassNotFoundException | SQLException e) { - throw new RuntimeException(e); - } - this.conn = conn; - - this.originalTableNames = this.getOriginalTableNames(); - try { - this.init(); - } catch (SQLException | IOException e) { - throw new RuntimeException(String.format("Failed to initialize %s database catalog.", this.benchmarkModule.getBenchmarkName()), e); - } + Connection conn; + try { + Class.forName(DB_JDBC); + conn = + DriverManager.getConnection(DB_CONNECTION + dbName + ";sql.syntax_mys=true", null, null); + } catch (ClassNotFoundException | SQLException e) { + throw new RuntimeException(e); } - - @Override - public void close() throws SQLException { - this.conn.close(); + this.conn = conn; + + this.originalTableNames = this.getOriginalTableNames(); + try { + this.init(); + } catch (SQLException | IOException e) { + throw new RuntimeException( + String.format( + "Failed to initialize %s database catalog.", this.benchmarkModule.getBenchmarkName()), + e); } + } + + @Override + public void close() throws SQLException { + this.conn.close(); + } + + @Override + public Collection
getTables() { + return tables.values(); + } + + @Override + public Table getTable(String tableName) { + return tables.get(originalTableNames.get(tableName.toUpperCase())); + } + + private void init() throws SQLException, IOException { + // Load the database DDL. + this.benchmarkModule.createDatabase(DB_TYPE, this.conn); + + // TableName -> ColumnName -> + Map>> foreignKeys = new HashMap<>(); + + DatabaseMetaData md = conn.getMetaData(); + ResultSet tableRS = md.getTables(null, null, null, new String[] {"TABLE"}); + while (tableRS.next()) { + String internalTableName = tableRS.getString(3); + String upperTableName = internalTableName.toUpperCase(); + String originalTableName = originalTableNames.get(upperTableName); + + String tableType = tableRS.getString(4); + if (!tableType.equalsIgnoreCase("TABLE")) continue; + + Table catalogTable = new Table(originalTableName, ""); + + // COLUMNS + try (ResultSet colRS = md.getColumns(null, null, internalTableName, null)) { + while (colRS.next()) { + String colName = colRS.getString(4); + int colType = colRS.getInt(5); + @SuppressWarnings("unused") + String colTypeName = colRS.getString(6); + Integer colSize = colRS.getInt(7); + boolean colNullable = colRS.getString(18).equalsIgnoreCase("YES"); + + Column catalogCol = new Column(colName, "", catalogTable, colType, colSize, colNullable); + // TODO(WAN): The following block of code was relevant for programmatic CreateDialect + // support. + // i.e., using the HSQLDB catalog instance to automatically create dialects for + // other DBMSs. + // Since we don't add new database support often, and can hand-write most of + // that, + // it is probably worth the tradeoff to have this functionality removed. + /* + { + String colDefaultValue = colRS.getString(13); + // TODO(WAN): Inherited FIXME autoinc should use colRS.getString(22).toUpperCase().equals("YES") + boolean colAutoInc = false; + catalogCol.setDefaultValue(colDefaultValue); + catalogCol.setAutoInc(colAutoInc); + catalogCol.setNullable(colNullable); + // TODO(WAN): Inherited FIXME setSigned + } + */ + + catalogTable.addColumn(catalogCol); + } + } + + // TODO(WAN): It looks like the primaryKeyColumns were only used in CreateDialect. + /* + { + // PRIMARY KEYS + try (ResultSet pkeyRS = md.getPrimaryKeys(null, null, internalTableName)) { + SortedMap pkeyCols = new TreeMap<>(); + while (pkeyRS.next()) { + String colName = pkeyRS.getString(4); + int colIdx = pkeyRS.getShort(5); + // TODO(WAN): Is this hack still necessary? + // Previously, the index hack is around SQLite not returning the KEY_SEQ. + if (colIdx == 0) colIdx = pkeyCols.size(); + pkeyCols.put(colIdx, colName); + } + } + catalogTable.setPrimaryKeyColumns(pkeyCols.values()); + } + */ + + // INDEXES + try (ResultSet idxRS = md.getIndexInfo(null, null, internalTableName, false, false)) { + while (idxRS.next()) { + int idxType = idxRS.getShort(7); + if (idxType == DatabaseMetaData.tableIndexStatistic) { + continue; + } + boolean idxUnique = !idxRS.getBoolean(4); + String idxName = idxRS.getString(6); + int idxColPos = idxRS.getInt(8) - 1; + String idxColName = idxRS.getString(9); + String sort = idxRS.getString(10); + SortDirectionType idxDirection; + if (sort != null) { + idxDirection = + sort.equalsIgnoreCase("A") ? SortDirectionType.ASC : SortDirectionType.DESC; + } else { + idxDirection = null; + } + + Index catalogIdx = catalogTable.getIndex(idxName); + if (catalogIdx == null) { + catalogIdx = new Index(idxName, "", catalogTable, idxType, idxUnique); + catalogTable.addIndex(catalogIdx); + } + catalogIdx.addColumn(idxColName, idxDirection, idxColPos); + } + } + + // FOREIGN KEYS + try (ResultSet fkRS = md.getImportedKeys(null, null, internalTableName)) { + foreignKeys.put(originalTableName, new HashMap<>()); + while (fkRS.next()) { + String colName = fkRS.getString(8); + String fkTableName = originalTableNames.get(fkRS.getString(3).toUpperCase()); + String fkColName = fkRS.getString(4); + foreignKeys.get(originalTableName).put(colName, Pair.of(fkTableName, fkColName)); + } + } - @Override - public Collection
getTables() { - return tables.values(); + // Register the table to the catalog. + this.tables.put(originalTableName, catalogTable); } - @Override - public Table getTable(String tableName) { - return tables.get(originalTableNames.get(tableName.toUpperCase())); - } + for (Table catalogTable : this.tables.values()) { + Map> fk = foreignKeys.get(catalogTable.getName()); + fk.forEach( + (colName, fkey) -> { + Column catalogCol = catalogTable.getColumnByName(colName); - private void init() throws SQLException, IOException { - // Load the database DDL. - this.benchmarkModule.createDatabase(DB_TYPE, this.conn); - - // TableName -> ColumnName -> - Map>> foreignKeys = new HashMap<>(); - - DatabaseMetaData md = conn.getMetaData(); - ResultSet tableRS = md.getTables(null, null, null, new String[]{"TABLE"}); - while (tableRS.next()) { - String internalTableName = tableRS.getString(3); - String upperTableName = internalTableName.toUpperCase(); - String originalTableName = originalTableNames.get(upperTableName); - - String tableType = tableRS.getString(4); - if (!tableType.equalsIgnoreCase("TABLE")) continue; - - Table catalogTable = new Table(originalTableName, ""); - - // COLUMNS - try (ResultSet colRS = md.getColumns(null, null, internalTableName, null)) { - while (colRS.next()) { - String colName = colRS.getString(4); - int colType = colRS.getInt(5); - @SuppressWarnings("unused") - String colTypeName = colRS.getString(6); - Integer colSize = colRS.getInt(7); - boolean colNullable = colRS.getString(18).equalsIgnoreCase("YES"); - - Column catalogCol = new Column(colName, "", catalogTable, colType, colSize, colNullable); - // TODO(WAN): The following block of code was relevant for programmatic CreateDialect support. - // i.e., using the HSQLDB catalog instance to automatically create dialects for other DBMSs. - // Since we don't add new database support often, and can hand-write most of that, - // it is probably worth the tradeoff to have this functionality removed. - /* - { - String colDefaultValue = colRS.getString(13); - // TODO(WAN): Inherited FIXME autoinc should use colRS.getString(22).toUpperCase().equals("YES") - boolean colAutoInc = false; - catalogCol.setDefaultValue(colDefaultValue); - catalogCol.setAutoInc(colAutoInc); - catalogCol.setNullable(colNullable); - // TODO(WAN): Inherited FIXME setSigned - } - */ - - catalogTable.addColumn(catalogCol); - } + Table fkeyTable = this.tables.get(fkey.first); + if (fkeyTable == null) { + throw new RuntimeException("Unexpected foreign key parent table " + fkey); } - // TODO(WAN): It looks like the primaryKeyColumns were only used in CreateDialect. - /* - { - // PRIMARY KEYS - try (ResultSet pkeyRS = md.getPrimaryKeys(null, null, internalTableName)) { - SortedMap pkeyCols = new TreeMap<>(); - while (pkeyRS.next()) { - String colName = pkeyRS.getString(4); - int colIdx = pkeyRS.getShort(5); - // TODO(WAN): Is this hack still necessary? - // Previously, the index hack is around SQLite not returning the KEY_SEQ. - if (colIdx == 0) colIdx = pkeyCols.size(); - pkeyCols.put(colIdx, colName); - } - } - catalogTable.setPrimaryKeyColumns(pkeyCols.values()); - } - */ - - // INDEXES - try (ResultSet idxRS = md.getIndexInfo(null, null, internalTableName, false, false)) { - while (idxRS.next()) { - int idxType = idxRS.getShort(7); - if (idxType == DatabaseMetaData.tableIndexStatistic) { - continue; - } - boolean idxUnique = !idxRS.getBoolean(4); - String idxName = idxRS.getString(6); - int idxColPos = idxRS.getInt(8) - 1; - String idxColName = idxRS.getString(9); - String sort = idxRS.getString(10); - SortDirectionType idxDirection; - if (sort != null) { - idxDirection = sort.equalsIgnoreCase("A") ? SortDirectionType.ASC : SortDirectionType.DESC; - } else { - idxDirection = null; - } - - Index catalogIdx = catalogTable.getIndex(idxName); - if (catalogIdx == null) { - catalogIdx = new Index(idxName, "", catalogTable, idxType, idxUnique); - catalogTable.addIndex(catalogIdx); - } - catalogIdx.addColumn(idxColName, idxDirection, idxColPos); - } + Column fkeyCol = fkeyTable.getColumnByName(fkey.second); + if (fkeyCol == null) { + throw new RuntimeException("Unexpected foreign key parent column " + fkey); } - // FOREIGN KEYS - try (ResultSet fkRS = md.getImportedKeys(null, null, internalTableName)) { - foreignKeys.put(originalTableName, new HashMap<>()); - while (fkRS.next()) { - String colName = fkRS.getString(8); - String fkTableName = originalTableNames.get(fkRS.getString(3).toUpperCase()); - String fkColName = fkRS.getString(4); - foreignKeys.get(originalTableName).put(colName, Pair.of(fkTableName, fkColName)); - } - } - - // Register the table to the catalog. - this.tables.put(originalTableName, catalogTable); - } - - for (Table catalogTable : this.tables.values()) { - Map> fk = foreignKeys.get(catalogTable.getName()); - fk.forEach((colName, fkey) -> { - Column catalogCol = catalogTable.getColumnByName(colName); - - Table fkeyTable = this.tables.get(fkey.first); - if (fkeyTable == null) { - throw new RuntimeException("Unexpected foreign key parent table " + fkey); - } - - Column fkeyCol = fkeyTable.getColumnByName(fkey.second); - if (fkeyCol == null) { - throw new RuntimeException("Unexpected foreign key parent column " + fkey); - } - - catalogCol.setForeignKey(fkeyCol); - }); - } + catalogCol.setForeignKey(fkeyCol); + }); + } + } + + /** + * HACK: HSQLDB will always uppercase table names. The original table names are extracted from the + * DDL. + * + * @return A map from the original table names to the uppercase HSQLDB table names. + */ + Map getOriginalTableNames() { + // Get the contents of the HSQLDB DDL for the current benchmark. + String ddlContents; + try { + String ddlPath = this.benchmarkModule.getWorkloadConfiguration().getDDLPath(); + URL ddlURL; + if (ddlPath == null) { + ddlPath = this.benchmarkModule.getDatabaseDDLPath(DatabaseType.HSQLDB); + ddlURL = Objects.requireNonNull(this.getClass().getResource(ddlPath)); + } else { + ddlURL = Path.of(ddlPath).toUri().toURL(); + } + ddlContents = IOUtils.toString(ddlURL, Charset.defaultCharset()); + } catch (IOException e) { + throw new RuntimeException(e); } - /** - * HACK: HSQLDB will always uppercase table names. - * The original table names are extracted from the DDL. - * - * @return A map from the original table names to the uppercase HSQLDB table names. - */ - Map getOriginalTableNames() { - // Get the contents of the HSQLDB DDL for the current benchmark. - String ddlContents; - try { - String ddlPath = this.benchmarkModule.getWorkloadConfiguration().getDDLPath(); - URL ddlURL; - if (ddlPath == null) { - ddlPath = this.benchmarkModule.getDatabaseDDLPath(DatabaseType.HSQLDB); - ddlURL = Objects.requireNonNull(this.getClass().getResource(ddlPath)); - } else { - ddlURL = Path.of(ddlPath).toUri().toURL(); - } - ddlContents = IOUtils.toString(ddlURL, Charset.defaultCharset()); - } catch (IOException e) { - throw new RuntimeException(e); - } - - // Extract and map the original table names to their uppercase versions. - Map originalTableNames = new HashMap<>(); - Pattern p = Pattern.compile("CREATE[\\s]+TABLE[\\s]+(.*?)[\\s]+", Pattern.CASE_INSENSITIVE); - Matcher m = p.matcher(ddlContents); - while (m.find()) { - String tableName = m.group(1).trim(); - originalTableNames.put(tableName.toUpperCase(), tableName); - } - return originalTableNames; + // Extract and map the original table names to their uppercase versions. + Map originalTableNames = new HashMap<>(); + Pattern p = Pattern.compile("CREATE[\\s]+TABLE[\\s]+(.*?)[\\s]+", Pattern.CASE_INSENSITIVE); + Matcher m = p.matcher(ddlContents); + while (m.find()) { + String tableName = m.group(1).trim(); + originalTableNames.put(tableName.toUpperCase(), tableName); } + return originalTableNames; + } } diff --git a/src/main/java/com/oltpbenchmark/catalog/Index.java b/src/main/java/com/oltpbenchmark/catalog/Index.java index e5f2118d0..4005fdc6b 100644 --- a/src/main/java/com/oltpbenchmark/catalog/Index.java +++ b/src/main/java/com/oltpbenchmark/catalog/Index.java @@ -18,87 +18,86 @@ package com.oltpbenchmark.catalog; import com.oltpbenchmark.types.SortDirectionType; - import java.io.Serializable; import java.util.Objects; import java.util.SortedMap; import java.util.TreeMap; public class Index extends AbstractCatalogObject { - private static final long serialVersionUID = 1L; - - private final Table table; - private final TreeMap columns = new TreeMap<>(); - private final int type; - private final boolean unique; - - static class IndexColumn implements Serializable { - static final long serialVersionUID = 0; - - private final String name; - private final SortDirectionType dir; - - IndexColumn(String name, SortDirectionType dir) { - this.name = name; - this.dir = dir; - } - - public String getName() { - return name; - } + private static final long serialVersionUID = 1L; - public SortDirectionType getDir() { - return dir; - } - } + private final Table table; + private final TreeMap columns = new TreeMap<>(); + private final int type; + private final boolean unique; - public Index(String name, String separator, Table table, int type, boolean unique) { - super(name, separator); - this.table = table; - this.type = type; - this.unique = unique; - } + static class IndexColumn implements Serializable { + static final long serialVersionUID = 0; - public void addColumn(String colName, SortDirectionType colOrder, int colPosition) { - this.columns.put(colPosition, new IndexColumn(colName, colOrder)); - } + private final String name; + private final SortDirectionType dir; - public Table getTable() { - return table; + IndexColumn(String name, SortDirectionType dir) { + this.name = name; + this.dir = dir; } - public SortedMap getColumns() { - return columns; + public String getName() { + return name; } - public int getType() { - return type; + public SortDirectionType getDir() { + return dir; } - - public boolean isUnique() { - return unique; + } + + public Index(String name, String separator, Table table, int type, boolean unique) { + super(name, separator); + this.table = table; + this.type = type; + this.unique = unique; + } + + public void addColumn(String colName, SortDirectionType colOrder, int colPosition) { + this.columns.put(colPosition, new IndexColumn(colName, colOrder)); + } + + public Table getTable() { + return table; + } + + public SortedMap getColumns() { + return columns; + } + + public int getType() { + return type; + } + + public boolean isUnique() { + return unique; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - if (!super.equals(o)) { - return false; - } - Index index = (Index) o; - return type == index.type && - unique == index.unique && - Objects.equals(table, index.table) && - Objects.equals(columns, index.columns); + if (o == null || getClass() != o.getClass()) { + return false; } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), table.name, columns, type, unique); + if (!super.equals(o)) { + return false; } + Index index = (Index) o; + return type == index.type + && unique == index.unique + && Objects.equals(table, index.table) + && Objects.equals(columns, index.columns); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), table.name, columns, type, unique); + } } diff --git a/src/main/java/com/oltpbenchmark/catalog/Table.java b/src/main/java/com/oltpbenchmark/catalog/Table.java index 587ff3cd3..c21693f49 100644 --- a/src/main/java/com/oltpbenchmark/catalog/Table.java +++ b/src/main/java/com/oltpbenchmark/catalog/Table.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.catalog; import java.util.ArrayList; @@ -23,7 +22,6 @@ import java.util.List; import java.util.Objects; - /** * Table Catalog Object * @@ -32,94 +30,91 @@ * @author Djellel */ public class Table extends AbstractCatalogObject { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private final ArrayList columns = new ArrayList<>(); - private final ArrayList indexes = new ArrayList<>(); + private final ArrayList columns = new ArrayList<>(); + private final ArrayList indexes = new ArrayList<>(); - public Table(String name, String separator) { - super(name, separator); - } - - public void addColumn(Column col) { - this.columns.add(col); - } - - public int getColumnCount() { - return this.columns.size(); - } - - public List getColumns() { - return Collections.unmodifiableList(this.columns); - } + public Table(String name, String separator) { + super(name, separator); + } - public Column getColumn(int index) { - return this.columns.get(index); - } + public void addColumn(Column col) { + this.columns.add(col); + } - public int[] getColumnTypes() { - int[] types = new int[this.getColumnCount()]; - for (Column catalog_col : this.getColumns()) { - types[catalog_col.getIndex()] = catalog_col.getType(); - } - return (types); - } + public int getColumnCount() { + return this.columns.size(); + } - public Column getColumnByName(String colname) { - int idx = getColumnIndex(colname); - return (idx >= 0 ? this.columns.get(idx) : null); - } + public List getColumns() { + return Collections.unmodifiableList(this.columns); + } + public Column getColumn(int index) { + return this.columns.get(index); + } - public int getColumnIndex(Column catalog_col) { - return (this.getColumnIndex(catalog_col.getName())); + public int[] getColumnTypes() { + int[] types = new int[this.getColumnCount()]; + for (Column catalog_col : this.getColumns()) { + types[catalog_col.getIndex()] = catalog_col.getType(); } - - public int getColumnIndex(String columnName) { - for (int i = 0, cnt = getColumnCount(); i < cnt; i++) { - if (this.columns.get(i).getName().equalsIgnoreCase(columnName)) { - return (i); - } - } - return -1; + return (types); + } + + public Column getColumnByName(String colname) { + int idx = getColumnIndex(colname); + return (idx >= 0 ? this.columns.get(idx) : null); + } + + public int getColumnIndex(Column catalog_col) { + return (this.getColumnIndex(catalog_col.getName())); + } + + public int getColumnIndex(String columnName) { + for (int i = 0, cnt = getColumnCount(); i < cnt; i++) { + if (this.columns.get(i).getName().equalsIgnoreCase(columnName)) { + return (i); + } } - - - public void addIndex(Index index) { - this.indexes.add(index); + return -1; + } + + public void addIndex(Index index) { + this.indexes.add(index); + } + + public Index getIndex(String indexName) { + for (Index catalog_idx : this.indexes) { + if (catalog_idx.getName().equalsIgnoreCase(indexName)) { + return (catalog_idx); + } } + return (null); + } - public Index getIndex(String indexName) { - for (Index catalog_idx : this.indexes) { - if (catalog_idx.getName().equalsIgnoreCase(indexName)) { - return (catalog_idx); - } - } - return (null); - } + public List getIndexes() { + return this.indexes; + } - public List getIndexes() { - return this.indexes; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - if (!super.equals(o)) { - return false; - } - Table table = (Table) o; - return Objects.equals(columns, table.columns) && - Objects.equals(indexes, table.indexes); + if (o == null || getClass() != o.getClass()) { + return false; } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), columns, indexes); + if (!super.equals(o)) { + return false; } + Table table = (Table) o; + return Objects.equals(columns, table.columns) && Objects.equals(indexes, table.indexes); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), columns, indexes); + } } diff --git a/src/main/java/com/oltpbenchmark/distributions/CounterGenerator.java b/src/main/java/com/oltpbenchmark/distributions/CounterGenerator.java index bbcadf452..28165950e 100644 --- a/src/main/java/com/oltpbenchmark/distributions/CounterGenerator.java +++ b/src/main/java/com/oltpbenchmark/distributions/CounterGenerator.java @@ -17,45 +17,40 @@ package com.oltpbenchmark.distributions; - import java.util.concurrent.atomic.AtomicInteger; -/** - * Generates a sequence of integers 0, 1, ... - */ +/** Generates a sequence of integers 0, 1, ... */ public final class CounterGenerator extends IntegerGenerator { - final AtomicInteger counter; - - /** - * Create a counter that starts at countstart - */ - public CounterGenerator(int countstart) { - counter = new AtomicInteger(countstart); - setLastInt(counter.get() - 1); - } - - /** - * If the generator returns numeric (integer) values, return the next value as an int. Default is to return -1, which - * is appropriate for generators that do not return numeric values. - */ - public int nextInt() { - int ret = counter.getAndIncrement(); - setLastInt(ret); - return ret; - } - - @Override - public int lastInt() { - return counter.get() - 1; - } - - @Override - public double mean() { - throw new UnsupportedOperationException("Can't compute mean of non-stationary distribution!"); - } - - public void reset() { - // TODO Auto-generated method stub - counter.set(0); - } + final AtomicInteger counter; + + /** Create a counter that starts at countstart */ + public CounterGenerator(int countstart) { + counter = new AtomicInteger(countstart); + setLastInt(counter.get() - 1); + } + + /** + * If the generator returns numeric (integer) values, return the next value as an int. Default is + * to return -1, which is appropriate for generators that do not return numeric values. + */ + public int nextInt() { + int ret = counter.getAndIncrement(); + setLastInt(ret); + return ret; + } + + @Override + public int lastInt() { + return counter.get() - 1; + } + + @Override + public double mean() { + throw new UnsupportedOperationException("Can't compute mean of non-stationary distribution!"); + } + + public void reset() { + // TODO Auto-generated method stub + counter.set(0); + } } diff --git a/src/main/java/com/oltpbenchmark/distributions/CyclicCounterGenerator.java b/src/main/java/com/oltpbenchmark/distributions/CyclicCounterGenerator.java index 3b6ec4902..0d3da8ae3 100644 --- a/src/main/java/com/oltpbenchmark/distributions/CyclicCounterGenerator.java +++ b/src/main/java/com/oltpbenchmark/distributions/CyclicCounterGenerator.java @@ -18,46 +18,43 @@ import java.util.concurrent.atomic.AtomicInteger; -/** - * Thread-safe cyclic counter generator. - */ +/** Thread-safe cyclic counter generator. */ public class CyclicCounterGenerator extends IntegerGenerator { - private final int maxVal; - private final AtomicInteger counter; - - public CyclicCounterGenerator(int maxVal) { - this.maxVal = maxVal; - this.counter = new AtomicInteger(0); - } - - protected void setLastInt(int last) { - throw new UnsupportedOperationException("Cyclic counter cannot be set to a value"); - } - - @Override - public int nextInt() { - return counter.accumulateAndGet(1, (index, inc) -> (++index >= maxVal ? 0 : index)); - } - - @Override - public String nextString() { - return "" + nextInt(); - } - - @Override - public String lastString() { - return "" + lastInt(); - } - - @Override - public int lastInt() { - return counter.get(); - } - - @Override - public double mean() { - throw new UnsupportedOperationException("Not implemented yet"); - } - + private final int maxVal; + private final AtomicInteger counter; + + public CyclicCounterGenerator(int maxVal) { + this.maxVal = maxVal; + this.counter = new AtomicInteger(0); + } + + protected void setLastInt(int last) { + throw new UnsupportedOperationException("Cyclic counter cannot be set to a value"); + } + + @Override + public int nextInt() { + return counter.accumulateAndGet(1, (index, inc) -> (++index >= maxVal ? 0 : index)); + } + + @Override + public String nextString() { + return "" + nextInt(); + } + + @Override + public String lastString() { + return "" + lastInt(); + } + + @Override + public int lastInt() { + return counter.get(); + } + + @Override + public double mean() { + throw new UnsupportedOperationException("Not implemented yet"); + } } diff --git a/src/main/java/com/oltpbenchmark/distributions/Generator.java b/src/main/java/com/oltpbenchmark/distributions/Generator.java index a7e0cb817..b2d7e7c20 100644 --- a/src/main/java/com/oltpbenchmark/distributions/Generator.java +++ b/src/main/java/com/oltpbenchmark/distributions/Generator.java @@ -18,19 +18,18 @@ package com.oltpbenchmark.distributions; /** - * An expression that generates a sequence of string values, following some distribution (Uniform, Zipfian, Sequential, etc.) + * An expression that generates a sequence of string values, following some distribution (Uniform, + * Zipfian, Sequential, etc.) */ public abstract class Generator { - /** - * Generate the next string in the distribution. - */ - public abstract String nextString(); + /** Generate the next string in the distribution. */ + public abstract String nextString(); - /** - * Return the previous string generated by the distribution; e.g., returned from the last nextString() call. - * Calling lastString() should not advance the distribution or have any side effects. If nextString() has not yet - * been called, lastString() should return something reasonable. - */ - public abstract String lastString(); + /** + * Return the previous string generated by the distribution; e.g., returned from the last + * nextString() call. Calling lastString() should not advance the distribution or have any side + * effects. If nextString() has not yet been called, lastString() should return something + * reasonable. + */ + public abstract String lastString(); } - diff --git a/src/main/java/com/oltpbenchmark/distributions/IntegerGenerator.java b/src/main/java/com/oltpbenchmark/distributions/IntegerGenerator.java index da7cb63df..9116cbf16 100644 --- a/src/main/java/com/oltpbenchmark/distributions/IntegerGenerator.java +++ b/src/main/java/com/oltpbenchmark/distributions/IntegerGenerator.java @@ -23,48 +23,47 @@ * @author cooperb */ public abstract class IntegerGenerator extends Generator { - int lastint; + int lastint; - /** - * Set the last value generated. IntegerGenerator subclasses must use this call - * to properly set the last string value, or the lastString() and lastInt() calls won't work. - */ - protected void setLastInt(int last) { - lastint = last; - } + /** + * Set the last value generated. IntegerGenerator subclasses must use this call to properly set + * the last string value, or the lastString() and lastInt() calls won't work. + */ + protected void setLastInt(int last) { + lastint = last; + } - /** - * Return the next value as an int. When overriding this method, be sure to call setLastString() properly, or the lastString() call won't work. - */ - public abstract int nextInt(); + /** + * Return the next value as an int. When overriding this method, be sure to call setLastString() + * properly, or the lastString() call won't work. + */ + public abstract int nextInt(); - /** - * Generate the next string in the distribution. - */ - public String nextString() { - return "" + nextInt(); - } + /** Generate the next string in the distribution. */ + public String nextString() { + return "" + nextInt(); + } - /** - * Return the previous string generated by the distribution; e.g., returned from the last nextString() call. - * Calling lastString() should not advance the distribution or have any side effects. If nextString() has not yet - * been called, lastString() should return something reasonable. - */ - @Override - public String lastString() { - return "" + lastInt(); - } + /** + * Return the previous string generated by the distribution; e.g., returned from the last + * nextString() call. Calling lastString() should not advance the distribution or have any side + * effects. If nextString() has not yet been called, lastString() should return something + * reasonable. + */ + @Override + public String lastString() { + return "" + lastInt(); + } - /** - * Return the previous int generated by the distribution. This call is unique to IntegerGenerator subclasses, and assumes - * IntegerGenerator subclasses always return ints for nextInt() (e.g. not arbitrary strings). - */ - public int lastInt() { - return lastint; - } + /** + * Return the previous int generated by the distribution. This call is unique to IntegerGenerator + * subclasses, and assumes IntegerGenerator subclasses always return ints for nextInt() (e.g. not + * arbitrary strings). + */ + public int lastInt() { + return lastint; + } - /** - * Return the expected value (mean) of the values this generator will return. - */ - public abstract double mean(); + /** Return the expected value (mean) of the values this generator will return. */ + public abstract double mean(); } diff --git a/src/main/java/com/oltpbenchmark/distributions/ScrambledZipfianGenerator.java b/src/main/java/com/oltpbenchmark/distributions/ScrambledZipfianGenerator.java index 94b122041..eb4832626 100644 --- a/src/main/java/com/oltpbenchmark/distributions/ScrambledZipfianGenerator.java +++ b/src/main/java/com/oltpbenchmark/distributions/ScrambledZipfianGenerator.java @@ -18,86 +18,85 @@ package com.oltpbenchmark.distributions; /** - * A generator of a zipfian distribution. It produces a sequence of items, such that some items are more popular than others, according - * to a zipfian distribution. When you construct an instance of this class, you specify the number of items in the set to draw from, either - * by specifying an itemcount (so that the sequence is of items from 0 to itemcount-1) or by specifying a min and a max (so that the sequence is of - * items from min to max inclusive). After you construct the instance, you can change the number of items by calling nextInt(itemcount) or nextLong(itemcount). - *

- * Unlike @ZipfianGenerator, this class scatters the "popular" items across the itemspace. Use this, instead of @ZipfianGenerator, if you - * don't want the head of the distribution (the popular items) clustered together. + * A generator of a zipfian distribution. It produces a sequence of items, such that some items are + * more popular than others, according to a zipfian distribution. When you construct an instance of + * this class, you specify the number of items in the set to draw from, either by specifying an + * itemcount (so that the sequence is of items from 0 to itemcount-1) or by specifying a min and a + * max (so that the sequence is of items from min to max inclusive). After you construct the + * instance, you can change the number of items by calling nextInt(itemcount) or + * nextLong(itemcount). + * + *

Unlike @ZipfianGenerator, this class scatters the "popular" items across the itemspace. Use + * this, instead of @ZipfianGenerator, if you don't want the head of the distribution (the popular + * items) clustered together. */ public class ScrambledZipfianGenerator extends IntegerGenerator { - public static final double ZETAN = 26.46902820178302; - public static final double USED_ZIPFIAN_CONSTANT = 0.99; - public static final long ITEM_COUNT = 10000000000L; + public static final double ZETAN = 26.46902820178302; + public static final double USED_ZIPFIAN_CONSTANT = 0.99; + public static final long ITEM_COUNT = 10000000000L; - ZipfianGenerator gen; - long _min, _max, _itemcount; + ZipfianGenerator gen; + long _min, _max, _itemcount; + /** + * Create a zipfian generator for the specified number of items. + * + * @param _items The number of items in the distribution. + */ + public ScrambledZipfianGenerator(long _items) { + this(0, _items - 1); + } - /** - * Create a zipfian generator for the specified number of items. - * - * @param _items The number of items in the distribution. - */ - public ScrambledZipfianGenerator(long _items) { - this(0, _items - 1); - } + /** + * Create a zipfian generator for items between min and max. + * + * @param _min The smallest integer to generate in the sequence. + * @param _max The largest integer to generate in the sequence. + */ + public ScrambledZipfianGenerator(long _min, long _max) { + this(_min, _max, ZipfianGenerator.ZIPFIAN_CONSTANT); + } - /** - * Create a zipfian generator for items between min and max. - * - * @param _min The smallest integer to generate in the sequence. - * @param _max The largest integer to generate in the sequence. - */ - public ScrambledZipfianGenerator(long _min, long _max) { - this(_min, _max, ZipfianGenerator.ZIPFIAN_CONSTANT); + /** + * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian + * constant. If you use a zipfian constant other than 0.99, this will take a long time to complete + * because we need to recompute zeta. + * + * @param min The smallest integer to generate in the sequence. + * @param max The largest integer to generate in the sequence. + * @param _zipfianconstant The zipfian constant to use. + */ + public ScrambledZipfianGenerator(long min, long max, double _zipfianconstant) { + _min = min; + _max = max; + _itemcount = _max - _min + 1; + if (_zipfianconstant == USED_ZIPFIAN_CONSTANT) { + gen = new ZipfianGenerator(Utils.random(), 0, ITEM_COUNT, _zipfianconstant, ZETAN); + } else { + gen = new ZipfianGenerator(Utils.random(), 0, ITEM_COUNT, _zipfianconstant); } + } + /** Return the next int in the sequence. */ + @Override + public int nextInt() { + return (int) nextLong(); + } - /** - * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian constant. If you - * use a zipfian constant other than 0.99, this will take a long time to complete because we need to recompute zeta. - * - * @param min The smallest integer to generate in the sequence. - * @param max The largest integer to generate in the sequence. - * @param _zipfianconstant The zipfian constant to use. - */ - public ScrambledZipfianGenerator(long min, long max, double _zipfianconstant) { - _min = min; - _max = max; - _itemcount = _max - _min + 1; - if (_zipfianconstant == USED_ZIPFIAN_CONSTANT) { - gen = new ZipfianGenerator(Utils.random(), 0, ITEM_COUNT, _zipfianconstant, ZETAN); - } else { - gen = new ZipfianGenerator(Utils.random(),0, ITEM_COUNT, _zipfianconstant); - } - } + /** Return the next long in the sequence. */ + public long nextLong() { + long ret = gen.nextLong(); + ret = _min + Utils.FNVhash64(ret) % _itemcount; + setLastInt((int) ret); + return ret; + } - - /** - * Return the next int in the sequence. - */ - @Override - public int nextInt() { - return (int) nextLong(); - } - - /** - * Return the next long in the sequence. - */ - public long nextLong() { - long ret = gen.nextLong(); - ret = _min + Utils.FNVhash64(ret) % _itemcount; - setLastInt((int) ret); - return ret; - } - - /** - * since the values are scrambled (hopefully uniformly), the mean is simply the middle of the range. - */ - @Override - public double mean() { - return ((double) (_min + _max)) / 2.0; - } + /** + * since the values are scrambled (hopefully uniformly), the mean is simply the middle of the + * range. + */ + @Override + public double mean() { + return ((double) (_min + _max)) / 2.0; + } } diff --git a/src/main/java/com/oltpbenchmark/distributions/Utils.java b/src/main/java/com/oltpbenchmark/distributions/Utils.java index d7ae85fe5..e27abc245 100644 --- a/src/main/java/com/oltpbenchmark/distributions/Utils.java +++ b/src/main/java/com/oltpbenchmark/distributions/Utils.java @@ -19,43 +19,41 @@ import java.util.Random; -/** - * Utility functions. - */ +/** Utility functions. */ public class Utils { - private static final Random rand = new Random(); - private static final ThreadLocal rng = new ThreadLocal<>(); - - public static Random random() { - Random ret = rng.get(); - if (ret == null) { - ret = new Random(rand.nextLong()); - rng.set(ret); - } - return ret; + private static final Random rand = new Random(); + private static final ThreadLocal rng = new ThreadLocal<>(); + + public static Random random() { + Random ret = rng.get(); + if (ret == null) { + ret = new Random(rand.nextLong()); + rng.set(ret); } - - public static final long FNV_offset_basis_64 = 0xCBF29CE484222325L; - public static final long FNV_prime_64 = 1099511628211L; - - /** - * 64 bit FNV hash. Produces more "random" hashes than (say) String.hashCode(). - * - * @param val The value to hash. - * @return The hash value - */ - public static long FNVhash64(long val) { - //from http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash - long hashval = FNV_offset_basis_64; - - for (int i = 0; i < 8; i++) { - long octet = val & 0x00ff; - val = val >> 8; - - hashval = hashval ^ octet; - hashval = hashval * FNV_prime_64; - //hashval = hashval ^ octet; - } - return Math.abs(hashval); + return ret; + } + + public static final long FNV_offset_basis_64 = 0xCBF29CE484222325L; + public static final long FNV_prime_64 = 1099511628211L; + + /** + * 64 bit FNV hash. Produces more "random" hashes than (say) String.hashCode(). + * + * @param val The value to hash. + * @return The hash value + */ + public static long FNVhash64(long val) { + // from http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash + long hashval = FNV_offset_basis_64; + + for (int i = 0; i < 8; i++) { + long octet = val & 0x00ff; + val = val >> 8; + + hashval = hashval ^ octet; + hashval = hashval * FNV_prime_64; + // hashval = hashval ^ octet; } + return Math.abs(hashval); + } } diff --git a/src/main/java/com/oltpbenchmark/distributions/ZipfianGenerator.java b/src/main/java/com/oltpbenchmark/distributions/ZipfianGenerator.java index 11961f8ec..cc843d7be 100644 --- a/src/main/java/com/oltpbenchmark/distributions/ZipfianGenerator.java +++ b/src/main/java/com/oltpbenchmark/distributions/ZipfianGenerator.java @@ -17,289 +17,301 @@ package com.oltpbenchmark.distributions; +import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Random; - /** - * A generator of a zipfian distribution. It produces a sequence of items, such that some items are more popular than others, according - * to a zipfian distribution. When you construct an instance of this class, you specify the number of items in the set to draw from, either - * by specifying an itemcount (so that the sequence is of items from 0 to itemcount-1) or by specifying a min and a max (so that the sequence is of - * items from min to max inclusive). After you construct the instance, you can change the number of items by calling nextInt(itemcount) or nextLong(itemcount). - *

- * Note that the popular items will be clustered together, e.g. item 0 is the most popular, item 1 the second most popular, and so on (or min is the most - * popular, min+1 the next most popular, etc.) If you don't want this clustering, and instead want the popular items scattered throughout the - * item space, then use ScrambledZipfianGenerator instead. - *

- * Be aware: initializing this generator may take a long time if there are lots of items to choose from (e.g. over a minute - * for 100 million objects). This is because certain mathematical values need to be computed to properly generate a zipfian skew, and one of those - * values (zeta) is a sum sequence from 1 to n, where n is the itemcount. Note that if you increase the number of items in the set, we can compute - * a new zeta incrementally, so it should be fast unless you have added millions of items. However, if you decrease the number of items, we recompute - * zeta from scratch, so this can take a long time. - *

- * The algorithm used here is from "Quickly Generating Billion-Record Synthetic Databases", Jim Gray et al, SIGMOD 1994. + * A generator of a zipfian distribution. It produces a sequence of items, such that some items are + * more popular than others, according to a zipfian distribution. When you construct an instance of + * this class, you specify the number of items in the set to draw from, either by specifying an + * itemcount (so that the sequence is of items from 0 to itemcount-1) or by specifying a min and a + * max (so that the sequence is of items from min to max inclusive). After you construct the + * instance, you can change the number of items by calling nextInt(itemcount) or + * nextLong(itemcount). + * + *

Note that the popular items will be clustered together, e.g. item 0 is the most popular, item + * 1 the second most popular, and so on (or min is the most popular, min+1 the next most popular, + * etc.) If you don't want this clustering, and instead want the popular items scattered throughout + * the item space, then use ScrambledZipfianGenerator instead. + * + *

Be aware: initializing this generator may take a long time if there are lots of items to + * choose from (e.g. over a minute for 100 million objects). This is because certain mathematical + * values need to be computed to properly generate a zipfian skew, and one of those values (zeta) is + * a sum sequence from 1 to n, where n is the itemcount. Note that if you increase the number of + * items in the set, we can compute a new zeta incrementally, so it should be fast unless you have + * added millions of items. However, if you decrease the number of items, we recompute zeta from + * scratch, so this can take a long time. + * + *

The algorithm used here is from "Quickly Generating Billion-Record Synthetic Databases", Jim + * Gray et al, SIGMOD 1994. */ public final class ZipfianGenerator extends IntegerGenerator { - public static final double ZIPFIAN_CONSTANT = 0.99; - - private static final Logger LOG = LoggerFactory.getLogger(ZipfianGenerator.class); - - final Random rng; - - /** - * Number of items. - */ - long items; - - /** - * Min item to generate. - */ - long base; - - /** - * The zipfian constant to use. - */ - double zipfianconstant; - - /** - * Computed parameters for generating the distribution. - */ - double alpha, zetan, eta, theta, zeta2theta; - - /** - * The number of items used to compute zetan the last time. - */ - long countforzeta; - - /** - * Flag to prevent problems. If you increase the number of items the zipfian generator is allowed to choose from, this code will incrementally compute a new zeta - * value for the larger itemcount. However, if you decrease the number of items, the code computes zeta from scratch; this is expensive for large itemsets. - * Usually this is not intentional; e.g. one thread thinks the number of items is 1001 and calls "nextLong()" with that item count; then another thread who thinks the - * number of items is 1000 calls nextLong() with itemcount=1000 triggering the expensive recomputation. (It is expensive for 100 million items, not really for 1000 items.) Why - * did the second thread think there were only 1000 items? maybe it read the item count before the first thread incremented it. So this flag allows you to say if you really do - * want that recomputation. If true, then the code will recompute zeta if the itemcount goes down. If false, the code will assume itemcount only goes up, and never recompute. - */ - boolean allowitemcountdecrease = false; - - /** - * Create a zipfian generator for the specified number of items. - * @param rng - * @param _items - */ - public ZipfianGenerator(Random rng, long _items) { - this(rng,0, _items - 1, ZIPFIAN_CONSTANT); - } - - /** - * Create a zipfian generator for items between min and max. - * - * @param _min The smallest integer to generate in the sequence. - * @param _max The largest integer to generate in the sequence. - */ - public ZipfianGenerator(Random rng, long _min, long _max) { - this(rng, _min, _max, ZIPFIAN_CONSTANT); - } - - /** - * Create a zipfian generator for the specified number of items using the specified zipfian constant. - * - * @param _items The number of items in the distribution. - * @param _zipfianconstant The zipfian constant to use. - */ - public ZipfianGenerator(Random rng, long _items, double _zipfianconstant) { - this(rng, 0, _items - 1, _zipfianconstant); - } - - /** - * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian constant. - * - * @param min The smallest integer to generate in the sequence. - * @param max The largest integer to generate in the sequence. - * @param _zipfianconstant The zipfian constant to use. - */ - public ZipfianGenerator(Random rng, long min, long max, double _zipfianconstant) { - this(rng, min, max, _zipfianconstant, zetastatic(max - min + 1, _zipfianconstant)); - } - - /** - * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian constant, using the precomputed value of zeta. - * - * @param min The smallest integer to generate in the sequence. - * @param max The largest integer to generate in the sequence. - * @param _zipfianconstant The zipfian constant to use. - * @param _zetan The precomputed zeta constant. - */ - public ZipfianGenerator(Random rng, long min, long max, double _zipfianconstant, double _zetan) { - this.rng = rng; - items = max - min + 1; - base = min; - zipfianconstant = _zipfianconstant; - - theta = zipfianconstant; - - zeta2theta = zeta(2, theta); - - - alpha = 1.0 / (1.0 - theta); - //zetan=zeta(items,theta); - zetan = _zetan; - countforzeta = items; - eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); - - //System.out.println("XXXX 3 XXXX"); - nextInt(); - //System.out.println("XXXX 4 XXXX"); + public static final double ZIPFIAN_CONSTANT = 0.99; + + private static final Logger LOG = LoggerFactory.getLogger(ZipfianGenerator.class); + + final Random rng; + + /** Number of items. */ + long items; + + /** Min item to generate. */ + long base; + + /** The zipfian constant to use. */ + double zipfianconstant; + + /** Computed parameters for generating the distribution. */ + double alpha, zetan, eta, theta, zeta2theta; + + /** The number of items used to compute zetan the last time. */ + long countforzeta; + + /** + * Flag to prevent problems. If you increase the number of items the zipfian generator is allowed + * to choose from, this code will incrementally compute a new zeta value for the larger itemcount. + * However, if you decrease the number of items, the code computes zeta from scratch; this is + * expensive for large itemsets. Usually this is not intentional; e.g. one thread thinks the + * number of items is 1001 and calls "nextLong()" with that item count; then another thread who + * thinks the number of items is 1000 calls nextLong() with itemcount=1000 triggering the + * expensive recomputation. (It is expensive for 100 million items, not really for 1000 items.) + * Why did the second thread think there were only 1000 items? maybe it read the item count before + * the first thread incremented it. So this flag allows you to say if you really do want that + * recomputation. If true, then the code will recompute zeta if the itemcount goes down. If false, + * the code will assume itemcount only goes up, and never recompute. + */ + boolean allowitemcountdecrease = false; + + /** + * Create a zipfian generator for the specified number of items. + * + * @param rng + * @param _items + */ + public ZipfianGenerator(Random rng, long _items) { + this(rng, 0, _items - 1, ZIPFIAN_CONSTANT); + } + + /** + * Create a zipfian generator for items between min and max. + * + * @param _min The smallest integer to generate in the sequence. + * @param _max The largest integer to generate in the sequence. + */ + public ZipfianGenerator(Random rng, long _min, long _max) { + this(rng, _min, _max, ZIPFIAN_CONSTANT); + } + + /** + * Create a zipfian generator for the specified number of items using the specified zipfian + * constant. + * + * @param _items The number of items in the distribution. + * @param _zipfianconstant The zipfian constant to use. + */ + public ZipfianGenerator(Random rng, long _items, double _zipfianconstant) { + this(rng, 0, _items - 1, _zipfianconstant); + } + + /** + * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian + * constant. + * + * @param min The smallest integer to generate in the sequence. + * @param max The largest integer to generate in the sequence. + * @param _zipfianconstant The zipfian constant to use. + */ + public ZipfianGenerator(Random rng, long min, long max, double _zipfianconstant) { + this(rng, min, max, _zipfianconstant, zetastatic(max - min + 1, _zipfianconstant)); + } + + /** + * Create a zipfian generator for items between min and max (inclusive) for the specified zipfian + * constant, using the precomputed value of zeta. + * + * @param min The smallest integer to generate in the sequence. + * @param max The largest integer to generate in the sequence. + * @param _zipfianconstant The zipfian constant to use. + * @param _zetan The precomputed zeta constant. + */ + public ZipfianGenerator(Random rng, long min, long max, double _zipfianconstant, double _zetan) { + this.rng = rng; + items = max - min + 1; + base = min; + zipfianconstant = _zipfianconstant; + + theta = zipfianconstant; + + zeta2theta = zeta(2, theta); + + alpha = 1.0 / (1.0 - theta); + // zetan=zeta(items,theta); + zetan = _zetan; + countforzeta = items; + eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); + + // System.out.println("XXXX 3 XXXX"); + nextInt(); + // System.out.println("XXXX 4 XXXX"); + } + + /** + * Compute the zeta constant needed for the distribution. Do this from scratch for a distribution + * with n items, using the zipfian constant theta. Remember the value of n, so if we change the + * itemcount, we can recompute zeta. + * + * @param n The number of items to compute zeta over. + * @param theta The zipfian constant. + */ + double zeta(long n, double theta) { + countforzeta = n; + return zetastatic(n, theta); + } + + /** + * Compute the zeta constant needed for the distribution. Do this from scratch for a distribution + * with n items, using the zipfian constant theta. This is a static version of the function which + * will not remember n. + * + * @param n The number of items to compute zeta over. + * @param theta The zipfian constant. + */ + static double zetastatic(long n, double theta) { + return zetastatic(0, n, theta, 0); + } + + /** + * Compute the zeta constant needed for the distribution. Do this incrementally for a distribution + * that has n items now but used to have st items. Use the zipfian constant theta. Remember the + * new value of n so that if we change the itemcount, we'll know to recompute zeta. + * + * @param st The number of items used to compute the last initialsum + * @param n The number of items to compute zeta over. + * @param theta The zipfian constant. + * @param initialsum The value of zeta we are computing incrementally from. + */ + double zeta(long st, long n, double theta, double initialsum) { + countforzeta = n; + return zetastatic(st, n, theta, initialsum); + } + + /** + * Compute the zeta constant needed for the distribution. Do this incrementally for a distribution + * that has n items now but used to have st items. Use the zipfian constant theta. Remember the + * new value of n so that if we change the itemcount, we'll know to recompute zeta. + * + * @param st The number of items used to compute the last initialsum + * @param n The number of items to compute zeta over. + * @param theta The zipfian constant. + * @param initialsum The value of zeta we are computing incrementally from. + */ + static double zetastatic(long st, long n, double theta, double initialsum) { + double sum = initialsum; + for (long i = st; i < n; i++) { + + sum += 1 / (Math.pow(i + 1, theta)); } - - /** - * Compute the zeta constant needed for the distribution. Do this from scratch for a distribution with n items, using the - * zipfian constant theta. Remember the value of n, so if we change the itemcount, we can recompute zeta. - * - * @param n The number of items to compute zeta over. - * @param theta The zipfian constant. - */ - double zeta(long n, double theta) { - countforzeta = n; - return zetastatic(n, theta); - } - - /** - * Compute the zeta constant needed for the distribution. Do this from scratch for a distribution with n items, using the - * zipfian constant theta. This is a static version of the function which will not remember n. - * - * @param n The number of items to compute zeta over. - * @param theta The zipfian constant. - */ - static double zetastatic(long n, double theta) { - return zetastatic(0, n, theta, 0); - } - - /** - * Compute the zeta constant needed for the distribution. Do this incrementally for a distribution that - * has n items now but used to have st items. Use the zipfian constant theta. Remember the new value of - * n so that if we change the itemcount, we'll know to recompute zeta. - * - * @param st The number of items used to compute the last initialsum - * @param n The number of items to compute zeta over. - * @param theta The zipfian constant. - * @param initialsum The value of zeta we are computing incrementally from. - */ - double zeta(long st, long n, double theta, double initialsum) { - countforzeta = n; - return zetastatic(st, n, theta, initialsum); - } - - /** - * Compute the zeta constant needed for the distribution. Do this incrementally for a distribution that - * has n items now but used to have st items. Use the zipfian constant theta. Remember the new value of - * n so that if we change the itemcount, we'll know to recompute zeta. - * - * @param st The number of items used to compute the last initialsum - * @param n The number of items to compute zeta over. - * @param theta The zipfian constant. - * @param initialsum The value of zeta we are computing incrementally from. - */ - static double zetastatic(long st, long n, double theta, double initialsum) { - double sum = initialsum; - for (long i = st; i < n; i++) { - - sum += 1 / (Math.pow(i + 1, theta)); + // System.out.println("countforzeta="+countforzeta); + + return sum; + } + + /** + * Generate the next item. this distribution will be skewed toward lower integers; e.g. 0 will be + * the most popular, 1 the next most popular, etc. + * + * @param itemcount The number of items in the distribution. + * @return The next item in the sequence. + */ + public int nextInt(int itemcount) { + return (int) nextLong(itemcount); + } + + /** + * Generate the next item as a long. + * + * @param itemcount The number of items in the distribution. + * @return The next item in the sequence. + */ + public long nextLong(long itemcount) { + // from "Quickly Generating Billion-Record Synthetic Databases", Jim Gray et al, SIGMOD 1994 + + if (itemcount != countforzeta) { + + // have to recompute zetan and eta, since they depend on itemcount + synchronized (this) { + if (itemcount > countforzeta) { + // System.err.println("WARNING: Incrementally recomputing Zipfian distribtion. + // (itemcount="+itemcount+" countforzeta="+countforzeta+")"); + + // we have added more items. can compute zetan incrementally, which is cheaper + zetan = zeta(countforzeta, itemcount, theta, zetan); + eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); + } else if ((itemcount < countforzeta) && (allowitemcountdecrease)) { + // have to start over with zetan + // note : for large itemsets, this is very slow. so don't do it! + + // TODO: can also have a negative incremental computation, e.g. if you decrease the number + // of items, then just subtract + // the zeta sequence terms for the items that went away. This would be faster than + // recomputing from scratch when the number of items + // decreases + + LOG.warn( + "WARNING: Recomputing Zipfian distribtion. This is slow and should be avoided. (itemcount={} countforzeta={})", + itemcount, + countforzeta); + + zetan = zeta(itemcount, theta); + eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); } - - //System.out.println("countforzeta="+countforzeta); - - return sum; + } } + double u = this.rng.nextDouble(); + double uz = u * zetan; - /** - * Generate the next item. this distribution will be skewed toward lower integers; e.g. 0 will - * be the most popular, 1 the next most popular, etc. - * - * @param itemcount The number of items in the distribution. - * @return The next item in the sequence. - */ - public int nextInt(int itemcount) { - return (int) nextLong(itemcount); + if (uz < 1.0) { + return base; } - /** - * Generate the next item as a long. - * - * @param itemcount The number of items in the distribution. - * @return The next item in the sequence. - */ - public long nextLong(long itemcount) { - //from "Quickly Generating Billion-Record Synthetic Databases", Jim Gray et al, SIGMOD 1994 - - if (itemcount != countforzeta) { - - //have to recompute zetan and eta, since they depend on itemcount - synchronized (this) { - if (itemcount > countforzeta) { - //System.err.println("WARNING: Incrementally recomputing Zipfian distribtion. (itemcount="+itemcount+" countforzeta="+countforzeta+")"); - - //we have added more items. can compute zetan incrementally, which is cheaper - zetan = zeta(countforzeta, itemcount, theta, zetan); - eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); - } else if ((itemcount < countforzeta) && (allowitemcountdecrease)) { - //have to start over with zetan - //note : for large itemsets, this is very slow. so don't do it! - - //TODO: can also have a negative incremental computation, e.g. if you decrease the number of items, then just subtract - //the zeta sequence terms for the items that went away. This would be faster than recomputing from scratch when the number of items - //decreases - - LOG.warn("WARNING: Recomputing Zipfian distribtion. This is slow and should be avoided. (itemcount={} countforzeta={})", itemcount, countforzeta); - - zetan = zeta(itemcount, theta); - eta = (1 - Math.pow(2.0 / items, 1 - theta)) / (1 - zeta2theta / zetan); - } - } - } - - double u = this.rng.nextDouble(); - double uz = u * zetan; - - if (uz < 1.0) { - return base; - } - - if (uz < 1.0 + Math.pow(0.5, theta)) { - return base + 1; - } - - long ret = base + (long) ((itemcount) * Math.pow(eta * u - eta + 1, alpha)); - setLastInt((int) ret); - return ret; - } - - /** - * Return the next value, skewed by the Zipfian distribution. The 0th item will be the most popular, followed by the 1st, followed - * by the 2nd, etc. (Or, if min != 0, the min-th item is the most popular, the min+1th item the next most popular, etc.) If you want the - * popular items scattered throughout the item space, use ScrambledZipfianGenerator instead. - */ - @Override - public int nextInt() { - return (int) nextLong(items); - } - - /** - * Return the next value, skewed by the Zipfian distribution. The 0th item will be the most popular, followed by the 1st, followed - * by the 2nd, etc. (Or, if min != 0, the min-th item is the most popular, the min+1th item the next most popular, etc.) If you want the - * popular items scattered throughout the item space, use ScrambledZipfianGenerator instead. - */ - public long nextLong() { - return nextLong(items); + if (uz < 1.0 + Math.pow(0.5, theta)) { + return base + 1; } - /** - * @todo Implement ZipfianGenerator.mean() - */ - @Override - public double mean() { - throw new UnsupportedOperationException("@todo implement ZipfianGenerator.mean()"); - } + long ret = base + (long) ((itemcount) * Math.pow(eta * u - eta + 1, alpha)); + setLastInt((int) ret); + return ret; + } + + /** + * Return the next value, skewed by the Zipfian distribution. The 0th item will be the most + * popular, followed by the 1st, followed by the 2nd, etc. (Or, if min != 0, the min-th item is + * the most popular, the min+1th item the next most popular, etc.) If you want the popular items + * scattered throughout the item space, use ScrambledZipfianGenerator instead. + */ + @Override + public int nextInt() { + return (int) nextLong(items); + } + + /** + * Return the next value, skewed by the Zipfian distribution. The 0th item will be the most + * popular, followed by the 1st, followed by the 2nd, etc. (Or, if min != 0, the min-th item is + * the most popular, the min+1th item the next most popular, etc.) If you want the popular items + * scattered throughout the item space, use ScrambledZipfianGenerator instead. + */ + public long nextLong() { + return nextLong(items); + } + + /** + * @todo Implement ZipfianGenerator.mean() + */ + @Override + public double mean() { + throw new UnsupportedOperationException("@todo implement ZipfianGenerator.mean()"); + } } diff --git a/src/main/java/com/oltpbenchmark/jdbc/AutoIncrementPreparedStatement.java b/src/main/java/com/oltpbenchmark/jdbc/AutoIncrementPreparedStatement.java index 8505b176e..45bb2248e 100644 --- a/src/main/java/com/oltpbenchmark/jdbc/AutoIncrementPreparedStatement.java +++ b/src/main/java/com/oltpbenchmark/jdbc/AutoIncrementPreparedStatement.java @@ -18,7 +18,6 @@ package com.oltpbenchmark.jdbc; import com.oltpbenchmark.types.DatabaseType; - import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; @@ -28,525 +27,519 @@ public class AutoIncrementPreparedStatement implements PreparedStatement { - private final DatabaseType dbType; - private final PreparedStatement stmt; - - public AutoIncrementPreparedStatement(DatabaseType dbType, PreparedStatement stmt) { - this.dbType = dbType; - this.stmt = stmt; - } - - /** - * Special override for Postgres - */ - @Override - public ResultSet getGeneratedKeys() throws SQLException { - if (this.dbType == DatabaseType.POSTGRES - || this.dbType == DatabaseType.COCKROACHDB - || this.dbType == DatabaseType.SQLSERVER - || this.dbType == DatabaseType.SQLAZURE - ) { - return this.stmt.getResultSet(); - } else { - return this.stmt.getGeneratedKeys(); - } - } - - @Override - public ResultSet executeQuery(String sql) throws SQLException { - return this.stmt.executeQuery(sql); - } - - @Override - public int executeUpdate(String sql) throws SQLException { - return this.stmt.executeUpdate(sql); - } - - @Override - public void close() throws SQLException { - this.stmt.close(); - - } - - @Override - public int getMaxFieldSize() throws SQLException { - return this.stmt.getMaxFieldSize(); - } - - @Override - public void setMaxFieldSize(int max) throws SQLException { - this.stmt.setMaxFieldSize(max); - - } - - @Override - public int getMaxRows() throws SQLException { - return this.stmt.getMaxRows(); - } - - @Override - public void setMaxRows(int max) throws SQLException { - this.stmt.setMaxRows(max); - - } - - @Override - public void setEscapeProcessing(boolean enable) throws SQLException { - this.stmt.setEscapeProcessing(enable); - - } - - @Override - public int getQueryTimeout() throws SQLException { - return this.stmt.getQueryTimeout(); - } - - @Override - public void setQueryTimeout(int seconds) throws SQLException { - this.stmt.setQueryTimeout(seconds); - } - - @Override - public void cancel() throws SQLException { - this.stmt.cancel(); - } - - @Override - public SQLWarning getWarnings() throws SQLException { - return this.stmt.getWarnings(); - } - - @Override - public void clearWarnings() throws SQLException { - this.stmt.clearWarnings(); - - } - - @Override - public void setCursorName(String name) throws SQLException { - this.stmt.setCursorName(name); - } - - @Override - public boolean execute(String sql) throws SQLException { - return this.stmt.execute(sql); - } - - @Override - public ResultSet getResultSet() throws SQLException { - return this.stmt.getResultSet(); - } - - @Override - public int getUpdateCount() throws SQLException { - return this.stmt.getUpdateCount(); - } - - @Override - public boolean getMoreResults() throws SQLException { - return this.stmt.getMoreResults(); - } - - @Override - public void setFetchDirection(int direction) throws SQLException { - this.stmt.setFetchDirection(direction); - } - - @Override - public int getFetchDirection() throws SQLException { - return this.stmt.getFetchDirection(); - } - - @Override - public void setFetchSize(int rows) throws SQLException { - this.stmt.setFetchSize(rows); - } - - @Override - public int getFetchSize() throws SQLException { - return this.stmt.getFetchSize(); - } - - @Override - public int getResultSetConcurrency() throws SQLException { - return this.stmt.getResultSetConcurrency(); - } - - @Override - public int getResultSetType() throws SQLException { - return this.stmt.getResultSetType(); - } - - @Override - public void addBatch(String sql) throws SQLException { - this.stmt.addBatch(sql); - } - - @Override - public void clearBatch() throws SQLException { - this.stmt.clearBatch(); - } - - @Override - public int[] executeBatch() throws SQLException { - return this.stmt.executeBatch(); - } - - @Override - public Connection getConnection() throws SQLException { - return this.stmt.getConnection(); - } - - @Override - public boolean getMoreResults(int current) throws SQLException { - return this.stmt.getMoreResults(current); - } - - @Override - public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { - return this.stmt.executeUpdate(sql, autoGeneratedKeys); - } - - @Override - public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { - return this.stmt.executeUpdate(sql, columnIndexes); - } - - @Override - public int executeUpdate(String sql, String[] columnNames) throws SQLException { - return this.stmt.executeUpdate(sql, columnNames); - } - - @Override - public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { - return this.stmt.execute(sql, autoGeneratedKeys); - } - - @Override - public boolean execute(String sql, int[] columnIndexes) throws SQLException { - return this.stmt.execute(sql, columnIndexes); - } - - @Override - public boolean execute(String sql, String[] columnNames) throws SQLException { - return this.stmt.execute(sql, columnNames); - } - - @Override - public int getResultSetHoldability() throws SQLException { - return this.stmt.getResultSetHoldability(); - } - - @Override - public boolean isClosed() throws SQLException { - return this.stmt.isClosed(); - } - - @Override - public void setPoolable(boolean poolable) throws SQLException { - this.stmt.setPoolable(poolable); - } - - @Override - public boolean isPoolable() throws SQLException { - return this.stmt.isPoolable(); - } - - @Override - public T unwrap(Class iface) throws SQLException { - return this.stmt.unwrap(iface); - } - - @Override - public boolean isWrapperFor(Class iface) throws SQLException { - return this.stmt.isWrapperFor(iface); - } - - @Override - public ResultSet executeQuery() throws SQLException { - return this.stmt.executeQuery(); - } - - @Override - public int executeUpdate() throws SQLException { - return this.stmt.executeUpdate(); - } - - @Override - public void setNull(int parameterIndex, int sqlType) throws SQLException { - this.stmt.setNull(parameterIndex, sqlType); - } - - @Override - public void setBoolean(int parameterIndex, boolean x) throws SQLException { - this.stmt.setBoolean(parameterIndex, x); - } - - @Override - public void setByte(int parameterIndex, byte x) throws SQLException { - this.stmt.setByte(parameterIndex, x); - } - - @Override - public void setShort(int parameterIndex, short x) throws SQLException { - this.stmt.setShort(parameterIndex, x); - } - - @Override - public void setInt(int parameterIndex, int x) throws SQLException { - this.stmt.setInt(parameterIndex, x); - } - - @Override - public void setLong(int parameterIndex, long x) throws SQLException { - this.stmt.setLong(parameterIndex, x); - } - - @Override - public void setFloat(int parameterIndex, float x) throws SQLException { - this.stmt.setFloat(parameterIndex, x); - } - - @Override - public void setDouble(int parameterIndex, double x) throws SQLException { - this.stmt.setDouble(parameterIndex, x); - - } - - @Override - public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { - this.stmt.setBigDecimal(parameterIndex, x); - } - - @Override - public void setString(int parameterIndex, String x) throws SQLException { - this.stmt.setString(parameterIndex, x); - } - - @Override - public void setBytes(int parameterIndex, byte[] x) throws SQLException { - this.stmt.setBytes(parameterIndex, x); - } - - @Override - public void setDate(int parameterIndex, Date x) throws SQLException { - this.stmt.setDate(parameterIndex, x); - } - - @Override - public void setTime(int parameterIndex, Time x) throws SQLException { - this.stmt.setTime(parameterIndex, x); - } - - @Override - public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { - this.stmt.setTimestamp(parameterIndex, x); - } - - @Override - public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { - this.stmt.setAsciiStream(parameterIndex, x, length); - } - - @Override - @Deprecated - public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { - throw new SQLFeatureNotSupportedException(); - } - - @Override - public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { - this.stmt.setBinaryStream(parameterIndex, x, length); - } - - @Override - public void clearParameters() throws SQLException { - this.stmt.clearParameters(); - } - - @Override - public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { - this.stmt.setObject(parameterIndex, x, targetSqlType); - } - - @Override - public void setObject(int parameterIndex, Object x) throws SQLException { - this.stmt.setObject(parameterIndex, x); - } - - @Override - public boolean execute() throws SQLException { - return this.stmt.execute(); - } - - @Override - public void addBatch() throws SQLException { - this.stmt.addBatch(); - } - - @Override - public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { - this.stmt.setCharacterStream(parameterIndex, reader, length); - } - - @Override - public void setRef(int parameterIndex, Ref x) throws SQLException { - this.stmt.setRef(parameterIndex, x); - } - - @Override - public void setBlob(int parameterIndex, Blob x) throws SQLException { - this.stmt.setBlob(parameterIndex, x); - } - - @Override - public void setClob(int parameterIndex, Clob x) throws SQLException { - this.stmt.setClob(parameterIndex, x); - } - - @Override - public void setArray(int parameterIndex, Array x) throws SQLException { - this.stmt.setArray(parameterIndex, x); - } - - @Override - public ResultSetMetaData getMetaData() throws SQLException { - return this.stmt.getMetaData(); - } - - @Override - public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { - this.stmt.setDate(parameterIndex, x, cal); - } - - @Override - public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { - this.stmt.setTime(parameterIndex, x, cal); - } - - @Override - public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { - this.stmt.setTimestamp(parameterIndex, x, cal); - } - - @Override - public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { - this.stmt.setNull(parameterIndex, sqlType, typeName); - } - - @Override - public void setURL(int parameterIndex, URL x) throws SQLException { - this.stmt.setURL(parameterIndex, x); - } - - @Override - public ParameterMetaData getParameterMetaData() throws SQLException { - return this.stmt.getParameterMetaData(); - } - - @Override - public void setRowId(int parameterIndex, RowId x) throws SQLException { - this.stmt.setRowId(parameterIndex, x); - } - - @Override - public void setNString(int parameterIndex, String value) throws SQLException { - this.stmt.setNString(parameterIndex, value); - } - - @Override - public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { - this.stmt.setNCharacterStream(parameterIndex, value, length); - } - - @Override - public void setNClob(int parameterIndex, NClob value) throws SQLException { - this.stmt.setNClob(parameterIndex, value); - } - - @Override - public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { - this.stmt.setClob(parameterIndex, reader, length); - } - - @Override - public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { - this.stmt.setBlob(parameterIndex, inputStream, length); - } - - @Override - public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { - this.stmt.setNClob(parameterIndex, reader, length); - } - - @Override - public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { - this.stmt.setSQLXML(parameterIndex, xmlObject); - } - - @Override - public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { - this.stmt.setObject(parameterIndex, x, targetSqlType, scaleOrLength); - } - - @Override - public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { - this.stmt.setAsciiStream(parameterIndex, x, length); - } - - @Override - public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { - this.stmt.setBinaryStream(parameterIndex, x, length); - } - - @Override - public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { - this.stmt.setCharacterStream(parameterIndex, reader, length); - } - - @Override - public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { - this.stmt.setAsciiStream(parameterIndex, x); - } - - @Override - public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { - this.stmt.setBinaryStream(parameterIndex, x); - } - - @Override - public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { - this.stmt.setCharacterStream(parameterIndex, reader); - } - - @Override - public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { - this.stmt.setNCharacterStream(parameterIndex, value); - } - - @Override - public void setClob(int parameterIndex, Reader reader) throws SQLException { - this.stmt.setClob(parameterIndex, reader); - } - - @Override - public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { - this.stmt.setBlob(parameterIndex, inputStream); - } - - @Override - public void setNClob(int parameterIndex, Reader reader) throws SQLException { - this.stmt.setNClob(parameterIndex, reader); - } - - // Java7 Fixes - public void closeOnCompletion() throws SQLException { - throw new SQLFeatureNotSupportedException(); - } - - public boolean isCloseOnCompletion() throws SQLException { - throw new SQLFeatureNotSupportedException(); - } - - + private final DatabaseType dbType; + private final PreparedStatement stmt; + + public AutoIncrementPreparedStatement(DatabaseType dbType, PreparedStatement stmt) { + this.dbType = dbType; + this.stmt = stmt; + } + + /** Special override for Postgres */ + @Override + public ResultSet getGeneratedKeys() throws SQLException { + if (this.dbType == DatabaseType.POSTGRES + || this.dbType == DatabaseType.COCKROACHDB + || this.dbType == DatabaseType.SQLSERVER + || this.dbType == DatabaseType.SQLAZURE) { + return this.stmt.getResultSet(); + } else { + return this.stmt.getGeneratedKeys(); + } + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + return this.stmt.executeQuery(sql); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + return this.stmt.executeUpdate(sql); + } + + @Override + public void close() throws SQLException { + this.stmt.close(); + } + + @Override + public int getMaxFieldSize() throws SQLException { + return this.stmt.getMaxFieldSize(); + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + this.stmt.setMaxFieldSize(max); + } + + @Override + public int getMaxRows() throws SQLException { + return this.stmt.getMaxRows(); + } + + @Override + public void setMaxRows(int max) throws SQLException { + this.stmt.setMaxRows(max); + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + this.stmt.setEscapeProcessing(enable); + } + + @Override + public int getQueryTimeout() throws SQLException { + return this.stmt.getQueryTimeout(); + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + this.stmt.setQueryTimeout(seconds); + } + + @Override + public void cancel() throws SQLException { + this.stmt.cancel(); + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return this.stmt.getWarnings(); + } + + @Override + public void clearWarnings() throws SQLException { + this.stmt.clearWarnings(); + } + + @Override + public void setCursorName(String name) throws SQLException { + this.stmt.setCursorName(name); + } + + @Override + public boolean execute(String sql) throws SQLException { + return this.stmt.execute(sql); + } + + @Override + public ResultSet getResultSet() throws SQLException { + return this.stmt.getResultSet(); + } + + @Override + public int getUpdateCount() throws SQLException { + return this.stmt.getUpdateCount(); + } + + @Override + public boolean getMoreResults() throws SQLException { + return this.stmt.getMoreResults(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + this.stmt.setFetchDirection(direction); + } + + @Override + public int getFetchDirection() throws SQLException { + return this.stmt.getFetchDirection(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + this.stmt.setFetchSize(rows); + } + + @Override + public int getFetchSize() throws SQLException { + return this.stmt.getFetchSize(); + } + + @Override + public int getResultSetConcurrency() throws SQLException { + return this.stmt.getResultSetConcurrency(); + } + + @Override + public int getResultSetType() throws SQLException { + return this.stmt.getResultSetType(); + } + + @Override + public void addBatch(String sql) throws SQLException { + this.stmt.addBatch(sql); + } + + @Override + public void clearBatch() throws SQLException { + this.stmt.clearBatch(); + } + + @Override + public int[] executeBatch() throws SQLException { + return this.stmt.executeBatch(); + } + + @Override + public Connection getConnection() throws SQLException { + return this.stmt.getConnection(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + return this.stmt.getMoreResults(current); + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return this.stmt.executeUpdate(sql, autoGeneratedKeys); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return this.stmt.executeUpdate(sql, columnIndexes); + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return this.stmt.executeUpdate(sql, columnNames); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return this.stmt.execute(sql, autoGeneratedKeys); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return this.stmt.execute(sql, columnIndexes); + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return this.stmt.execute(sql, columnNames); + } + + @Override + public int getResultSetHoldability() throws SQLException { + return this.stmt.getResultSetHoldability(); + } + + @Override + public boolean isClosed() throws SQLException { + return this.stmt.isClosed(); + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + this.stmt.setPoolable(poolable); + } + + @Override + public boolean isPoolable() throws SQLException { + return this.stmt.isPoolable(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + return this.stmt.unwrap(iface); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return this.stmt.isWrapperFor(iface); + } + + @Override + public ResultSet executeQuery() throws SQLException { + return this.stmt.executeQuery(); + } + + @Override + public int executeUpdate() throws SQLException { + return this.stmt.executeUpdate(); + } + + @Override + public void setNull(int parameterIndex, int sqlType) throws SQLException { + this.stmt.setNull(parameterIndex, sqlType); + } + + @Override + public void setBoolean(int parameterIndex, boolean x) throws SQLException { + this.stmt.setBoolean(parameterIndex, x); + } + + @Override + public void setByte(int parameterIndex, byte x) throws SQLException { + this.stmt.setByte(parameterIndex, x); + } + + @Override + public void setShort(int parameterIndex, short x) throws SQLException { + this.stmt.setShort(parameterIndex, x); + } + + @Override + public void setInt(int parameterIndex, int x) throws SQLException { + this.stmt.setInt(parameterIndex, x); + } + + @Override + public void setLong(int parameterIndex, long x) throws SQLException { + this.stmt.setLong(parameterIndex, x); + } + + @Override + public void setFloat(int parameterIndex, float x) throws SQLException { + this.stmt.setFloat(parameterIndex, x); + } + + @Override + public void setDouble(int parameterIndex, double x) throws SQLException { + this.stmt.setDouble(parameterIndex, x); + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + this.stmt.setBigDecimal(parameterIndex, x); + } + + @Override + public void setString(int parameterIndex, String x) throws SQLException { + this.stmt.setString(parameterIndex, x); + } + + @Override + public void setBytes(int parameterIndex, byte[] x) throws SQLException { + this.stmt.setBytes(parameterIndex, x); + } + + @Override + public void setDate(int parameterIndex, Date x) throws SQLException { + this.stmt.setDate(parameterIndex, x); + } + + @Override + public void setTime(int parameterIndex, Time x) throws SQLException { + this.stmt.setTime(parameterIndex, x); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + this.stmt.setTimestamp(parameterIndex, x); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + this.stmt.setAsciiStream(parameterIndex, x, length); + } + + @Override + @Deprecated + public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + this.stmt.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void clearParameters() throws SQLException { + this.stmt.clearParameters(); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + this.stmt.setObject(parameterIndex, x, targetSqlType); + } + + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + this.stmt.setObject(parameterIndex, x); + } + + @Override + public boolean execute() throws SQLException { + return this.stmt.execute(); + } + + @Override + public void addBatch() throws SQLException { + this.stmt.addBatch(); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) + throws SQLException { + this.stmt.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setRef(int parameterIndex, Ref x) throws SQLException { + this.stmt.setRef(parameterIndex, x); + } + + @Override + public void setBlob(int parameterIndex, Blob x) throws SQLException { + this.stmt.setBlob(parameterIndex, x); + } + + @Override + public void setClob(int parameterIndex, Clob x) throws SQLException { + this.stmt.setClob(parameterIndex, x); + } + + @Override + public void setArray(int parameterIndex, Array x) throws SQLException { + this.stmt.setArray(parameterIndex, x); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return this.stmt.getMetaData(); + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + this.stmt.setDate(parameterIndex, x, cal); + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + this.stmt.setTime(parameterIndex, x, cal); + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + this.stmt.setTimestamp(parameterIndex, x, cal); + } + + @Override + public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { + this.stmt.setNull(parameterIndex, sqlType, typeName); + } + + @Override + public void setURL(int parameterIndex, URL x) throws SQLException { + this.stmt.setURL(parameterIndex, x); + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + return this.stmt.getParameterMetaData(); + } + + @Override + public void setRowId(int parameterIndex, RowId x) throws SQLException { + this.stmt.setRowId(parameterIndex, x); + } + + @Override + public void setNString(int parameterIndex, String value) throws SQLException { + this.stmt.setNString(parameterIndex, value); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) + throws SQLException { + this.stmt.setNCharacterStream(parameterIndex, value, length); + } + + @Override + public void setNClob(int parameterIndex, NClob value) throws SQLException { + this.stmt.setNClob(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + this.stmt.setClob(parameterIndex, reader, length); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) + throws SQLException { + this.stmt.setBlob(parameterIndex, inputStream, length); + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + this.stmt.setNClob(parameterIndex, reader, length); + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + this.stmt.setSQLXML(parameterIndex, xmlObject); + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) + throws SQLException { + this.stmt.setObject(parameterIndex, x, targetSqlType, scaleOrLength); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + this.stmt.setAsciiStream(parameterIndex, x, length); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + this.stmt.setBinaryStream(parameterIndex, x, length); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, long length) + throws SQLException { + this.stmt.setCharacterStream(parameterIndex, reader, length); + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + this.stmt.setAsciiStream(parameterIndex, x); + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + this.stmt.setBinaryStream(parameterIndex, x); + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + this.stmt.setCharacterStream(parameterIndex, reader); + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + this.stmt.setNCharacterStream(parameterIndex, value); + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + this.stmt.setClob(parameterIndex, reader); + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + this.stmt.setBlob(parameterIndex, inputStream); + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + this.stmt.setNClob(parameterIndex, reader); + } + + // Java7 Fixes + public void closeOnCompletion() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } + + public boolean isCloseOnCompletion() throws SQLException { + throw new SQLFeatureNotSupportedException(); + } } diff --git a/src/main/java/com/oltpbenchmark/types/DatabaseType.java b/src/main/java/com/oltpbenchmark/types/DatabaseType.java index 00e3d2b74..80a0a396f 100644 --- a/src/main/java/com/oltpbenchmark/types/DatabaseType.java +++ b/src/main/java/com/oltpbenchmark/types/DatabaseType.java @@ -22,108 +22,101 @@ import java.util.Map; /** - * List of the database management systems that we support - * in the framework. + * List of the database management systems that we support in the framework. * * @author pavlo */ public enum DatabaseType { - - AMAZONRDS(true, false), - CASSANDRA(true, true), - COCKROACHDB(false, false, true), - DB2(true, false), - H2(true, false), - HSQLDB(false, false), - POSTGRES(false, false, true), - MARIADB(true, false), - MONETDB(false, false), - MYROCKS(true, false), - MYSQL(true, false), - NOISEPAGE(false, false), - NUODB(true, false), - ORACLE(true, false), - SINGLESTORE(true, false), - SPANNER(false, true), - SQLAZURE(true, true, true), - SQLITE(true, false), - SQLSERVER(true, true, true), - TIMESTEN(true, false), - PHOENIX(true, true); - - - DatabaseType(boolean escapeNames, boolean includeColNames, boolean loadNeedsUpdateColumnSequence) { - this.escapeNames = escapeNames; - this.includeColNames = includeColNames; - this.loadNeedsUpdateColumnSequence = loadNeedsUpdateColumnSequence; - } - - DatabaseType(boolean escapeNames, boolean includeColNames) { - this(escapeNames, includeColNames, false); - } - - /** - * If this flag is set to true, then the framework will escape names in - * the INSERT queries - */ - private final boolean escapeNames; - - /** - * If this flag is set to true, then the framework will include the column names - * when generating INSERT queries for loading data. - */ - private final boolean includeColNames; - - /** - * If this flag is set to true, the framework will attempt to update the - * column sequence after loading data. - */ - private final boolean loadNeedsUpdateColumnSequence; - - - // --------------------------------------------------------------- - // ACCESSORS - // ---------------------------------------------------------------- - - /** - * @return True if the framework should escape the names of columns/tables when - * generating SQL to load in data for the target database type. - */ - public boolean shouldEscapeNames() { - return (this.escapeNames); - } - - /** - * @return True if the framework should include the names of columns when - * generating SQL to load in data for the target database type. - */ - public boolean shouldIncludeColumnNames() { - return (this.includeColNames); + AMAZONRDS(true, false), + CASSANDRA(true, true), + COCKROACHDB(false, false, true), + DB2(true, false), + H2(true, false), + HSQLDB(false, false), + POSTGRES(false, false, true), + MARIADB(true, false), + MONETDB(false, false), + MYROCKS(true, false), + MYSQL(true, false), + NOISEPAGE(false, false), + NUODB(true, false), + ORACLE(true, false), + SINGLESTORE(true, false), + SPANNER(false, true), + SQLAZURE(true, true, true), + SQLITE(true, false), + SQLSERVER(true, true, true), + TIMESTEN(true, false), + PHOENIX(true, true); + + DatabaseType( + boolean escapeNames, boolean includeColNames, boolean loadNeedsUpdateColumnSequence) { + this.escapeNames = escapeNames; + this.includeColNames = includeColNames; + this.loadNeedsUpdateColumnSequence = loadNeedsUpdateColumnSequence; + } + + DatabaseType(boolean escapeNames, boolean includeColNames) { + this(escapeNames, includeColNames, false); + } + + /** If this flag is set to true, then the framework will escape names in the INSERT queries */ + private final boolean escapeNames; + + /** + * If this flag is set to true, then the framework will include the column names when generating + * INSERT queries for loading data. + */ + private final boolean includeColNames; + + /** + * If this flag is set to true, the framework will attempt to update the column sequence after + * loading data. + */ + private final boolean loadNeedsUpdateColumnSequence; + + // --------------------------------------------------------------- + // ACCESSORS + // ---------------------------------------------------------------- + + /** + * @return True if the framework should escape the names of columns/tables when generating SQL to + * load in data for the target database type. + */ + public boolean shouldEscapeNames() { + return (this.escapeNames); + } + + /** + * @return True if the framework should include the names of columns when generating SQL to load + * in data for the target database type. + */ + public boolean shouldIncludeColumnNames() { + return (this.includeColNames); + } + + /** + * @return True if the framework should attempt to update the column sequence after loading data. + */ + public boolean shouldUpdateColumnSequenceAfterLoad() { + return (this.loadNeedsUpdateColumnSequence); + } + + // ---------------------------------------------------------------- + // STATIC METHODS + MEMBERS + // ---------------------------------------------------------------- + + protected static final Map idx_lookup = new HashMap<>(); + protected static final Map name_lookup = new HashMap<>(); + + static { + for (DatabaseType vt : EnumSet.allOf(DatabaseType.class)) { + DatabaseType.idx_lookup.put(vt.ordinal(), vt); + DatabaseType.name_lookup.put(vt.name().toUpperCase(), vt); } + } - /** - * @return True if the framework should attempt to update the column - * sequence after loading data. - */ - public boolean shouldUpdateColumnSequenceAfterLoad() { - return (this.loadNeedsUpdateColumnSequence); - } - - // ---------------------------------------------------------------- - // STATIC METHODS + MEMBERS - // ---------------------------------------------------------------- - - protected static final Map idx_lookup = new HashMap<>(); - protected static final Map name_lookup = new HashMap<>(); - - static { - for (DatabaseType vt : EnumSet.allOf(DatabaseType.class)) { - DatabaseType.idx_lookup.put(vt.ordinal(), vt); - DatabaseType.name_lookup.put(vt.name().toUpperCase(), vt); - } - } - - public static DatabaseType get(String name) { - return (DatabaseType.name_lookup.get(name.toUpperCase())); - } + public static DatabaseType get(String name) { + return (DatabaseType.name_lookup.get(name.toUpperCase())); + } } diff --git a/src/main/java/com/oltpbenchmark/types/SortDirectionType.java b/src/main/java/com/oltpbenchmark/types/SortDirectionType.java index 662741444..4e5114a7a 100644 --- a/src/main/java/com/oltpbenchmark/types/SortDirectionType.java +++ b/src/main/java/com/oltpbenchmark/types/SortDirectionType.java @@ -38,39 +38,36 @@ import java.util.HashMap; import java.util.Map; -/** - * - */ +/** */ public enum SortDirectionType { - INVALID(0), - ASC(1), - DESC(2); + INVALID(0), + ASC(1), + DESC(2); - SortDirectionType(int val) { - } + SortDirectionType(int val) {} - public int getValue() { - return this.ordinal(); - } + public int getValue() { + return this.ordinal(); + } - protected static final Map idx_lookup = new HashMap<>(); - protected static final Map name_lookup = new HashMap<>(); + protected static final Map idx_lookup = new HashMap<>(); + protected static final Map name_lookup = new HashMap<>(); - static { - for (SortDirectionType vt : EnumSet.allOf(SortDirectionType.class)) { - SortDirectionType.idx_lookup.put(vt.ordinal(), vt); - SortDirectionType.name_lookup.put(vt.name().toLowerCase().intern(), vt); - } + static { + for (SortDirectionType vt : EnumSet.allOf(SortDirectionType.class)) { + SortDirectionType.idx_lookup.put(vt.ordinal(), vt); + SortDirectionType.name_lookup.put(vt.name().toLowerCase().intern(), vt); } + } - public static SortDirectionType get(Integer idx) { + public static SortDirectionType get(Integer idx) { - SortDirectionType ret = SortDirectionType.idx_lookup.get(idx); - return (ret == null ? SortDirectionType.INVALID : ret); - } + SortDirectionType ret = SortDirectionType.idx_lookup.get(idx); + return (ret == null ? SortDirectionType.INVALID : ret); + } - public static SortDirectionType get(String name) { - SortDirectionType ret = SortDirectionType.name_lookup.get(name.toLowerCase().intern()); - return (ret == null ? SortDirectionType.INVALID : ret); - } + public static SortDirectionType get(String name) { + SortDirectionType ret = SortDirectionType.name_lookup.get(name.toLowerCase().intern()); + return (ret == null ? SortDirectionType.INVALID : ret); + } } diff --git a/src/main/java/com/oltpbenchmark/types/State.java b/src/main/java/com/oltpbenchmark/types/State.java index 2ad963831..611db1616 100644 --- a/src/main/java/com/oltpbenchmark/types/State.java +++ b/src/main/java/com/oltpbenchmark/types/State.java @@ -15,11 +15,15 @@ * */ -/** - * - */ +/** */ package com.oltpbenchmark.types; public enum State { - WARMUP, MEASURE, COLD_QUERY, LATENCY_COMPLETE, DONE, EXIT, ERROR -} \ No newline at end of file + WARMUP, + MEASURE, + COLD_QUERY, + LATENCY_COMPLETE, + DONE, + EXIT, + ERROR +} diff --git a/src/main/java/com/oltpbenchmark/types/TransactionStatus.java b/src/main/java/com/oltpbenchmark/types/TransactionStatus.java index df3745f00..f2f9628cd 100644 --- a/src/main/java/com/oltpbenchmark/types/TransactionStatus.java +++ b/src/main/java/com/oltpbenchmark/types/TransactionStatus.java @@ -18,36 +18,24 @@ package com.oltpbenchmark.types; public enum TransactionStatus { - /** - * Unknown status - */ - UNKNOWN, - /** - * The transaction executed successfully and - * committed without any errors. - */ - SUCCESS, - /** - * The transaction executed successfully but then was aborted - * due to the valid user control code. - * This is not an error. - */ - USER_ABORTED, - /** - * The transaction did not execute due to internal - * benchmark state. It should be retried - */ - RETRY, + /** Unknown status */ + UNKNOWN, + /** The transaction executed successfully and committed without any errors. */ + SUCCESS, + /** + * The transaction executed successfully but then was aborted due to the valid user control code. + * This is not an error. + */ + USER_ABORTED, + /** The transaction did not execute due to internal benchmark state. It should be retried */ + RETRY, - /** - * The transaction did not execute due to internal - * benchmark state. The Worker should retry but select - * a new random transaction to execute. - */ - RETRY_DIFFERENT, + /** + * The transaction did not execute due to internal benchmark state. The Worker should retry but + * select a new random transaction to execute. + */ + RETRY_DIFFERENT, - /** - * Transaction encountered an error and was not retried - */ - ERROR + /** Transaction encountered an error and was not retried */ + ERROR } diff --git a/src/main/java/com/oltpbenchmark/util/ClassUtil.java b/src/main/java/com/oltpbenchmark/util/ClassUtil.java index 80a00933f..474dfa6bf 100644 --- a/src/main/java/com/oltpbenchmark/util/ClassUtil.java +++ b/src/main/java/com/oltpbenchmark/util/ClassUtil.java @@ -15,195 +15,190 @@ * */ - package com.oltpbenchmark.util; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.lang3.ClassUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ClassUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author pavlo */ public abstract class ClassUtil { - private static final Logger LOG = LoggerFactory.getLogger(ClassUtil.class); - - private static final Map, List>> CACHE_getSuperClasses = new HashMap<>(); - private static final Map, Set>> CACHE_getInterfaceClasses = new HashMap<>(); - - /** - * Get the generic types for the given field - * - * @param field - * @return - */ - public static List> getGenericTypes(Field field) { - ArrayList> generic_classes = new ArrayList<>(); - Type gtype = field.getGenericType(); - if (gtype instanceof ParameterizedType) { - ParameterizedType ptype = (ParameterizedType) gtype; - getGenericTypesImpl(ptype, generic_classes); - } - return (generic_classes); + private static final Logger LOG = LoggerFactory.getLogger(ClassUtil.class); + + private static final Map, List>> CACHE_getSuperClasses = new HashMap<>(); + private static final Map, Set>> CACHE_getInterfaceClasses = new HashMap<>(); + + /** + * Get the generic types for the given field + * + * @param field + * @return + */ + public static List> getGenericTypes(Field field) { + ArrayList> generic_classes = new ArrayList<>(); + Type gtype = field.getGenericType(); + if (gtype instanceof ParameterizedType) { + ParameterizedType ptype = (ParameterizedType) gtype; + getGenericTypesImpl(ptype, generic_classes); } - - private static void getGenericTypesImpl(ParameterizedType ptype, List> classes) { - // list the actual type arguments - for (Type t : ptype.getActualTypeArguments()) { - if (t instanceof Class) { -// System.err.println("C: " + t); - classes.add((Class) t); - } else if (t instanceof ParameterizedType) { - ParameterizedType next = (ParameterizedType) t; -// System.err.println("PT: " + next); - classes.add((Class) next.getRawType()); - getGenericTypesImpl(next, classes); - } - } + return (generic_classes); + } + + private static void getGenericTypesImpl(ParameterizedType ptype, List> classes) { + // list the actual type arguments + for (Type t : ptype.getActualTypeArguments()) { + if (t instanceof Class) { + // System.err.println("C: " + t); + classes.add((Class) t); + } else if (t instanceof ParameterizedType) { + ParameterizedType next = (ParameterizedType) t; + // System.err.println("PT: " + next); + classes.add((Class) next.getRawType()); + getGenericTypesImpl(next, classes); + } } - - /** - * Return an ordered list of all the sub-classes for a given class - * Useful when dealing with generics - * - * @param element_class - * @return - */ - public static List> getSuperClasses(Class element_class) { - List> ret = ClassUtil.CACHE_getSuperClasses.get(element_class); - if (ret == null) { - ret = new ArrayList<>(); - while (element_class != null) { - ret.add(element_class); - element_class = element_class.getSuperclass(); - } - ret = Collections.unmodifiableList(ret); - ClassUtil.CACHE_getSuperClasses.put(element_class, ret); - } - return (ret); + } + + /** + * Return an ordered list of all the sub-classes for a given class Useful when dealing with + * generics + * + * @param element_class + * @return + */ + public static List> getSuperClasses(Class element_class) { + List> ret = ClassUtil.CACHE_getSuperClasses.get(element_class); + if (ret == null) { + ret = new ArrayList<>(); + while (element_class != null) { + ret.add(element_class); + element_class = element_class.getSuperclass(); + } + ret = Collections.unmodifiableList(ret); + ClassUtil.CACHE_getSuperClasses.put(element_class, ret); } - - /** - * Get a set of all of the interfaces that the element_class implements - * - * @param element_class - * @return - */ - - public static Collection> getInterfaces(Class element_class) { - Set> ret = ClassUtil.CACHE_getInterfaceClasses.get(element_class); - if (ret == null) { - ret = new HashSet>(ClassUtils.getAllInterfaces(element_class)); - if (element_class.isInterface()) { - ret.add(element_class); - } - ret = Collections.unmodifiableSet(ret); - ClassUtil.CACHE_getInterfaceClasses.put(element_class, ret); - } - return (ret); + return (ret); + } + + /** + * Get a set of all of the interfaces that the element_class implements + * + * @param element_class + * @return + */ + public static Collection> getInterfaces(Class element_class) { + Set> ret = ClassUtil.CACHE_getInterfaceClasses.get(element_class); + if (ret == null) { + ret = new HashSet>(ClassUtils.getAllInterfaces(element_class)); + if (element_class.isInterface()) { + ret.add(element_class); + } + ret = Collections.unmodifiableSet(ret); + ClassUtil.CACHE_getInterfaceClasses.put(element_class, ret); } - - @SuppressWarnings("unchecked") - public static T newInstance(String class_name, Object[] params, Class[] classes) { - return ((T) ClassUtil.newInstance(ClassUtil.getClass(class_name), params, classes)); + return (ret); + } + + @SuppressWarnings("unchecked") + public static T newInstance(String class_name, Object[] params, Class[] classes) { + return ((T) ClassUtil.newInstance(ClassUtil.getClass(class_name), params, classes)); + } + + public static T newInstance(Class target_class, Object[] params, Class[] classes) { + Constructor constructor = ClassUtil.getConstructor(target_class, classes); + T ret = null; + try { + ret = constructor.newInstance(params); + } catch (Exception ex) { + throw new RuntimeException( + "Failed to create new instance of " + target_class.getSimpleName(), ex); } - - - public static T newInstance(Class target_class, Object[] params, Class[] classes) { - Constructor constructor = ClassUtil.getConstructor(target_class, classes); - T ret = null; - try { - ret = constructor.newInstance(params); - } catch (Exception ex) { - throw new RuntimeException("Failed to create new instance of " + target_class.getSimpleName(), ex); - } - return (ret); + return (ret); + } + + /** + * @param + * @param target_class + * @param params + * @return + */ + @SuppressWarnings("unchecked") + public static Constructor getConstructor(Class target_class, Class... params) { + NoSuchMethodException error = null; + try { + return (target_class.getConstructor(params)); + } catch (NoSuchMethodException ex) { + // The first time we get this it can be ignored + // We'll try to be nice and find a match for them + error = ex; } - /** - * @param - * @param target_class - * @param params - * @return - */ - @SuppressWarnings("unchecked") - public static Constructor getConstructor(Class target_class, Class... params) { - NoSuchMethodException error = null; - try { - return (target_class.getConstructor(params)); - } catch (NoSuchMethodException ex) { - // The first time we get this it can be ignored - // We'll try to be nice and find a match for them - error = ex; - } + if (LOG.isDebugEnabled()) { + LOG.debug("TARGET CLASS: {}", target_class); + LOG.debug("TARGET PARAMS: {}", Arrays.toString(params)); + } + @SuppressWarnings("rawtypes") + List>[] paramSuper = (List>[]) new List[params.length]; + for (int i = 0; i < params.length; i++) { + paramSuper[i] = ClassUtil.getSuperClasses(params[i]); + if (LOG.isDebugEnabled()) { + LOG.debug(" SUPER[{}] => {}", params[i].getSimpleName(), paramSuper[i]); + } + } + for (Constructor c : target_class.getConstructors()) { + Class[] cTypes = c.getParameterTypes(); + if (LOG.isDebugEnabled()) { + LOG.debug("CANDIDATE: {}", c); + LOG.debug("CANDIDATE PARAMS: {}", Arrays.toString(cTypes)); + } + if (params.length != cTypes.length) { + continue; + } + + for (int i = 0; i < params.length; i++) { + List> cSuper = ClassUtil.getSuperClasses(cTypes[i]); if (LOG.isDebugEnabled()) { - LOG.debug("TARGET CLASS: {}", target_class); - LOG.debug("TARGET PARAMS: {}", Arrays.toString(params)); - } - - @SuppressWarnings("rawtypes") - List>[] paramSuper = (List>[]) new List[params.length]; - for (int i = 0; i < params.length; i++) { - paramSuper[i] = ClassUtil.getSuperClasses(params[i]); - if (LOG.isDebugEnabled()) { - LOG.debug(" SUPER[{}] => {}", params[i].getSimpleName(), paramSuper[i]); - } + LOG.debug(" SUPER[{}] => {}", cTypes[i].getSimpleName(), cSuper); } - - for (Constructor c : target_class.getConstructors()) { - Class[] cTypes = c.getParameterTypes(); - if (LOG.isDebugEnabled()) { - LOG.debug("CANDIDATE: {}", c); - LOG.debug("CANDIDATE PARAMS: {}", Arrays.toString(cTypes)); - } - if (params.length != cTypes.length) { - continue; - } - - for (int i = 0; i < params.length; i++) { - List> cSuper = ClassUtil.getSuperClasses(cTypes[i]); - if (LOG.isDebugEnabled()) { - LOG.debug(" SUPER[{}] => {}", cTypes[i].getSimpleName(), cSuper); - } - if (!CollectionUtils.intersection(paramSuper[i], cSuper).isEmpty()) { - return ((Constructor) c); - } - } + if (!CollectionUtils.intersection(paramSuper[i], cSuper).isEmpty()) { + return ((Constructor) c); } - throw new RuntimeException("Failed to retrieve constructor for " + target_class.getSimpleName(), error); - } - - /** - * @param class_name - * @return - */ - public static Class getClass(String class_name) { - return getClass(ClassLoader.getSystemClassLoader(), class_name); + } } - - /** - * @param loader - * @param class_name - * @return - */ - public static Class getClass(ClassLoader loader, String class_name) { - Class target_class = null; - try { - target_class = ClassUtils.getClass(loader, class_name); - } catch (Exception ex) { - throw new RuntimeException("Failed to retrieve class for " + class_name, ex); - } - return target_class; - + throw new RuntimeException( + "Failed to retrieve constructor for " + target_class.getSimpleName(), error); + } + + /** + * @param class_name + * @return + */ + public static Class getClass(String class_name) { + return getClass(ClassLoader.getSystemClassLoader(), class_name); + } + + /** + * @param loader + * @param class_name + * @return + */ + public static Class getClass(ClassLoader loader, String class_name) { + Class target_class = null; + try { + target_class = ClassUtils.getClass(loader, class_name); + } catch (Exception ex) { + throw new RuntimeException("Failed to retrieve class for " + class_name, ex); } - + return target_class; + } } diff --git a/src/main/java/com/oltpbenchmark/util/CollectionUtil.java b/src/main/java/com/oltpbenchmark/util/CollectionUtil.java index 7e8587050..b6f17396a 100644 --- a/src/main/java/com/oltpbenchmark/util/CollectionUtil.java +++ b/src/main/java/com/oltpbenchmark/util/CollectionUtil.java @@ -15,170 +15,166 @@ * */ - package com.oltpbenchmark.util; -import org.apache.commons.collections4.set.ListOrderedSet; - import java.util.*; +import org.apache.commons.collections4.set.ListOrderedSet; /** * @author pavlo */ public abstract class CollectionUtil { - /** - * Put all the values of an Iterator into a List - * - * @param - * @param it - * @return - */ - public static List list(Iterator it) { - List list = new ArrayList<>(); - CollectionUtil.addAll(list, it); - return (list); + /** + * Put all the values of an Iterator into a List + * + * @param + * @param it + * @return + */ + public static List list(Iterator it) { + List list = new ArrayList<>(); + CollectionUtil.addAll(list, it); + return (list); + } + + /** + * Add all the items in the array to a Collection + * + * @param + * @param data + * @param items + */ + @SuppressWarnings("unchecked") + public static Collection addAll(Collection data, T... items) { + data.addAll(Arrays.asList(items)); + return (data); + } + + /** + * Add all of the items from the Iterator into the given collection + * + * @param + * @param data + * @param items + */ + public static Collection addAll(Collection data, Iterator items) { + while (items.hasNext()) { + data.add(items.next()); } - - - /** - * Add all the items in the array to a Collection - * - * @param - * @param data - * @param items - */ - @SuppressWarnings("unchecked") - public static Collection addAll(Collection data, T... items) { - data.addAll(Arrays.asList(items)); - return (data); + return (data); + } + + /** + * @param + * @param + * @param map + * @return + */ + public static > T getGreatest(Map map) { + T max_key = null; + U max_value = null; + for (Map.Entry e : map.entrySet()) { + T key = e.getKey(); + U value = e.getValue(); + if (max_value == null || value.compareTo(max_value) > 0) { + max_value = value; + max_key = key; + } + } // FOR + return (max_key); + } + + /** + * Return the first item in a Iterable + * + * @param + * @param items + * @return + */ + public static T first(Iterable items) { + return (CollectionUtil.get(items, 0)); + } + + /** + * Return the ith element of a set. Super lame + * + * @param + * @param items + * @param idx + * @return + */ + public static T get(Iterable items, int idx) { + if (items instanceof AbstractList) { + return ((AbstractList) items).get(idx); + } else if (items instanceof ListOrderedSet) { + return ((ListOrderedSet) items).get(idx); } - - /** - * Add all of the items from the Iterator into the given collection - * - * @param - * @param data - * @param items - */ - public static Collection addAll(Collection data, Iterator items) { - while (items.hasNext()) { - data.add(items.next()); - } - return (data); - } - - /** - * @param - * @param - * @param map - * @return - */ - public static > T getGreatest(Map map) { - T max_key = null; - U max_value = null; - for (Map.Entry e : map.entrySet()) { - T key = e.getKey(); - U value = e.getValue(); - if (max_value == null || value.compareTo(max_value) > 0) { - max_value = value; - max_key = key; - } - } // FOR - return (max_key); - } - - /** - * Return the first item in a Iterable - * - * @param - * @param items - * @return - */ - public static T first(Iterable items) { - return (CollectionUtil.get(items, 0)); - } - - /** - * Return the ith element of a set. Super lame - * - * @param - * @param items - * @param idx - * @return - */ - public static T get(Iterable items, int idx) { - if (items instanceof AbstractList) { - return ((AbstractList) items).get(idx); - } else if (items instanceof ListOrderedSet) { - return ((ListOrderedSet) items).get(idx); - } - int ctr = 0; - for (T t : items) { - if (ctr++ == idx) { - return (t); - } - } - return (null); - } - - /** - * Return the last item in an Iterable - * - * @param - * @param items - * @return - */ - public static T last(Iterable items) { - T last = null; - if (items instanceof AbstractList) { - AbstractList list = (AbstractList) items; - last = (list.isEmpty() ? null : list.get(list.size() - 1)); - } else { - for (T t : items) { - last = t; - } - } - return (last); + int ctr = 0; + for (T t : items) { + if (ctr++ == idx) { + return (t); + } } - - /** - * Return the last item in an array - * - * @param - * @param items - * @return - */ - @SuppressWarnings("unchecked") - public static T last(T... items) { - if (items != null && items.length > 0) { - return (items[items.length - 1]); - } - return (null); + return (null); + } + + /** + * Return the last item in an Iterable + * + * @param + * @param items + * @return + */ + public static T last(Iterable items) { + T last = null; + if (items instanceof AbstractList) { + AbstractList list = (AbstractList) items; + last = (list.isEmpty() ? null : list.get(list.size() - 1)); + } else { + for (T t : items) { + last = t; + } } - - /** - * Wrap an Iterable around an Iterator - * - * @param - * @param it - * @return - */ - public static Iterable iterable(final Iterator it) { - return (new Iterable() { - @Override - public Iterator iterator() { - return (it); - } - }); + return (last); + } + + /** + * Return the last item in an array + * + * @param + * @param items + * @return + */ + @SuppressWarnings("unchecked") + public static T last(T... items) { + if (items != null && items.length > 0) { + return (items[items.length - 1]); } - - public static T pop(Collection items) { - T t = CollectionUtil.first(items); - if (t != null) { - items.remove(t); - - } - return (t); + return (null); + } + + /** + * Wrap an Iterable around an Iterator + * + * @param + * @param it + * @return + */ + public static Iterable iterable(final Iterator it) { + return (new Iterable() { + @Override + public Iterator iterator() { + return (it); + } + }); + } + + public static T pop(Collection items) { + T t = CollectionUtil.first(items); + if (t != null) { + items.remove(t); } + return (t); + } } diff --git a/src/main/java/com/oltpbenchmark/util/CompositeId.java b/src/main/java/com/oltpbenchmark/util/CompositeId.java index ab8b8f871..add8d4409 100644 --- a/src/main/java/com/oltpbenchmark/util/CompositeId.java +++ b/src/main/java/com/oltpbenchmark/util/CompositeId.java @@ -15,13 +15,10 @@ * */ - package com.oltpbenchmark.util; - -import org.apache.commons.lang3.StringUtils; - import java.util.stream.IntStream; +import org.apache.commons.lang3.StringUtils; /** * Pack multiple values into a single long using bit-shifting @@ -30,43 +27,41 @@ */ public abstract class CompositeId { - private static final String PAD_STRING = "0"; - public static final int INT_MAX_DIGITS = 10; - public static final int LONG_MAX_DIGITS = 19; + private static final String PAD_STRING = "0"; + public static final int INT_MAX_DIGITS = 10; + public static final int LONG_MAX_DIGITS = 19; - protected final String encode(int[] offset_bits) { - int encodedStringSize = IntStream.of(offset_bits).sum(); - StringBuilder compositeBuilder = new StringBuilder(encodedStringSize); + protected final String encode(int[] offset_bits) { + int encodedStringSize = IntStream.of(offset_bits).sum(); + StringBuilder compositeBuilder = new StringBuilder(encodedStringSize); - String[] decodedValues = this.toArray(); - for (int i = 0; i < decodedValues.length; i++) { - String value = decodedValues[i]; - int valueLength = offset_bits[i]; - String encodedValue = StringUtils.leftPad(value, valueLength, PAD_STRING); - compositeBuilder.append(encodedValue); - } - - return compositeBuilder.toString(); + String[] decodedValues = this.toArray(); + for (int i = 0; i < decodedValues.length; i++) { + String value = decodedValues[i]; + int valueLength = offset_bits[i]; + String encodedValue = StringUtils.leftPad(value, valueLength, PAD_STRING); + compositeBuilder.append(encodedValue); } - protected final String[] decode(String composite_id, int[] offset_bits) { - String[] decodedValues = new String[offset_bits.length]; - - int start = 0; - for (int i = 0; i < decodedValues.length; i++) { - int valueLength = offset_bits[i]; - int end = start + valueLength; - decodedValues[i] = StringUtils.substring(composite_id, start, end); - start = end; - } - return decodedValues; - } + return compositeBuilder.toString(); + } - public abstract String encode(); + protected final String[] decode(String composite_id, int[] offset_bits) { + String[] decodedValues = new String[offset_bits.length]; - public abstract void decode(String composite_id); + int start = 0; + for (int i = 0; i < decodedValues.length; i++) { + int valueLength = offset_bits[i]; + int end = start + valueLength; + decodedValues[i] = StringUtils.substring(composite_id, start, end); + start = end; + } + return decodedValues; + } - public abstract String[] toArray(); + public abstract String encode(); + public abstract void decode(String composite_id); + public abstract String[] toArray(); } diff --git a/src/main/java/com/oltpbenchmark/util/FileUtil.java b/src/main/java/com/oltpbenchmark/util/FileUtil.java index e6da082e4..aa4c4eabd 100644 --- a/src/main/java/com/oltpbenchmark/util/FileUtil.java +++ b/src/main/java/com/oltpbenchmark/util/FileUtil.java @@ -15,7 +15,6 @@ * */ - package com.oltpbenchmark.util; import java.io.File; @@ -28,86 +27,83 @@ */ public abstract class FileUtil { - private static final Pattern EXT_SPLIT = Pattern.compile("\\."); + private static final Pattern EXT_SPLIT = Pattern.compile("\\."); - /** - * Join path components - * - * @param args - * @return - */ - public static String joinPath(String... args) { - StringBuilder result = new StringBuilder(); - boolean first = true; - for (String a : args) { - if (a != null && a.length() > 0) { - if (!first) { - result.append("/"); - } - result.append(a); - first = false; - } + /** + * Join path components + * + * @param args + * @return + */ + public static String joinPath(String... args) { + StringBuilder result = new StringBuilder(); + boolean first = true; + for (String a : args) { + if (a != null && a.length() > 0) { + if (!first) { + result.append("/"); } - return result.toString(); + result.append(a); + first = false; + } } + return result.toString(); + } - /** - * Given a basename for a file, find the next possible filename if this file - * already exists. For example, if the file test.res already exists, create - * a file called, test.1.res - * - * @param basename - * @return - */ - public static String getNextFilename(String basename) { - - if (!exists(basename)) - return basename; + /** + * Given a basename for a file, find the next possible filename if this file already exists. For + * example, if the file test.res already exists, create a file called, test.1.res + * + * @param basename + * @return + */ + public static String getNextFilename(String basename) { - File f = new File(basename); - if (f != null && f.isFile()) { - String parts[] = EXT_SPLIT.split(basename); + if (!exists(basename)) return basename; - // Check how many files already exist - int counter = 1; - String nextName = parts[0] + "." + counter + "." + parts[1]; - while (exists(nextName)) { - ++counter; - nextName = parts[0] + "." + counter + "." + parts[1]; - } - return nextName; - } + File f = new File(basename); + if (f != null && f.isFile()) { + String parts[] = EXT_SPLIT.split(basename); - // Should we throw instead?? - return null; + // Check how many files already exist + int counter = 1; + String nextName = parts[0] + "." + counter + "." + parts[1]; + while (exists(nextName)) { + ++counter; + nextName = parts[0] + "." + counter + "." + parts[1]; + } + return nextName; } - public static boolean exists(String path) { - return (new File(path).exists()); - } + // Should we throw instead?? + return null; + } - /** - * Create any directory in the list paths if it doesn't exist - * - * @param paths - */ - public static void makeDirIfNotExists(String... paths) { - for (String p : paths) { - if (p == null) { - continue; - } - File f = new File(p); - if (!f.exists()) { - f.mkdirs(); - } - } - } + public static boolean exists(String path) { + return (new File(path).exists()); + } - public static void writeStringToFile(File file, String content) throws IOException { - try (FileWriter writer = new FileWriter(file)) { - writer.write(content); - writer.flush(); - } + /** + * Create any directory in the list paths if it doesn't exist + * + * @param paths + */ + public static void makeDirIfNotExists(String... paths) { + for (String p : paths) { + if (p == null) { + continue; + } + File f = new File(p); + if (!f.exists()) { + f.mkdirs(); + } } + } + public static void writeStringToFile(File file, String content) throws IOException { + try (FileWriter writer = new FileWriter(file)) { + writer.write(content); + writer.flush(); + } + } } diff --git a/src/main/java/com/oltpbenchmark/util/Histogram.java b/src/main/java/com/oltpbenchmark/util/Histogram.java index d3c246c51..2913987c8 100644 --- a/src/main/java/com/oltpbenchmark/util/Histogram.java +++ b/src/main/java/com/oltpbenchmark/util/Histogram.java @@ -15,20 +15,18 @@ * */ - package com.oltpbenchmark.util; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.*; +import java.util.Map.Entry; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONStringer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.*; -import java.util.Map.Entry; - /** * A very nice and simple generic Histogram * @@ -36,631 +34,615 @@ * @author pavlo */ public class Histogram> implements JSONSerializable { - private static final Logger LOG = LoggerFactory.getLogger(Histogram.class); - - private static final long serialVersionUID = 0L; - - private static final String MARKER = "*"; - private static final Integer MAX_CHARS = 80; - private static final Integer MAX_VALUE_LENGTH = 80; - - public enum Members { - VALUE_TYPE, - HISTOGRAM, - NUM_SAMPLES, - KEEP_ZERO_ENTRIES, - } - - protected final TreeMap histogram = new TreeMap<>(); - protected int num_samples = 0; - private transient boolean dirty = false; - - /** - * - */ - protected transient Map debug_names; - - /** - * The Min/Max values are the smallest/greatest values we have seen based - * on some natural ordering - */ - // Note: marked as transient to avoid serialization warnings due to missing - // explicit Serializable interface on base types like X == Integer - protected transient Comparable min_value; - protected transient Comparable max_value; - - /** - * The Min/Max counts are the values that have the smallest/greatest number of - * occurences in the histogram - */ - protected int min_count = 0; - protected ArrayList min_count_values; - protected int max_count = 0; - protected ArrayList max_count_values; - - /** - * A switchable flag that determines whether non-zero entries are kept or removed - */ - protected boolean keep_zero_entries = false; - - /** - * Constructor - */ - public Histogram() { - // Nothing... - } - - /** - * Constructor - * - * @param keepZeroEntries - */ - public Histogram(boolean keepZeroEntries) { - this.keep_zero_entries = keepZeroEntries; - } - - public boolean hasDebugLabels() { - return (this.debug_names != null && !this.debug_names.isEmpty()); - } - - - /** - * Set whether this histogram is allowed to retain zero count entries - * If the flag switches from true to false, then all zero count entries will be removed - * Default is false - * - * @param flag - */ - public void setKeepZeroEntries(boolean flag) { - // When this option is disabled, we need to remove all of the zeroed entries - if (!flag && this.keep_zero_entries) { - synchronized (this) { - Iterator it = this.histogram.keySet().iterator(); - int ctr = 0; - while (it.hasNext()) { - X key = it.next(); - if (this.histogram.get(key) == 0) { - it.remove(); - ctr++; - this.dirty = true; - } - } - if (ctr > 0) { - LOG.debug("Removed {} zero entries from histogram", ctr); - } - } - } - this.keep_zero_entries = flag; - } - - public boolean isZeroEntriesEnabled() { - return this.keep_zero_entries; - } - - /** - * The main method that updates a value in the histogram with a given sample count - * This should be called by one of the public interface methods that are synchronized - * This method is not synchronized on purpose for performance - * - * @param value - * @param count - */ - private void _put(X value, int count) { - if (value == null) { - return; + private static final Logger LOG = LoggerFactory.getLogger(Histogram.class); + + private static final long serialVersionUID = 0L; + + private static final String MARKER = "*"; + private static final Integer MAX_CHARS = 80; + private static final Integer MAX_VALUE_LENGTH = 80; + + public enum Members { + VALUE_TYPE, + HISTOGRAM, + NUM_SAMPLES, + KEEP_ZERO_ENTRIES, + } + + protected final TreeMap histogram = new TreeMap<>(); + protected int num_samples = 0; + private transient boolean dirty = false; + + /** */ + protected transient Map debug_names; + + /** + * The Min/Max values are the smallest/greatest values we have seen based on some natural ordering + */ + // Note: marked as transient to avoid serialization warnings due to missing + // explicit Serializable interface on base types like X == Integer + protected transient Comparable min_value; + + protected transient Comparable max_value; + + /** + * The Min/Max counts are the values that have the smallest/greatest number of occurences in the + * histogram + */ + protected int min_count = 0; + + protected ArrayList min_count_values; + protected int max_count = 0; + protected ArrayList max_count_values; + + /** A switchable flag that determines whether non-zero entries are kept or removed */ + protected boolean keep_zero_entries = false; + + /** Constructor */ + public Histogram() { + // Nothing... + } + + /** + * Constructor + * + * @param keepZeroEntries + */ + public Histogram(boolean keepZeroEntries) { + this.keep_zero_entries = keepZeroEntries; + } + + public boolean hasDebugLabels() { + return (this.debug_names != null && !this.debug_names.isEmpty()); + } + + /** + * Set whether this histogram is allowed to retain zero count entries If the flag switches from + * true to false, then all zero count entries will be removed Default is false + * + * @param flag + */ + public void setKeepZeroEntries(boolean flag) { + // When this option is disabled, we need to remove all of the zeroed entries + if (!flag && this.keep_zero_entries) { + synchronized (this) { + Iterator it = this.histogram.keySet().iterator(); + int ctr = 0; + while (it.hasNext()) { + X key = it.next(); + if (this.histogram.get(key) == 0) { + it.remove(); + ctr++; + this.dirty = true; + } } - this.num_samples += count; - - // If we already have this value in our histogram, then add the new count - // to its existing total - if (this.histogram.containsKey(value)) { - count += this.histogram.get(value); + if (ctr > 0) { + LOG.debug("Removed {} zero entries from histogram", ctr); } - - // If the new count is zero, then completely remove it if we're not allowed to have zero entries - if (count == 0 && !this.keep_zero_entries) { - this.histogram.remove(value); - } else { - this.histogram.put(value, count); + } + } + this.keep_zero_entries = flag; + } + + public boolean isZeroEntriesEnabled() { + return this.keep_zero_entries; + } + + /** + * The main method that updates a value in the histogram with a given sample count This should be + * called by one of the public interface methods that are synchronized This method is not + * synchronized on purpose for performance + * + * @param value + * @param count + */ + private void _put(X value, int count) { + if (value == null) { + return; + } + this.num_samples += count; + + // If we already have this value in our histogram, then add the new count + // to its existing total + if (this.histogram.containsKey(value)) { + count += this.histogram.get(value); + } + + // If the new count is zero, then completely remove it if we're not allowed to have zero entries + if (count == 0 && !this.keep_zero_entries) { + this.histogram.remove(value); + } else { + this.histogram.put(value, count); + } + this.dirty = true; + } + + /** + * Recalculate the min/max count value sets Since this is expensive, this should only be done + * whenever that information is needed + */ + private synchronized void calculateInternalValues() { + if (!this.dirty) { + return; + } + + // New Min/Max Counts + // The reason we have to loop through and check every time is that our + // value may be the current min/max count and thus it may or may not still + // be after the count is changed + this.max_count = 0; + this.min_count = Integer.MAX_VALUE; + this.min_value = null; + this.max_value = null; + + if (this.min_count_values == null) { + this.min_count_values = new ArrayList<>(); + } + if (this.max_count_values == null) { + this.max_count_values = new ArrayList<>(); + } + + for (Entry e : this.histogram.entrySet()) { + X value = e.getKey(); + int cnt = e.getValue(); + + // Is this value the new min/max values? + if (this.min_value == null || this.min_value.compareTo(value) > 0) { + this.min_value = value; + } + + if (this.max_value == null || this.max_value.compareTo(value) < 0) { + this.max_value = value; + } + + if (cnt <= this.min_count) { + if (cnt < this.min_count) { + this.min_count_values.clear(); } - this.dirty = true; - } - - /** - * Recalculate the min/max count value sets - * Since this is expensive, this should only be done whenever that information is needed - */ + this.min_count_values.add(value); + this.min_count = cnt; + } - private synchronized void calculateInternalValues() { - if (!this.dirty) { - return; + if (cnt >= this.max_count) { + if (cnt > this.max_count) { + this.max_count_values.clear(); } - - // New Min/Max Counts - // The reason we have to loop through and check every time is that our - // value may be the current min/max count and thus it may or may not still - // be after the count is changed - this.max_count = 0; - this.min_count = Integer.MAX_VALUE; - this.min_value = null; - this.max_value = null; - - if (this.min_count_values == null) { - this.min_count_values = new ArrayList<>(); - } - if (this.max_count_values == null) { - this.max_count_values = new ArrayList<>(); - } - - for (Entry e : this.histogram.entrySet()) { - X value = e.getKey(); - int cnt = e.getValue(); - - // Is this value the new min/max values? - if (this.min_value == null || this.min_value.compareTo(value) > 0) { - this.min_value = value; - } - - if (this.max_value == null || this.max_value.compareTo(value) < 0) { - this.max_value = value; - } - - if (cnt <= this.min_count) { - if (cnt < this.min_count) { - this.min_count_values.clear(); - } - this.min_count_values.add(value); - this.min_count = cnt; + this.max_count_values.add(value); + this.max_count = cnt; + } + } + this.dirty = false; + } + + /** + * Get the number of samples entered into the histogram using the put methods + * + * @return + */ + public int getSampleCount() { + return (this.num_samples); + } + + /** + * Get the number of unique values entered into the histogram + * + * @return + */ + public int getValueCount() { + return (this.histogram.values().size()); + } + + /** + * Get the smallest value entered into the histogram This assumes that the values implement the + * Comparable interface + * + * @return + */ + @SuppressWarnings("unchecked") + public X getMinValue() { + this.calculateInternalValues(); + return ((X) this.min_value); + } + + /** + * Get the largest value entered into the histogram This assumes that the values implement the + * Comparable interface + * + * @return + */ + @SuppressWarnings("unchecked") + public X getMaxValue() { + this.calculateInternalValues(); + return ((X) this.max_value); + } + + /** + * Return the number of samples for the value with the smallest number of samples in the histogram + * + * @return + */ + public int getMinCount() { + this.calculateInternalValues(); + return (this.min_count); + } + + /** + * Return the set values with the smallest number of samples + * + * @return + */ + public Collection getMinCountValues() { + this.calculateInternalValues(); + return (this.min_count_values); + } + + /** + * Return the number of samples for the value with the greatest number of samples in the histogram + * + * @return + */ + public int getMaxCount() { + this.calculateInternalValues(); + return (this.max_count); + } + + /** + * Return the set values with the greatest number of samples + * + * @return + */ + public Collection getMaxCountValues() { + this.calculateInternalValues(); + return (this.max_count_values); + } + + /** + * Return all the values stored in the histogram + * + * @return + */ + public Collection values() { + return (Collections.unmodifiableCollection(this.histogram.keySet())); + } + + /** Reset the histogram's internal data */ + public synchronized void clear() { + this.histogram.clear(); + this.num_samples = 0; + this.min_count = 0; + if (this.min_count_values != null) { + this.min_count_values.clear(); + } + this.min_value = null; + this.max_count = 0; + if (this.max_count_values != null) { + this.max_count_values.clear(); + } + this.max_value = null; + + this.dirty = true; + } + + /** + * Clear all the values stored in the histogram. The keys are only kept if KeepZeroEntries is + * enabled, otherwise it does the same thing as clear() + */ + public synchronized void clearValues() { + if (this.keep_zero_entries) { + for (Entry e : this.histogram.entrySet()) { + this.histogram.put(e.getKey(), 0); + } // FOR + this.num_samples = 0; + this.min_count = 0; + if (this.min_count_values != null) this.min_count_values.clear(); + this.min_value = null; + this.max_count = 0; + if (this.max_count_values != null) this.max_count_values.clear(); + this.max_value = null; + } else { + this.clear(); + } + this.dirty = true; + } + + /** + * @return + */ + public boolean isEmpty() { + return (this.histogram.isEmpty()); + } + + /** + * Increments the number of occurrences of this particular value i + * + * @param value the value to be added to the histogram + */ + public synchronized void put(X value, int i) { + this._put(value, i); + } + + /** + * Set the number of occurrences of this particular value i + * + * @param value the value to be added to the histogram + */ + public synchronized void set(X value, int i) { + Integer orig = this.get(value); + if (orig != null && orig != i) { + i = (orig > i ? -1 * (orig - i) : i - orig); + } + this._put(value, i); + } + + /** + * Increments the number of occurrences of this particular value i + * + * @param value the value to be added to the histogram + */ + public synchronized void put(X value) { + this._put(value, 1); + } + + /** Increment all values in the histogram by one */ + public void putAll() { + this.putAll(this.histogram.keySet(), 1); + } + + /** + * Increment multiple values by one + * + * @param values + */ + public void putAll(Collection values) { + this.putAll(values, 1); + } + + /** + * Increment multiple values by the given count + * + * @param values + * @param count + */ + public synchronized void putAll(Collection values, int count) { + for (X v : values) { + this._put(v, count); + } + } + + /** + * Add all the entries from the provided Histogram into this objects totals + * + * @param other + */ + public synchronized void putHistogram(Histogram other) { + for (Entry e : other.histogram.entrySet()) { + if (e.getValue() > 0) { + this._put(e.getKey(), e.getValue()); + } + } + } + + /** + * Remove the entire count for the given value + * + * @param value + */ + public synchronized void removeAll(X value) { + Integer cnt = this.histogram.get(value); + if (cnt != null && cnt > 0) { + this._put(value, cnt * -1); + } + } + + /** + * Returns the current count for the given value If the value was never entered into the + * histogram, then the count will be null + * + * @param value + * @return + */ + public Integer get(X value) { + return (histogram.get(value)); + } + + /** + * Returns the current count for the given value. If that value was nevered entered in the + * histogram, then the value returned will be value_if_null + * + * @param value + * @param value_if_null + * @return + */ + public int get(X value, int value_if_null) { + Integer count = histogram.get(value); + return (count == null ? value_if_null : count); + } + + /** + * Returns true if this histogram contains the specified key. + * + * @param value + * @return + */ + public boolean contains(X value) { + return (this.histogram.containsKey(value)); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Histogram histogram1 = (Histogram) o; + return Objects.equals(histogram, histogram1.histogram); + } + + @Override + public int hashCode() { + return Objects.hash(histogram); + } + + // ---------------------------------------------------------------------------- + // DEBUG METHODS + // ---------------------------------------------------------------------------- + + /** Histogram Pretty Print */ + public String toString() { + return (this.toString(MAX_CHARS, MAX_VALUE_LENGTH)); + } + + /** + * Histogram Pretty Print + * + * @param max_chars + * @param max_length + * @return + */ + public synchronized String toString(Integer max_chars, Integer max_length) { + StringBuilder s = new StringBuilder(); + if (max_length == null) { + max_length = MAX_VALUE_LENGTH; + } + + this.calculateInternalValues(); + + // Figure out the max size of the counts + int max_ctr_length = 4; + for (Integer ctr : this.histogram.values()) { + max_ctr_length = Math.max(max_ctr_length, ctr.toString().length()); + } + + // Don't let anything go longer than MAX_VALUE_LENGTH chars + String f = "%-" + max_length + "s [%" + max_ctr_length + "d] "; + boolean first = true; + boolean has_labels = this.hasDebugLabels(); + for (Object value : this.histogram.keySet()) { + if (!first) { + s.append("\n"); + } + String str = null; + if (has_labels) { + str = this.debug_names.get(value); + } + if (str == null) { + str = (value != null ? value.toString() : "null"); + } + int value_str_len = str.length(); + if (value_str_len > max_length) { + str = str.substring(0, max_length - 3) + "..."; + } + + int cnt = (value != null ? this.histogram.get(value) : 0); + int chars = (int) ((cnt / (double) this.max_count) * max_chars); + s.append(String.format(f, str, cnt)); + for (int i = 0; i < chars; i++) { + s.append(MARKER); + } + first = false; + } + if (this.histogram.isEmpty()) { + s.append(""); + } + return (s.toString()); + } + + // ---------------------------------------------------------------------------- + // SERIALIZATION METHODS + // ---------------------------------------------------------------------------- + + @Override + public void load(String input_path) throws IOException { + JSONUtil.load(this, input_path); + } + + @Override + public void save(String output_path) throws IOException { + JSONUtil.save(this, output_path); + } + + @Override + public String toJSONString() { + return (JSONUtil.toJSONString(this)); + } + + @Override + public void toJSON(JSONStringer stringer) throws JSONException { + Class value_type = null; + for (Members element : Histogram.Members.values()) { + if (element == Histogram.Members.VALUE_TYPE) { + continue; + } + try { + Field field = Histogram.class.getDeclaredField(element.toString().toLowerCase()); + if (element == Members.HISTOGRAM) { + stringer.key(Members.HISTOGRAM.name()).object(); + for (Object value : this.histogram.keySet()) { + if (value != null && value_type == null) { + value_type = value.getClass(); } - - if (cnt >= this.max_count) { - if (cnt > this.max_count) { - this.max_count_values.clear(); - } - this.max_count_values.add(value); - this.max_count = cnt; - } - } - this.dirty = false; - } - - - /** - * Get the number of samples entered into the histogram using the put methods - * - * @return - */ - public int getSampleCount() { - return (this.num_samples); - } - - /** - * Get the number of unique values entered into the histogram - * - * @return - */ - public int getValueCount() { - return (this.histogram.values().size()); - } - - /** - * Get the smallest value entered into the histogram - * This assumes that the values implement the Comparable interface - * - * @return - */ - @SuppressWarnings("unchecked") - public X getMinValue() { - this.calculateInternalValues(); - return ((X) this.min_value); - } - - /** - * Get the largest value entered into the histogram - * This assumes that the values implement the Comparable interface - * - * @return - */ - @SuppressWarnings("unchecked") - public X getMaxValue() { - this.calculateInternalValues(); - return ((X) this.max_value); - } - - /** - * Return the number of samples for the value with the smallest number of samples in the histogram - * - * @return - */ - public int getMinCount() { - this.calculateInternalValues(); - return (this.min_count); - } - - /** - * Return the set values with the smallest number of samples - * - * @return - */ - public Collection getMinCountValues() { - this.calculateInternalValues(); - return (this.min_count_values); - } - - /** - * Return the number of samples for the value with the greatest number of samples in the histogram - * - * @return - */ - public int getMaxCount() { - this.calculateInternalValues(); - return (this.max_count); - } - - /** - * Return the set values with the greatest number of samples - * - * @return - */ - public Collection getMaxCountValues() { - this.calculateInternalValues(); - return (this.max_count_values); - } - - /** - * Return all the values stored in the histogram - * - * @return - */ - public Collection values() { - return (Collections.unmodifiableCollection(this.histogram.keySet())); - } - - /** - * Reset the histogram's internal data - */ - public synchronized void clear() { - this.histogram.clear(); - this.num_samples = 0; - this.min_count = 0; - if (this.min_count_values != null) { - this.min_count_values.clear(); - } - this.min_value = null; - this.max_count = 0; - if (this.max_count_values != null) { - this.max_count_values.clear(); - } - this.max_value = null; - - this.dirty = true; - } - - /** - * Clear all the values stored in the histogram. The keys are only kept if - * KeepZeroEntries is enabled, otherwise it does the same thing as clear() - */ - public synchronized void clearValues() { - if (this.keep_zero_entries) { - for (Entry e : this.histogram.entrySet()) { - this.histogram.put(e.getKey(), 0); - } // FOR - this.num_samples = 0; - this.min_count = 0; - if (this.min_count_values != null) this.min_count_values.clear(); - this.min_value = null; - this.max_count = 0; - if (this.max_count_values != null) this.max_count_values.clear(); - this.max_value = null; + stringer.key(value.toString()).value(this.histogram.get(value)); + } + stringer.endObject(); + } else if (element == Members.KEEP_ZERO_ENTRIES) { + if (this.keep_zero_entries) { + stringer.key(element.name()).value(this.keep_zero_entries); + } } else { - this.clear(); - } - this.dirty = true; - } - - /** - * @return - */ - public boolean isEmpty() { - return (this.histogram.isEmpty()); - } - - /** - * Increments the number of occurrences of this particular value i - * - * @param value the value to be added to the histogram - */ - public synchronized void put(X value, int i) { - this._put(value, i); - } - - /** - * Set the number of occurrences of this particular value i - * - * @param value the value to be added to the histogram - */ - public synchronized void set(X value, int i) { - Integer orig = this.get(value); - if (orig != null && orig != i) { - i = (orig > i ? -1 * (orig - i) : i - orig); + stringer.key(element.name()).value(field.get(this)); } - this._put(value, i); - } - - /** - * Increments the number of occurrences of this particular value i - * - * @param value the value to be added to the histogram - */ - public synchronized void put(X value) { - this._put(value, 1); - } - - /** - * Increment all values in the histogram by one - */ - public void putAll() { - this.putAll(this.histogram.keySet(), 1); - } - - /** - * Increment multiple values by one - * - * @param values - */ - public void putAll(Collection values) { - this.putAll(values, 1); - } - - /** - * Increment multiple values by the given count - * - * @param values - * @param count - */ - public synchronized void putAll(Collection values, int count) { - for (X v : values) { - this._put(v, count); - } - } - - /** - * Add all the entries from the provided Histogram into this objects totals - * - * @param other - */ - public synchronized void putHistogram(Histogram other) { - for (Entry e : other.histogram.entrySet()) { - if (e.getValue() > 0) { - this._put(e.getKey(), e.getValue()); - } - } - } - - /** - * Remove the entire count for the given value - * - * @param value - */ - public synchronized void removeAll(X value) { - Integer cnt = this.histogram.get(value); - if (cnt != null && cnt > 0) { - this._put(value, cnt * -1); - } - } - - /** - * Returns the current count for the given value - * If the value was never entered into the histogram, then the count will be null - * - * @param value - * @return - */ - public Integer get(X value) { - return (histogram.get(value)); - } - - /** - * Returns the current count for the given value. - * If that value was nevered entered in the histogram, then the value returned will be value_if_null - * - * @param value - * @param value_if_null - * @return - */ - public int get(X value, int value_if_null) { - Integer count = histogram.get(value); - return (count == null ? value_if_null : count); - } - - /** - * Returns true if this histogram contains the specified key. - * - * @param value - * @return - */ - public boolean contains(X value) { - return (this.histogram.containsKey(value)); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Histogram histogram1 = (Histogram) o; - return Objects.equals(histogram, histogram1.histogram); - } - - @Override - public int hashCode() { - return Objects.hash(histogram); - } - - // ---------------------------------------------------------------------------- - // DEBUG METHODS - // ---------------------------------------------------------------------------- - - /** - * Histogram Pretty Print - */ - public String toString() { - return (this.toString(MAX_CHARS, MAX_VALUE_LENGTH)); - } - - /** - * Histogram Pretty Print - * - * @param max_chars - * @param max_length - * @return - */ - public synchronized String toString(Integer max_chars, Integer max_length) { - StringBuilder s = new StringBuilder(); - if (max_length == null) { - max_length = MAX_VALUE_LENGTH; - } - - this.calculateInternalValues(); - - // Figure out the max size of the counts - int max_ctr_length = 4; - for (Integer ctr : this.histogram.values()) { - max_ctr_length = Math.max(max_ctr_length, ctr.toString().length()); - } - - // Don't let anything go longer than MAX_VALUE_LENGTH chars - String f = "%-" + max_length + "s [%" + max_ctr_length + "d] "; - boolean first = true; - boolean has_labels = this.hasDebugLabels(); - for (Object value : this.histogram.keySet()) { - if (!first) { - s.append("\n"); - } - String str = null; - if (has_labels) { - str = this.debug_names.get(value); - } - if (str == null) { - str = (value != null ? value.toString() : "null"); - } - int value_str_len = str.length(); - if (value_str_len > max_length) { - str = str.substring(0, max_length - 3) + "..."; - } - - int cnt = (value != null ? this.histogram.get(value) : 0); - int chars = (int) ((cnt / (double) this.max_count) * max_chars); - s.append(String.format(f, str, cnt)); - for (int i = 0; i < chars; i++) { - s.append(MARKER); - } - first = false; - } - if (this.histogram.isEmpty()) { - s.append(""); - } - return (s.toString()); - } - - // ---------------------------------------------------------------------------- - // SERIALIZATION METHODS - // ---------------------------------------------------------------------------- - - @Override - public void load(String input_path) throws IOException { - JSONUtil.load(this, input_path); - } - - @Override - public void save(String output_path) throws IOException { - JSONUtil.save(this, output_path); - } - - @Override - public String toJSONString() { - return (JSONUtil.toJSONString(this)); - } - - @Override - public void toJSON(JSONStringer stringer) throws JSONException { - Class value_type = null; - for (Members element : Histogram.Members.values()) { - if (element == Histogram.Members.VALUE_TYPE) { - continue; - } - try { - Field field = Histogram.class.getDeclaredField(element.toString().toLowerCase()); - if (element == Members.HISTOGRAM) { - stringer.key(Members.HISTOGRAM.name()).object(); - for (Object value : this.histogram.keySet()) { - if (value != null && value_type == null) { - value_type = value.getClass(); - } - stringer.key(value.toString()).value(this.histogram.get(value)); - } - stringer.endObject(); - } else if (element == Members.KEEP_ZERO_ENTRIES) { - if (this.keep_zero_entries) { - stringer.key(element.name()).value(this.keep_zero_entries); - } - } else { - stringer.key(element.name()).value(field.get(this)); - } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - System.exit(1); - } - } - if (value_type != null) { - stringer.key(Histogram.Members.VALUE_TYPE.name()).value(value_type.getCanonicalName()); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + System.exit(1); + } + } + if (value_type != null) { + stringer.key(Histogram.Members.VALUE_TYPE.name()).value(value_type.getCanonicalName()); + } + } + + @Override + @SuppressWarnings("unchecked") + public void fromJSON(JSONObject object) throws JSONException { + if (object.has(Members.KEEP_ZERO_ENTRIES.name())) { + this.setKeepZeroEntries(object.getBoolean(Members.KEEP_ZERO_ENTRIES.name())); + } + Class value_type = null; + if (object.has(Members.VALUE_TYPE.name())) { + String className = object.getString(Members.VALUE_TYPE.name()); + value_type = ClassUtil.getClass(className); + } + + // This code sucks ass... + for (Members element : Histogram.Members.values()) { + if (element == Members.KEEP_ZERO_ENTRIES || element == Members.VALUE_TYPE) { + continue; + } + try { + String field_name = element.toString().toLowerCase(); + Field field = Histogram.class.getDeclaredField(field_name); + if (element == Members.HISTOGRAM) { + JSONObject jsonObject = object.getJSONObject(Members.HISTOGRAM.name()); + Iterator keys = jsonObject.keys(); + while (keys.hasNext()) { + String key_name = keys.next(); + + X key_value = (X) JSONUtil.getPrimitiveValue(key_name, value_type); + int count = jsonObject.getInt(key_name); + this.histogram.put(key_value, count); + } + } else { + field.set(this, object.getInt(element.name())); } + } catch (Exception e) { + LOG.error(e.getMessage(), e); + System.exit(1); + } } - @Override - @SuppressWarnings("unchecked") - public void fromJSON(JSONObject object) throws JSONException { - if (object.has(Members.KEEP_ZERO_ENTRIES.name())) { - this.setKeepZeroEntries(object.getBoolean(Members.KEEP_ZERO_ENTRIES.name())); - } - Class value_type = null; - if (object.has(Members.VALUE_TYPE.name())) { - String className = object.getString(Members.VALUE_TYPE.name()); - value_type = ClassUtil.getClass(className); - - } - - // This code sucks ass... - for (Members element : Histogram.Members.values()) { - if (element == Members.KEEP_ZERO_ENTRIES || element == Members.VALUE_TYPE) { - continue; - } - try { - String field_name = element.toString().toLowerCase(); - Field field = Histogram.class.getDeclaredField(field_name); - if (element == Members.HISTOGRAM) { - JSONObject jsonObject = object.getJSONObject(Members.HISTOGRAM.name()); - Iterator keys = jsonObject.keys(); - while (keys.hasNext()) { - String key_name = keys.next(); - - X key_value = (X) JSONUtil.getPrimitiveValue(key_name, value_type); - int count = jsonObject.getInt(key_name); - this.histogram.put(key_value, count); - } - } else { - field.set(this, object.getInt(element.name())); - } - } catch (Exception e) { - LOG.error(e.getMessage(), e); - System.exit(1); - } - } - - this.dirty = true; - this.calculateInternalValues(); - } + this.dirty = true; + this.calculateInternalValues(); + } } diff --git a/src/main/java/com/oltpbenchmark/util/JSONSerializable.java b/src/main/java/com/oltpbenchmark/util/JSONSerializable.java index 332208d4f..048935495 100644 --- a/src/main/java/com/oltpbenchmark/util/JSONSerializable.java +++ b/src/main/java/com/oltpbenchmark/util/JSONSerializable.java @@ -17,20 +17,19 @@ package com.oltpbenchmark.util; +import java.io.IOException; +import java.io.Serializable; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONString; import org.json.JSONStringer; -import java.io.IOException; -import java.io.Serializable; - public interface JSONSerializable extends JSONString, Serializable { - void save(String output_path) throws IOException; + void save(String output_path) throws IOException; - void load(String input_path) throws IOException; + void load(String input_path) throws IOException; - void toJSON(JSONStringer stringer) throws JSONException; + void toJSON(JSONStringer stringer) throws JSONException; - void fromJSON(JSONObject json_object) throws JSONException; + void fromJSON(JSONObject json_object) throws JSONException; } diff --git a/src/main/java/com/oltpbenchmark/util/JSONUtil.java b/src/main/java/com/oltpbenchmark/util/JSONUtil.java index ae6619c79..7ce5470bb 100644 --- a/src/main/java/com/oltpbenchmark/util/JSONUtil.java +++ b/src/main/java/com/oltpbenchmark/util/JSONUtil.java @@ -17,15 +17,6 @@ package com.oltpbenchmark.util; - -import org.apache.commons.io.IOUtils; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONStringer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -34,585 +25,621 @@ import java.nio.charset.Charset; import java.util.*; import java.util.Map.Entry; +import org.apache.commons.io.IOUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONStringer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author pavlo */ public abstract class JSONUtil { - private static final Logger LOG = LoggerFactory.getLogger(JSONUtil.class.getName()); - - private static final String JSON_CLASS_SUFFIX = "_class"; - private static final Map, Field[]> SERIALIZABLE_FIELDS = new HashMap<>(); - - /** - * @param clazz - * @return - */ - public static Field[] getSerializableFields(Class clazz, String... fieldsToExclude) { - Field[] ret = SERIALIZABLE_FIELDS.get(clazz); + private static final Logger LOG = LoggerFactory.getLogger(JSONUtil.class.getName()); + + private static final String JSON_CLASS_SUFFIX = "_class"; + private static final Map, Field[]> SERIALIZABLE_FIELDS = new HashMap<>(); + + /** + * @param clazz + * @return + */ + public static Field[] getSerializableFields(Class clazz, String... fieldsToExclude) { + Field[] ret = SERIALIZABLE_FIELDS.get(clazz); + if (ret == null) { + Collection exclude = CollectionUtil.addAll(new HashSet<>(), fieldsToExclude); + synchronized (SERIALIZABLE_FIELDS) { + ret = SERIALIZABLE_FIELDS.get(clazz); if (ret == null) { - Collection exclude = CollectionUtil.addAll(new HashSet<>(), fieldsToExclude); - synchronized (SERIALIZABLE_FIELDS) { - ret = SERIALIZABLE_FIELDS.get(clazz); - if (ret == null) { - List fields = new ArrayList<>(); - for (Field f : clazz.getFields()) { - int modifiers = f.getModifiers(); - if (!Modifier.isTransient(modifiers) && - Modifier.isPublic(modifiers) && - !Modifier.isStatic(modifiers) && - !exclude.contains(f.getName())) { - fields.add(f); - } - } - ret = fields.toArray(new Field[0]); - SERIALIZABLE_FIELDS.put(clazz, ret); - } + List fields = new ArrayList<>(); + for (Field f : clazz.getFields()) { + int modifiers = f.getModifiers(); + if (!Modifier.isTransient(modifiers) + && Modifier.isPublic(modifiers) + && !Modifier.isStatic(modifiers) + && !exclude.contains(f.getName())) { + fields.add(f); } + } + ret = fields.toArray(new Field[0]); + SERIALIZABLE_FIELDS.put(clazz, ret); } - return (ret); + } } - - /** - * JSON Pretty Print - * - * @param json - * @return - * @throws JSONException - */ - public static String format(String json) { - try { - return (JSONUtil.format(new JSONObject(json){ - /** - * changes the value of JSONObject.map to a LinkedHashMap in order to maintain - * order of keys. - * See Also: https://stackoverflow.com/a/62476486 - */ - @Override - public JSONObject put(String key, Object value) throws JSONException { - try { - Field map = JSONObject.class.getDeclaredField("map"); - map.setAccessible(true); - Object mapValue = map.get(this); - if (!(mapValue instanceof LinkedHashMap)) { - map.set(this, new LinkedHashMap<>()); - } - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new RuntimeException(e); - } - return super.put(key, value); + return (ret); + } + + /** + * JSON Pretty Print + * + * @param json + * @return + * @throws JSONException + */ + public static String format(String json) { + try { + return (JSONUtil.format( + new JSONObject(json) { + /** + * changes the value of JSONObject.map to a LinkedHashMap in order to maintain order of + * keys. See Also: https://stackoverflow.com/a/62476486 + */ + @Override + public JSONObject put(String key, Object value) throws JSONException { + try { + Field map = JSONObject.class.getDeclaredField("map"); + map.setAccessible(true); + Object mapValue = map.get(this); + if (!(mapValue instanceof LinkedHashMap)) { + map.set(this, new LinkedHashMap<>()); } - })); - } catch (RuntimeException ex) { - throw ex; - } catch (Exception ex) { - throw new RuntimeException(ex); - } + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + return super.put(key, value); + } + })); + } catch (RuntimeException ex) { + throw ex; + } catch (Exception ex) { + throw new RuntimeException(ex); } + } - public static String format(JSONObject o) { - try { - return o.toString(1); - } catch (JSONException ex) { - throw new RuntimeException(ex); - } + public static String format(JSONObject o) { + try { + return o.toString(1); + } catch (JSONException ex) { + throw new RuntimeException(ex); } - - /** - * @param object - * @return - */ - public static String toJSONString(Object object) { - JSONStringer stringer = new JSONStringer(); - try { - if (object instanceof JSONSerializable) { - stringer.object(); - ((JSONSerializable) object).toJSON(stringer); - stringer.endObject(); - } else if (object != null) { - Class clazz = object.getClass(); -// stringer.key(clazz.getSimpleName()); - JSONUtil.writeFieldValue(stringer, clazz, object); - } - } catch (JSONException e) { - throw new RuntimeException(e); - } - return (stringer.toString()); + } + + /** + * @param object + * @return + */ + public static String toJSONString(Object object) { + JSONStringer stringer = new JSONStringer(); + try { + if (object instanceof JSONSerializable) { + stringer.object(); + ((JSONSerializable) object).toJSON(stringer); + stringer.endObject(); + } else if (object != null) { + Class clazz = object.getClass(); + // stringer.key(clazz.getSimpleName()); + JSONUtil.writeFieldValue(stringer, clazz, object); + } + } catch (JSONException e) { + throw new RuntimeException(e); } - - public static T fromJSONString(T t, String json) { - try { - JSONObject json_object = new JSONObject(json); - t.fromJSON(json_object); - } catch (JSONException ex) { - throw new RuntimeException("Failed to deserialize object " + t, ex); - } - return (t); + return (stringer.toString()); + } + + public static T fromJSONString(T t, String json) { + try { + JSONObject json_object = new JSONObject(json); + t.fromJSON(json_object); + } catch (JSONException ex) { + throw new RuntimeException("Failed to deserialize object " + t, ex); } - - /** - * Write the contents of a JSONSerializable object out to a file on the local disk - * - * @param - * @param object - * @param output_path - * @throws IOException - */ - public static void save(T object, String output_path) throws IOException { - if (LOG.isDebugEnabled()) { - LOG.debug("Writing out contents of {} to '{}'", object.getClass().getSimpleName(), output_path); - } - File f = new File(output_path); - try { - FileUtil.makeDirIfNotExists(f.getParent()); - String json = object.toJSONString(); - FileUtil.writeStringToFile(f, format(json)); - } catch (Exception ex) { - LOG.error("Failed to serialize the {} file '{}'", object.getClass().getSimpleName(), f, ex); - throw new IOException(ex); - } + return (t); + } + + /** + * Write the contents of a JSONSerializable object out to a file on the local disk + * + * @param + * @param object + * @param output_path + * @throws IOException + */ + public static void save(T object, String output_path) + throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug( + "Writing out contents of {} to '{}'", object.getClass().getSimpleName(), output_path); } - - /** - * Load in a JSONSerialable stored in a file - * - * @param object - * @param input_path - * @throws Exception - */ - public static void load(T object, String input_path) throws IOException { - if (LOG.isDebugEnabled()) { - LOG.debug("Loading in serialized {} from '{}'", object.getClass().getSimpleName(), input_path); - } - - String contents; - - try (InputStream in = JSONUtil.class.getResourceAsStream(input_path)) { - contents = IOUtils.toString(in, Charset.defaultCharset()); - } - - try { - object.fromJSON(new JSONObject(contents)); - } catch (Exception ex) { - LOG.error("Failed to deserialize the {} from file '{}'", object.getClass().getSimpleName(), input_path, ex); - throw new IOException(ex); - } - - if (LOG.isDebugEnabled()) { - LOG.debug("The loading of the {} is complete", object.getClass().getSimpleName()); - } + File f = new File(output_path); + try { + FileUtil.makeDirIfNotExists(f.getParent()); + String json = object.toJSONString(); + FileUtil.writeStringToFile(f, format(json)); + } catch (Exception ex) { + LOG.error("Failed to serialize the {} file '{}'", object.getClass().getSimpleName(), f, ex); + throw new IOException(ex); } - - /** - * For a given list of Fields, write out the contents of the corresponding field to the JSONObject - * The each of the JSONObject's elements will be the upper case version of the Field's name - * - * @param - * @param stringer - * @param object - * @param base_class - * @param fields - * @throws JSONException - */ - public static void fieldsToJSON(JSONStringer stringer, T object, Class base_class, Field[] fields) throws JSONException { - if (LOG.isDebugEnabled()) { - LOG.debug("Serializing out {} elements for {}", fields.length, base_class.getSimpleName()); - } - for (Field f : fields) { - String json_key = f.getName().toUpperCase(); - stringer.key(json_key); - - try { - Class f_class = f.getType(); - Object f_value = f.get(object); - - // Null - if (f_value == null) { - writeFieldValue(stringer, f_class, f_value); - // Maps - } else if (f_value instanceof Map) { - writeFieldValue(stringer, f_class, f_value); - // Everything else - } else { - writeFieldValue(stringer, f_class, f_value); - } - } catch (Exception ex) { - throw new JSONException(ex); - } - } + } + + /** + * Load in a JSONSerialable stored in a file + * + * @param object + * @param input_path + * @throws Exception + */ + public static void load(T object, String input_path) + throws IOException { + if (LOG.isDebugEnabled()) { + LOG.debug( + "Loading in serialized {} from '{}'", object.getClass().getSimpleName(), input_path); } - /** - * @param stringer - * @param field_class - * @param field_value - * @throws JSONException - */ - public static void writeFieldValue(JSONStringer stringer, Class field_class, Object field_value) throws JSONException { - // Null - if (field_value == null) { - if (LOG.isDebugEnabled()) { - LOG.debug("writeNullFieldValue({}, {})", field_class, field_value); - } - stringer.value(null); - - // Collections - } else if (ClassUtil.getInterfaces(field_class).contains(Collection.class)) { - if (LOG.isDebugEnabled()) { - LOG.debug("writeCollectionFieldValue({}, {})", field_class, field_value); - } - stringer.array(); - for (Object value : (Collection) field_value) { - if (value == null) { - stringer.value(null); - } else { - writeFieldValue(stringer, value.getClass(), value); - } - } - stringer.endArray(); - - // Maps - } else if (field_value instanceof Map) { - if (LOG.isDebugEnabled()) { - LOG.debug("writeMapFieldValue({}, {})", field_class, field_value); - } - stringer.object(); - for (Entry e : ((Map) field_value).entrySet()) { - // We can handle null keys - String key_value = null; - if (e.getKey() != null) { - // deserialize it on the other side - Class key_class = e.getKey().getClass(); - key_value = makePrimitiveValue(key_class, e.getKey()).toString(); - } - stringer.key(key_value); - - // We can also handle null values. Where is your god now??? - if (e.getValue() == null) { - stringer.value(null); - } else { - writeFieldValue(stringer, e.getValue().getClass(), e.getValue()); - } - } - stringer.endObject(); + String contents; - // Primitive - } else { - if (LOG.isDebugEnabled()) { - LOG.debug("writePrimitiveFieldValue({}, {})", field_class, field_value); - } - stringer.value(makePrimitiveValue(field_class, field_value)); - } + try (InputStream in = JSONUtil.class.getResourceAsStream(input_path)) { + contents = IOUtils.toString(in, Charset.defaultCharset()); } - /** - * Read data from the given JSONObject and populate the given Map - * - * @param json_object - * @param map - * @param inner_classes - * @throws Exception - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - protected static void readMapField(final JSONObject json_object, final Map map, final Stack inner_classes) throws Exception { - Class key_class = inner_classes.pop(); - Class val_class = inner_classes.pop(); - Collection> val_interfaces = ClassUtil.getInterfaces(val_class); - - - for (String json_key : CollectionUtil.iterable(json_object.keys())) { - final Stack next_inner_classes = new Stack<>(); - next_inner_classes.addAll(inner_classes); - - - // KEY - Object key = JSONUtil.getPrimitiveValue(json_key, key_class); - - // VALUE - Object object = null; - if (json_object.isNull(json_key)) { - // Nothing... - } else if (val_interfaces.contains(List.class)) { - object = new ArrayList(); - readCollectionField(json_object.getJSONArray(json_key), (Collection) object, next_inner_classes); - } else if (val_interfaces.contains(Set.class)) { - object = new HashSet(); - readCollectionField(json_object.getJSONArray(json_key), (Collection) object, next_inner_classes); - } else if (val_interfaces.contains(Map.class)) { - object = new HashMap(); - readMapField(json_object.getJSONObject(json_key), (Map) object, next_inner_classes); - } else { - String json_string = json_object.getString(json_key); - - object = JSONUtil.getPrimitiveValue(json_string, val_class); - - } - map.put(key, object); - } + try { + object.fromJSON(new JSONObject(contents)); + } catch (Exception ex) { + LOG.error( + "Failed to deserialize the {} from file '{}'", + object.getClass().getSimpleName(), + input_path, + ex); + throw new IOException(ex); } - /** - * Read data from the given JSONArray and populate the given Collection - * - * @param json_array - * @param collection - * @param inner_classes - * @throws Exception - */ - @SuppressWarnings({"unchecked", "rawtypes"}) - protected static void readCollectionField(final JSONArray json_array, final Collection collection, final Stack inner_classes) throws Exception { - // We need to figure out what the inner type of the collection is - // If it's a Collection or a Map, then we need to instantiate it before - // we can call readFieldValue() again for it. - Class inner_class = inner_classes.pop(); - Collection> inner_interfaces = ClassUtil.getInterfaces(inner_class); - - for (int i = 0, cnt = json_array.length(); i < cnt; i++) { - final Stack next_inner_classes = new Stack<>(); - next_inner_classes.addAll(inner_classes); - - Object value = null; - - // Null - if (json_array.isNull(i)) { - value = null; - // Lists - } else if (inner_interfaces.contains(List.class)) { - value = new ArrayList(); - readCollectionField(json_array.getJSONArray(i), (Collection) value, next_inner_classes); - // Sets - } else if (inner_interfaces.contains(Set.class)) { - value = new HashSet(); - readCollectionField(json_array.getJSONArray(i), (Collection) value, next_inner_classes); - // Maps - } else if (inner_interfaces.contains(Map.class)) { - value = new HashMap(); - readMapField(json_array.getJSONObject(i), (Map) value, next_inner_classes); - // Values - } else { - String json_string = json_array.getString(i); - value = JSONUtil.getPrimitiveValue(json_string, inner_class); - } - collection.add(value); - } + if (LOG.isDebugEnabled()) { + LOG.debug("The loading of the {} is complete", object.getClass().getSimpleName()); } + } + + /** + * For a given list of Fields, write out the contents of the corresponding field to the JSONObject + * The each of the JSONObject's elements will be the upper case version of the Field's name + * + * @param + * @param stringer + * @param object + * @param base_class + * @param fields + * @throws JSONException + */ + public static void fieldsToJSON( + JSONStringer stringer, T object, Class base_class, Field[] fields) + throws JSONException { + if (LOG.isDebugEnabled()) { + LOG.debug("Serializing out {} elements for {}", fields.length, base_class.getSimpleName()); + } + for (Field f : fields) { + String json_key = f.getName().toUpperCase(); + stringer.key(json_key); - /** - * @param json_object - * @param json_key - * @param field_handle - * @param object - * @throws Exception - */ - @SuppressWarnings("rawtypes") - public static void readFieldValue(final JSONObject json_object, final String json_key, Field field_handle, Object object) throws Exception { - - Class field_class = field_handle.getType(); - Object field_object = field_handle.get(object); - // String field_name = field_handle.getName(); + try { + Class f_class = f.getType(); + Object f_value = f.get(object); // Null - if (json_object.isNull(json_key)) { - if (LOG.isDebugEnabled()) { - LOG.debug("Field {} is null", json_key); - } - field_handle.set(object, null); - - // Collections - } else if (ClassUtil.getInterfaces(field_class).contains(Collection.class)) { - if (LOG.isDebugEnabled()) { - LOG.debug("Field {} is a collection", json_key); - } - - Stack inner_classes = new Stack<>(); - inner_classes.addAll(ClassUtil.getGenericTypes(field_handle)); - Collections.reverse(inner_classes); - - JSONArray json_inner = json_object.getJSONArray(json_key); - if (json_inner == null) { - throw new JSONException("No array exists for '" + json_key + "'"); - } - readCollectionField(json_inner, (Collection) field_object, inner_classes); - - // Maps - } else if (field_object instanceof Map) { - if (LOG.isDebugEnabled()) { - LOG.debug("Field {} is a map", json_key); - } - - Stack inner_classes = new Stack<>(); - inner_classes.addAll(ClassUtil.getGenericTypes(field_handle)); - Collections.reverse(inner_classes); - - JSONObject json_inner = json_object.getJSONObject(json_key); - if (json_inner == null) { - throw new JSONException("No object exists for '" + json_key + "'"); - } - readMapField(json_inner, (Map) field_object, inner_classes); - - // Everything else... + if (f_value == null) { + writeFieldValue(stringer, f_class, f_value); + // Maps + } else if (f_value instanceof Map) { + writeFieldValue(stringer, f_class, f_value); + // Everything else } else { - Class explicit_field_class = JSONUtil.getClassForField(json_object, json_key); - if (explicit_field_class != null) { - field_class = explicit_field_class; - if (LOG.isDebugEnabled()) { - LOG.debug("Found explict field class {} for {}", field_class.getSimpleName(), json_key); - } - } - if (LOG.isDebugEnabled()) { - LOG.debug("Field {} is primitive type {}", json_key, field_class.getSimpleName()); - } - Object value = JSONUtil.getPrimitiveValue(json_object.getString(json_key), field_class); - field_handle.set(object, value); - if (LOG.isDebugEnabled()) { - LOG.debug("Set field {} to '{}'", json_key, value); - } + writeFieldValue(stringer, f_class, f_value); } + } catch (Exception ex) { + throw new JSONException(ex); + } } + } + + /** + * @param stringer + * @param field_class + * @param field_value + * @throws JSONException + */ + public static void writeFieldValue( + JSONStringer stringer, Class field_class, Object field_value) throws JSONException { + // Null + if (field_value == null) { + if (LOG.isDebugEnabled()) { + LOG.debug("writeNullFieldValue({}, {})", field_class, field_value); + } + stringer.value(null); + + // Collections + } else if (ClassUtil.getInterfaces(field_class).contains(Collection.class)) { + if (LOG.isDebugEnabled()) { + LOG.debug("writeCollectionFieldValue({}, {})", field_class, field_value); + } + stringer.array(); + for (Object value : (Collection) field_value) { + if (value == null) { + stringer.value(null); + } else { + writeFieldValue(stringer, value.getClass(), value); + } + } + stringer.endArray(); + + // Maps + } else if (field_value instanceof Map) { + if (LOG.isDebugEnabled()) { + LOG.debug("writeMapFieldValue({}, {})", field_class, field_value); + } + stringer.object(); + for (Entry e : ((Map) field_value).entrySet()) { + // We can handle null keys + String key_value = null; + if (e.getKey() != null) { + // deserialize it on the other side + Class key_class = e.getKey().getClass(); + key_value = makePrimitiveValue(key_class, e.getKey()).toString(); + } + stringer.key(key_value); - /** - * For the given list of Fields, load in the values from the JSON object into the current object - * If ignore_missing is false, then JSONUtil will not throw an error if a field is missing - * - * @param - * @param - * @param json_object - * @param object - * @param base_class - * @param ignore_missing - * @param fields - * @throws JSONException - */ - public static , T> void fieldsFromJSON(JSONObject json_object, T object, Class base_class, boolean ignore_missing, Field... fields) throws JSONException { - for (Field field_handle : fields) { - String json_key = field_handle.getName().toUpperCase(); - if (LOG.isDebugEnabled()) { - LOG.debug("Retreiving value for field '{}'", json_key); - } - - if (!json_object.has(json_key)) { - String msg = "JSONObject for " + base_class.getSimpleName() + " does not have key '" + json_key + "': " + CollectionUtil.list(json_object.keys()); - if (ignore_missing) { - LOG.warn(msg); - continue; - } else { - throw new JSONException(msg); - } - } - - try { - readFieldValue(json_object, json_key, field_handle, object); - } catch (Exception ex) { - // System.err.println(field_class + ": " + ClassUtil.getSuperClasses(field_class)); - LOG.error("Unable to deserialize field '{}' from {}", json_key, base_class.getSimpleName(), ex); - throw new JSONException(ex); - } + // We can also handle null values. Where is your god now??? + if (e.getValue() == null) { + stringer.value(null); + } else { + writeFieldValue(stringer, e.getValue().getClass(), e.getValue()); } + } + stringer.endObject(); + + // Primitive + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("writePrimitiveFieldValue({}, {})", field_class, field_value); + } + stringer.value(makePrimitiveValue(field_class, field_value)); } - - /** - * Return the class of a field if it was stored in the JSONObject along with the value - * If there is no class information, then this will return null - * - * @param json_object - * @param json_key - * @return - * @throws JSONException - */ - private static Class getClassForField(JSONObject json_object, String json_key) throws JSONException { - Class field_class = null; - // Check whether we also stored the class - if (json_object.has(json_key + JSON_CLASS_SUFFIX)) { - try { - field_class = ClassUtil.getClass(json_object.getString(json_key + JSON_CLASS_SUFFIX)); - } catch (Exception ex) { - LOG.error("Failed to include class for field '{}'", json_key, ex); - throw new JSONException(ex); - } + } + + /** + * Read data from the given JSONObject and populate the given Map + * + * @param json_object + * @param map + * @param inner_classes + * @throws Exception + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + protected static void readMapField( + final JSONObject json_object, final Map map, final Stack inner_classes) + throws Exception { + Class key_class = inner_classes.pop(); + Class val_class = inner_classes.pop(); + Collection> val_interfaces = ClassUtil.getInterfaces(val_class); + + for (String json_key : CollectionUtil.iterable(json_object.keys())) { + final Stack next_inner_classes = new Stack<>(); + next_inner_classes.addAll(inner_classes); + + // KEY + Object key = JSONUtil.getPrimitiveValue(json_key, key_class); + + // VALUE + Object object = null; + if (json_object.isNull(json_key)) { + // Nothing... + } else if (val_interfaces.contains(List.class)) { + object = new ArrayList(); + readCollectionField( + json_object.getJSONArray(json_key), (Collection) object, next_inner_classes); + } else if (val_interfaces.contains(Set.class)) { + object = new HashSet(); + readCollectionField( + json_object.getJSONArray(json_key), (Collection) object, next_inner_classes); + } else if (val_interfaces.contains(Map.class)) { + object = new HashMap(); + readMapField(json_object.getJSONObject(json_key), (Map) object, next_inner_classes); + } else { + String json_string = json_object.getString(json_key); + + object = JSONUtil.getPrimitiveValue(json_string, val_class); + } + map.put(key, object); + } + } + + /** + * Read data from the given JSONArray and populate the given Collection + * + * @param json_array + * @param collection + * @param inner_classes + * @throws Exception + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + protected static void readCollectionField( + final JSONArray json_array, final Collection collection, final Stack inner_classes) + throws Exception { + // We need to figure out what the inner type of the collection is + // If it's a Collection or a Map, then we need to instantiate it before + // we can call readFieldValue() again for it. + Class inner_class = inner_classes.pop(); + Collection> inner_interfaces = ClassUtil.getInterfaces(inner_class); + + for (int i = 0, cnt = json_array.length(); i < cnt; i++) { + final Stack next_inner_classes = new Stack<>(); + next_inner_classes.addAll(inner_classes); + + Object value = null; + + // Null + if (json_array.isNull(i)) { + value = null; + // Lists + } else if (inner_interfaces.contains(List.class)) { + value = new ArrayList(); + readCollectionField(json_array.getJSONArray(i), (Collection) value, next_inner_classes); + // Sets + } else if (inner_interfaces.contains(Set.class)) { + value = new HashSet(); + readCollectionField(json_array.getJSONArray(i), (Collection) value, next_inner_classes); + // Maps + } else if (inner_interfaces.contains(Map.class)) { + value = new HashMap(); + readMapField(json_array.getJSONObject(i), (Map) value, next_inner_classes); + // Values + } else { + String json_string = json_array.getString(i); + value = JSONUtil.getPrimitiveValue(json_string, inner_class); + } + collection.add(value); + } + } + + /** + * @param json_object + * @param json_key + * @param field_handle + * @param object + * @throws Exception + */ + @SuppressWarnings("rawtypes") + public static void readFieldValue( + final JSONObject json_object, final String json_key, Field field_handle, Object object) + throws Exception { + + Class field_class = field_handle.getType(); + Object field_object = field_handle.get(object); + // String field_name = field_handle.getName(); + + // Null + if (json_object.isNull(json_key)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Field {} is null", json_key); + } + field_handle.set(object, null); + + // Collections + } else if (ClassUtil.getInterfaces(field_class).contains(Collection.class)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Field {} is a collection", json_key); + } + + Stack inner_classes = new Stack<>(); + inner_classes.addAll(ClassUtil.getGenericTypes(field_handle)); + Collections.reverse(inner_classes); + + JSONArray json_inner = json_object.getJSONArray(json_key); + if (json_inner == null) { + throw new JSONException("No array exists for '" + json_key + "'"); + } + readCollectionField(json_inner, (Collection) field_object, inner_classes); + + // Maps + } else if (field_object instanceof Map) { + if (LOG.isDebugEnabled()) { + LOG.debug("Field {} is a map", json_key); + } + + Stack inner_classes = new Stack<>(); + inner_classes.addAll(ClassUtil.getGenericTypes(field_handle)); + Collections.reverse(inner_classes); + + JSONObject json_inner = json_object.getJSONObject(json_key); + if (json_inner == null) { + throw new JSONException("No object exists for '" + json_key + "'"); + } + readMapField(json_inner, (Map) field_object, inner_classes); + + // Everything else... + } else { + Class explicit_field_class = JSONUtil.getClassForField(json_object, json_key); + if (explicit_field_class != null) { + field_class = explicit_field_class; + if (LOG.isDebugEnabled()) { + LOG.debug("Found explict field class {} for {}", field_class.getSimpleName(), json_key); } - return (field_class); - + } + if (LOG.isDebugEnabled()) { + LOG.debug("Field {} is primitive type {}", json_key, field_class.getSimpleName()); + } + Object value = JSONUtil.getPrimitiveValue(json_object.getString(json_key), field_class); + field_handle.set(object, value); + if (LOG.isDebugEnabled()) { + LOG.debug("Set field {} to '{}'", json_key, value); + } } - - /** - * Return the proper serialization string for the given value - * - * @param field_class - * @param field_value - * @return - */ - private static Object makePrimitiveValue(Class field_class, Object field_value) { - Object value = null; - - - if (field_class.equals(Class.class)) { - value = ((Class) field_value).getName(); - // JSONSerializable - } else if (ClassUtil.getInterfaces(field_class).contains(JSONSerializable.class)) { - // Just return the value back. The JSON library will take care of it -// System.err.println(field_class + ": " + field_value); - value = field_value; - // Everything else + } + + /** + * For the given list of Fields, load in the values from the JSON object into the current object + * If ignore_missing is false, then JSONUtil will not throw an error if a field is missing + * + * @param + * @param + * @param json_object + * @param object + * @param base_class + * @param ignore_missing + * @param fields + * @throws JSONException + */ + public static , T> void fieldsFromJSON( + JSONObject json_object, + T object, + Class base_class, + boolean ignore_missing, + Field... fields) + throws JSONException { + for (Field field_handle : fields) { + String json_key = field_handle.getName().toUpperCase(); + if (LOG.isDebugEnabled()) { + LOG.debug("Retreiving value for field '{}'", json_key); + } + + if (!json_object.has(json_key)) { + String msg = + "JSONObject for " + + base_class.getSimpleName() + + " does not have key '" + + json_key + + "': " + + CollectionUtil.list(json_object.keys()); + if (ignore_missing) { + LOG.warn(msg); + continue; } else { - value = field_value; // .toString(); + throw new JSONException(msg); } - return (value); + } + + try { + readFieldValue(json_object, json_key, field_handle, object); + } catch (Exception ex) { + // System.err.println(field_class + ": " + ClassUtil.getSuperClasses(field_class)); + LOG.error( + "Unable to deserialize field '{}' from {}", json_key, base_class.getSimpleName(), ex); + throw new JSONException(ex); + } } - - - /** - * For the given JSON string, figure out what kind of object it is and return it - * - * @param json_value - * @param field_class - * @return - */ - public static Object getPrimitiveValue(String json_value, Class field_class) { - Object value = null; - - - if (field_class.equals(Class.class)) { - value = ClassUtil.getClass(json_value); - if (value == null) { - throw new JSONException("Failed to get class from '" + json_value + "'"); - } - // Enum - } else if (field_class.isEnum()) { - for (Object o : field_class.getEnumConstants()) { - Enum e = (Enum) o; - if (json_value.equals(e.name())) { - return (e); - } - } - throw new JSONException("Invalid enum value '" + json_value + "': " + Arrays.toString(field_class.getEnumConstants())); - // JSONSerializable - } else if (ClassUtil.getInterfaces(field_class).contains(JSONSerializable.class)) { - value = ClassUtil.newInstance(field_class, null, null); - ((JSONSerializable) value).fromJSON(new JSONObject(json_value)); - // Boolean - } else if (field_class.equals(Boolean.class) || field_class.equals(boolean.class)) { - // We have to use field_class.equals() because the value may be null - value = Boolean.parseBoolean(json_value); - // Short - } else if (field_class.equals(Short.class) || field_class.equals(short.class)) { - value = Short.parseShort(json_value); - // Integer - } else if (field_class.equals(Integer.class) || field_class.equals(int.class)) { - value = Integer.parseInt(json_value); - // Long - } else if (field_class.equals(Long.class) || field_class.equals(long.class)) { - value = Long.parseLong(json_value); - // Float - } else if (field_class.equals(Float.class) || field_class.equals(float.class)) { - value = Float.parseFloat(json_value); - // Double - } else if (field_class.equals(Double.class) || field_class.equals(double.class)) { - value = Double.parseDouble(json_value); - // String - } else if (field_class.equals(String.class)) { - value = json_value; + } + + /** + * Return the class of a field if it was stored in the JSONObject along with the value If there is + * no class information, then this will return null + * + * @param json_object + * @param json_key + * @return + * @throws JSONException + */ + private static Class getClassForField(JSONObject json_object, String json_key) + throws JSONException { + Class field_class = null; + // Check whether we also stored the class + if (json_object.has(json_key + JSON_CLASS_SUFFIX)) { + try { + field_class = ClassUtil.getClass(json_object.getString(json_key + JSON_CLASS_SUFFIX)); + } catch (Exception ex) { + LOG.error("Failed to include class for field '{}'", json_key, ex); + throw new JSONException(ex); + } + } + return (field_class); + } + + /** + * Return the proper serialization string for the given value + * + * @param field_class + * @param field_value + * @return + */ + private static Object makePrimitiveValue(Class field_class, Object field_value) { + Object value = null; + + if (field_class.equals(Class.class)) { + value = ((Class) field_value).getName(); + // JSONSerializable + } else if (ClassUtil.getInterfaces(field_class).contains(JSONSerializable.class)) { + // Just return the value back. The JSON library will take care of it + // System.err.println(field_class + ": " + field_value); + value = field_value; + // Everything else + } else { + value = field_value; // .toString(); + } + return (value); + } + + /** + * For the given JSON string, figure out what kind of object it is and return it + * + * @param json_value + * @param field_class + * @return + */ + public static Object getPrimitiveValue(String json_value, Class field_class) { + Object value = null; + + if (field_class.equals(Class.class)) { + value = ClassUtil.getClass(json_value); + if (value == null) { + throw new JSONException("Failed to get class from '" + json_value + "'"); + } + // Enum + } else if (field_class.isEnum()) { + for (Object o : field_class.getEnumConstants()) { + Enum e = (Enum) o; + if (json_value.equals(e.name())) { + return (e); } - return (value); + } + throw new JSONException( + "Invalid enum value '" + + json_value + + "': " + + Arrays.toString(field_class.getEnumConstants())); + // JSONSerializable + } else if (ClassUtil.getInterfaces(field_class).contains(JSONSerializable.class)) { + value = ClassUtil.newInstance(field_class, null, null); + ((JSONSerializable) value).fromJSON(new JSONObject(json_value)); + // Boolean + } else if (field_class.equals(Boolean.class) || field_class.equals(boolean.class)) { + // We have to use field_class.equals() because the value may be null + value = Boolean.parseBoolean(json_value); + // Short + } else if (field_class.equals(Short.class) || field_class.equals(short.class)) { + value = Short.parseShort(json_value); + // Integer + } else if (field_class.equals(Integer.class) || field_class.equals(int.class)) { + value = Integer.parseInt(json_value); + // Long + } else if (field_class.equals(Long.class) || field_class.equals(long.class)) { + value = Long.parseLong(json_value); + // Float + } else if (field_class.equals(Float.class) || field_class.equals(float.class)) { + value = Float.parseFloat(json_value); + // Double + } else if (field_class.equals(Double.class) || field_class.equals(double.class)) { + value = Double.parseDouble(json_value); + // String + } else if (field_class.equals(String.class)) { + value = json_value; } - + return (value); + } } diff --git a/src/main/java/com/oltpbenchmark/util/LatchedExceptionHandler.java b/src/main/java/com/oltpbenchmark/util/LatchedExceptionHandler.java index f0a22c7cd..47ef89a80 100644 --- a/src/main/java/com/oltpbenchmark/util/LatchedExceptionHandler.java +++ b/src/main/java/com/oltpbenchmark/util/LatchedExceptionHandler.java @@ -45,27 +45,28 @@ package com.oltpbenchmark.util; +import java.util.concurrent.CountDownLatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.CountDownLatch; - public class LatchedExceptionHandler implements Thread.UncaughtExceptionHandler { - private final Logger LOG = LoggerFactory.getLogger(getClass()); + private final Logger LOG = LoggerFactory.getLogger(getClass()); - private final CountDownLatch latch; + private final CountDownLatch latch; - public LatchedExceptionHandler(CountDownLatch latch) { - this.latch = latch; - } + public LatchedExceptionHandler(CountDownLatch latch) { + this.latch = latch; + } - @Override - public void uncaughtException(Thread t, Throwable e) { - LOG.error(String.format("Uncaught Exception in thread with message: [%s]; will count down latch with count %d", e.getMessage(), this.latch.getCount()), e); - while (this.latch.getCount() > 0) { - this.latch.countDown(); - } + @Override + public void uncaughtException(Thread t, Throwable e) { + LOG.error( + String.format( + "Uncaught Exception in thread with message: [%s]; will count down latch with count %d", + e.getMessage(), this.latch.getCount()), + e); + while (this.latch.getCount() > 0) { + this.latch.countDown(); } - - + } } diff --git a/src/main/java/com/oltpbenchmark/util/Pair.java b/src/main/java/com/oltpbenchmark/util/Pair.java index b2c016f58..ec995d345 100644 --- a/src/main/java/com/oltpbenchmark/util/Pair.java +++ b/src/main/java/com/oltpbenchmark/util/Pair.java @@ -37,68 +37,62 @@ import java.util.Objects; /** - * Class representing a pair of generic-ized types. Supports equality, hashing - * and all that other nice Java stuff. Based on STL's pair class in C++. + * Class representing a pair of generic-ized types. Supports equality, hashing and all that other + * nice Java stuff. Based on STL's pair class in C++. */ public class Pair implements Comparable> { - public final T first; - public final U second; - private final transient Integer hash; + public final T first; + public final U second; + private final transient Integer hash; - public Pair(T first, U second, boolean precomputeHash) { - this.first = first; - this.second = second; - hash = (precomputeHash ? this.computeHashCode() : null); - } + public Pair(T first, U second, boolean precomputeHash) { + this.first = first; + this.second = second; + hash = (precomputeHash ? this.computeHashCode() : null); + } - public Pair(T first, U second) { - this(first, second, true); - } + public Pair(T first, U second) { + this(first, second, true); + } - private int computeHashCode() { - return (first == null ? 0 : first.hashCode() * 31) + - (second == null ? 0 : second.hashCode()); - } + private int computeHashCode() { + return (first == null ? 0 : first.hashCode() * 31) + (second == null ? 0 : second.hashCode()); + } - public int hashCode() { - if (hash != null) { - return (hash); - } - return (this.computeHashCode()); + public int hashCode() { + if (hash != null) { + return (hash); } - - public String toString() { - return String.format("<%s, %s>", first, second); + return (this.computeHashCode()); + } + + public String toString() { + return String.format("<%s, %s>", first, second); + } + + @Override + public int compareTo(Pair other) { + return (other.hash - this.hash); + } + + @SuppressWarnings("unchecked") + public boolean equals(Object o) { + if (this == o) { + return true; } - @Override - public int compareTo(Pair other) { - return (other.hash - this.hash); + if (o == null || !(o instanceof Pair)) { + return false; } - @SuppressWarnings("unchecked") - public boolean equals(Object o) { - if (this == o) { - return true; - } - - if (o == null || !(o instanceof Pair)) { - return false; - } + Pair other = (Pair) o; + return (Objects.equals(first, other.first)) && (Objects.equals(second, other.second)); + } - Pair other = (Pair) o; - - return (Objects.equals(first, other.first)) - && (Objects.equals(second, other.second)); - } - - /** - * Convenience class method for constructing pairs using Java's generic type - * inference. - */ - public static Pair of(T x, U y) { - return new Pair<>(x, y); - } + /** Convenience class method for constructing pairs using Java's generic type inference. */ + public static Pair of(T x, U y) { + return new Pair<>(x, y); + } } diff --git a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java index 559ce67f6..cf05f0d87 100644 --- a/src/main/java/com/oltpbenchmark/util/RandomDistribution.java +++ b/src/main/java/com/oltpbenchmark/util/RandomDistribution.java @@ -21,350 +21,335 @@ /** * A class that generates random numbers that follow some distribution. - *

- * Copied from - * hadoop-3315 tfile. - * Remove after tfile is committed and use the tfile version of this class - * instead.

+ * + *

Copied from hadoop-3315 tfile. + * Remove after tfile is committed and use the tfile version of this class instead. */ public class RandomDistribution { - /** - * Interface for discrete (integer) random distributions. - */ - public static abstract class DiscreteRNG extends Random { - private static final long serialVersionUID = 1L; - protected final long min; - protected final long max; - protected final Random random; - protected final double mean; - protected final long range_size; - private Histogram history; - - public DiscreteRNG(Random random, long min, long max) { - if (min >= max) { - throw new IllegalArgumentException("Invalid range [" + min + " >= " + max + "]"); - } - this.random = random; - this.min = min; - this.max = max; - this.range_size = (max - min) + 1; - this.mean = this.range_size / 2.0; - } + /** Interface for discrete (integer) random distributions. */ + public abstract static class DiscreteRNG extends Random { + private static final long serialVersionUID = 1L; + protected final long min; + protected final long max; + protected final Random random; + protected final double mean; + protected final long range_size; + private Histogram history; + + public DiscreteRNG(Random random, long min, long max) { + if (min >= max) { + throw new IllegalArgumentException("Invalid range [" + min + " >= " + max + "]"); + } + this.random = random; + this.min = min; + this.max = max; + this.range_size = (max - min) + 1; + this.mean = this.range_size / 2.0; + } - protected abstract long nextLongImpl(); + protected abstract long nextLongImpl(); - /** - * Enable keeping track of the values that the RNG generates - */ - public void enableHistory() { + /** Enable keeping track of the values that the RNG generates */ + public void enableHistory() { - this.history = new Histogram<>(); - } + this.history = new Histogram<>(); + } - /** - * Return the histogram of the values that have been generated - * - * @return - */ - public Histogram getHistory() { + /** + * Return the histogram of the values that have been generated + * + * @return + */ + public Histogram getHistory() { - return (this.history); - } + return (this.history); + } - public long getRange() { - return this.range_size; - } + public long getRange() { + return this.range_size; + } - public long getMin() { - return this.min; - } + public long getMin() { + return this.min; + } - public long getMax() { - return this.max; - } + public long getMax() { + return this.max; + } - public Random getRandom() { - return (this.random); - } + public Random getRandom() { + return (this.random); + } - public double calculateMean(int num_samples) { - long total = 0l; - for (int i = 0; i < num_samples; i++) { - total += this.nextLong(); - } // FOR - return (total / (double)num_samples); - } + public double calculateMean(int num_samples) { + long total = 0l; + for (int i = 0; i < num_samples; i++) { + total += this.nextLong(); + } // FOR + return (total / (double) num_samples); + } - /** - * Get the next random number as an int - * - * @return the next random number. - */ - @Override - public final int nextInt() { - long val = (int) this.nextLongImpl(); - if (this.history != null) { - this.history.put(val); - } - return ((int) val); - } + /** + * Get the next random number as an int + * + * @return the next random number. + */ + @Override + public final int nextInt() { + long val = (int) this.nextLongImpl(); + if (this.history != null) { + this.history.put(val); + } + return ((int) val); + } - /** - * Get the next random number as a long - * - * @return the next random number. - */ - @Override - public final long nextLong() { - long val = this.nextLongImpl(); - if (this.history != null) { - this.history.put(val); - } - return (val); - } + /** + * Get the next random number as a long + * + * @return the next random number. + */ + @Override + public final long nextLong() { + long val = this.nextLongImpl(); + if (this.history != null) { + this.history.put(val); + } + return (val); + } - @Override - public String toString() { - return String.format("%s[min=%d, max=%d]", this.getClass().getSimpleName(), this.min, this.max); - } + @Override + public String toString() { + return String.format( + "%s[min=%d, max=%d]", this.getClass().getSimpleName(), this.min, this.max); + } + public static long nextLong(Random rng, long n) { + // error checking and 2^x checking removed for simplicity. + long bits, val; + do { + bits = (rng.nextLong() << 1) >>> 1; + val = bits % n; + } while (bits - val + (n - 1) < 0L); + return val; + } + } - public static long nextLong(Random rng, long n) { - // error checking and 2^x checking removed for simplicity. - long bits, val; - do { - bits = (rng.nextLong() << 1) >>> 1; - val = bits % n; - } - while (bits - val + (n - 1) < 0L); - return val; - } + /** P(i)=1/(max-min) */ + public static class Flat extends DiscreteRNG { + private static final long serialVersionUID = 1L; + + /** + * Generate random integers from min (inclusive) to max (exclusive) following even distribution. + * + * @param random The basic random number generator. + * @param min Minimum integer + * @param max maximum integer (exclusive). + */ + public Flat(Random random, long min, long max) { + super(random, min, max); } /** - * P(i)=1/(max-min) + * @see DiscreteRNG#nextInt() */ - public static class Flat extends DiscreteRNG { - private static final long serialVersionUID = 1L; - - /** - * Generate random integers from min (inclusive) to max (exclusive) - * following even distribution. - * - * @param random The basic random number generator. - * @param min Minimum integer - * @param max maximum integer (exclusive). - */ - public Flat(Random random, long min, long max) { - super(random, min, max); - } + @Override + protected long nextLongImpl() { + // error checking and 2^x checking removed for simplicity. + long bits, val; + do { + bits = (random.nextLong() << 1) >>> 1; + val = bits % (this.range_size - 1); + } while (bits - val + (this.range_size - 1) < 0L); + val += this.min; + + return val; + } + } + + /** P(i)=1/(max-min) */ + public static class FlatHistogram> extends DiscreteRNG { + private static final long serialVersionUID = 1L; + private final Flat inner; + private final TreeMap value_rle = new TreeMap<>(); + private Histogram history; + + /** Generate a run-length of the values of the histogram */ + public FlatHistogram(Random random, Histogram histogram) { + super(random, 0, histogram.getSampleCount()); + this.inner = new Flat(random, 0, histogram.getSampleCount()); + + long total = 0; + for (T k : histogram.values()) { + long v = histogram.get(k); + total += v; + this.value_rle.put(total, k); + } + } - /** - * @see DiscreteRNG#nextInt() - */ - @Override - protected long nextLongImpl() { - // error checking and 2^x checking removed for simplicity. - long bits, val; - do { - bits = (random.nextLong() << 1) >>> 1; - val = bits % (this.range_size - 1); - } - while (bits - val + (this.range_size - 1) < 0L); - val += this.min; - - - return val; - } + @Override + public void enableHistory() { + this.history = new Histogram<>(); + } + + public Histogram getHistogramHistory() { + if (this.history != null) { + return (this.history); + } + return (null); + } + + public T nextValue() { + int idx = this.inner.nextInt(); + Long total = this.value_rle.tailMap((long) idx).firstKey(); + T val = this.value_rle.get(total); + if (this.history != null) { + this.history.put(val); + } + return (val); + // assert(false) : "Went beyond our expected total '" + idx + "'"; + // return (null); } /** - * P(i)=1/(max-min) + * @see DiscreteRNG#nextLong() */ - public static class FlatHistogram> extends DiscreteRNG { - private static final long serialVersionUID = 1L; - private final Flat inner; - private final TreeMap value_rle = new TreeMap<>(); - private Histogram history; - - /** - * Generate a run-length of the values of the histogram - */ - public FlatHistogram(Random random, Histogram histogram) { - super(random, 0, histogram.getSampleCount()); - this.inner = new Flat(random, 0, histogram.getSampleCount()); - - long total = 0; - for (T k : histogram.values()) { - long v = histogram.get(k); - total += v; - this.value_rle.put(total, k); - } - } + @Override + protected long nextLongImpl() { + Object val = this.nextValue(); + if (val instanceof Integer) { + return ((Integer) val); + } + return ((Long) val); + } + } - @Override - public void enableHistory() { - this.history = new Histogram<>(); - } + /** Simple generic class overload to avoid some cast warnings below. */ + public static class IntegerFlatHistogram extends FlatHistogram { + // Required serialization field. + private static final long serialVersionUID = 1L; + public IntegerFlatHistogram(Random random, Histogram histogram) { + super(random, histogram); + } + } - public Histogram getHistogramHistory() { - if (this.history != null) { - return (this.history); - } - return (null); - } + /** Gaussian Distribution */ + public static class Gaussian extends DiscreteRNG { + private static final long serialVersionUID = 1L; - public T nextValue() { - int idx = this.inner.nextInt(); - Long total = this.value_rle.tailMap((long) idx).firstKey(); - T val = this.value_rle.get(total); - if (this.history != null) { - this.history.put(val); - } - return (val); -// assert(false) : "Went beyond our expected total '" + idx + "'"; -// return (null); - } + public Gaussian(Random random, long min, long max) { + super(random, min, max); + } - /** - * @see DiscreteRNG#nextLong() - */ - @Override - protected long nextLongImpl() { - Object val = this.nextValue(); - if (val instanceof Integer) { - return ((Integer) val); - } - return ((Long) val); - } + @Override + protected long nextLongImpl() { + int value = -1; + while (value < 0 || value >= this.range_size) { + double gaussian = (this.random.nextGaussian() + 2.0) / 4.0; + value = (int) Math.round(gaussian * this.range_size); + } + return (value + this.min); } + } + + /** + * Zipf distribution. The ratio of the probabilities of integer i and j is defined as follows: + * + *

P(i)/P(j)=((j-min+1)/(i-min+1))^sigma. + */ + public static class Zipf extends DiscreteRNG { + private static final long serialVersionUID = 1L; + private static final double DEFAULT_EPSILON = 0.001; + private final ArrayList k; + private final ArrayList v; /** - * Simple generic class overload to avoid some cast warnings below. + * Constructor + * + * @param r The random number generator. + * @param min minimum integer (inclusvie) + * @param max maximum integer (exclusive) + * @param sigma parameter sigma. (sigma > 1.0) */ - public static class IntegerFlatHistogram extends FlatHistogram { - // Required serialization field. - private static final long serialVersionUID = 1L; - public IntegerFlatHistogram(Random random, Histogram histogram) { - super(random, histogram); - } + public Zipf(Random r, long min, long max, double sigma) { + this(r, min, max, sigma, DEFAULT_EPSILON); } /** - * Gaussian Distribution + * Constructor. + * + * @param r The random number generator. + * @param min minimum integer (inclusvie) + * @param max maximum integer (exclusive) + * @param sigma parameter sigma. (sigma > 1.0) + * @param epsilon Allowable error percentage (0 < epsilon < 1.0). */ - public static class Gaussian extends DiscreteRNG { - private static final long serialVersionUID = 1L; - - public Gaussian(Random random, long min, long max) { - super(random, min, max); + public Zipf(Random r, long min, long max, double sigma, double epsilon) { + super(r, min, max); + if ((max <= min) || (sigma <= 1) || (epsilon <= 0) || (epsilon >= 0.5)) { + throw new IllegalArgumentException( + "Invalid arguments [min=" + + min + + ", max=" + + max + + ", sigma=" + + sigma + + ", epsilon=" + + epsilon + + "]"); + } + k = new ArrayList<>(); + v = new ArrayList<>(); + + double sum = 0; + long last = -1; + for (long i = min; i < max; ++i) { + sum += Math.exp(-sigma * Math.log(i - min + 1)); + if ((last == -1) || i * (1 - epsilon) > last) { + k.add(i); + v.add(sum); + last = i; } + } - @Override - protected long nextLongImpl() { - int value = -1; - while (value < 0 || value >= this.range_size) { - double gaussian = (this.random.nextGaussian() + 2.0) / 4.0; - value = (int) Math.round(gaussian * this.range_size); - } - return (value + this.min); - } - } + if (last != max - 1) { + k.add(max - 1); + v.add(sum); + } + + v.set(v.size() - 1, 1.0); + for (int i = v.size() - 2; i >= 0; --i) { + v.set(i, v.get(i) / sum); + } + } /** - * Zipf distribution. The ratio of the probabilities of integer i and j is - * defined as follows: - *

- * P(i)/P(j)=((j-min+1)/(i-min+1))^sigma. + * @see DiscreteRNG#nextInt() */ - public static class Zipf extends DiscreteRNG { - private static final long serialVersionUID = 1L; - private static final double DEFAULT_EPSILON = 0.001; - private final ArrayList k; - private final ArrayList v; - - /** - * Constructor - * - * @param r The random number generator. - * @param min minimum integer (inclusvie) - * @param max maximum integer (exclusive) - * @param sigma parameter sigma. (sigma > 1.0) - */ - public Zipf(Random r, long min, long max, double sigma) { - this(r, min, max, sigma, DEFAULT_EPSILON); - } - - /** - * Constructor. - * - * @param r The random number generator. - * @param min minimum integer (inclusvie) - * @param max maximum integer (exclusive) - * @param sigma parameter sigma. (sigma > 1.0) - * @param epsilon Allowable error percentage (0 < epsilon < 1.0). - */ - public Zipf(Random r, long min, long max, double sigma, double epsilon) { - super(r, min, max); - if ((max <= min) || (sigma <= 1) || (epsilon <= 0) || (epsilon >= 0.5)) { - throw new IllegalArgumentException("Invalid arguments [min=" + min + ", max=" + max + ", sigma=" + sigma + ", epsilon=" + epsilon + "]"); - } - k = new ArrayList<>(); - v = new ArrayList<>(); - - double sum = 0; - long last = -1; - for (long i = min; i < max; ++i) { - sum += Math.exp(-sigma * Math.log(i - min + 1)); - if ((last == -1) || i * (1 - epsilon) > last) { - k.add(i); - v.add(sum); - last = i; - } - } - - if (last != max - 1) { - k.add(max - 1); - v.add(sum); - } - - v.set(v.size() - 1, 1.0); - - for (int i = v.size() - 2; i >= 0; --i) { - v.set(i, v.get(i) / sum); - } - } + @Override + protected long nextLongImpl() { + double d = random.nextDouble(); + int idx = Collections.binarySearch(v, d); + if (idx > 0) { + ++idx; + } else { + idx = -(idx + 1); + } - /** - * @see DiscreteRNG#nextInt() - */ - @Override - protected long nextLongImpl() { - double d = random.nextDouble(); - int idx = Collections.binarySearch(v, d); + if (idx >= v.size()) { + idx = v.size() - 1; + } - if (idx > 0) { - ++idx; - } else { - idx = -(idx + 1); - } + if (idx == 0) { + return k.get(0); + } - if (idx >= v.size()) { - idx = v.size() - 1; - } + long ceiling = k.get(idx); + long lower = k.get(idx - 1); - if (idx == 0) { - return k.get(0); - } - - long ceiling = k.get(idx); - long lower = k.get(idx - 1); - - return ceiling - DiscreteRNG.nextLong(random, ceiling - lower); - } + return ceiling - DiscreteRNG.nextLong(random, ceiling - lower); } - + } } diff --git a/src/main/java/com/oltpbenchmark/util/RandomGenerator.java b/src/main/java/com/oltpbenchmark/util/RandomGenerator.java index 3e1fa627f..fcbd42f68 100644 --- a/src/main/java/com/oltpbenchmark/util/RandomGenerator.java +++ b/src/main/java/com/oltpbenchmark/util/RandomGenerator.java @@ -15,112 +15,108 @@ * */ - package com.oltpbenchmark.util; import java.util.Random; public class RandomGenerator extends Random { - static final long serialVersionUID = 0; - - /** - * Constructor - * - * @param seed - */ - public RandomGenerator(int seed) { - super(seed); - } - - /** - * Returns a random int value between minimum and maximum (inclusive) - * - * @param minimum - * @param maximum - * @returns a int in the range [minimum, maximum]. Note that this is inclusive. - */ - public int number(int minimum, int maximum) { - - int range_size = maximum - minimum + 1; - int value = this.nextInt(range_size); - value += minimum; - - return value; - } - - /** - * Returns a random long value between minimum and maximum (inclusive) - * - * @param minimum - * @param maximum - * @return - */ - public long number(long minimum, long maximum) { - - long range_size = (maximum - minimum) + 1; - - // error checking and 2^x checking removed for simplicity. - long bits, val; - do { - bits = (this.nextLong() << 1) >>> 1; - val = bits % range_size; - } - while (bits - val + range_size < 0L); - val += minimum; - - - return val; - } - - /** - * @param decimal_places - * @param minimum - * @param maximum - * @return - */ - public double fixedPoint(int decimal_places, double minimum, double maximum) { - - - int multiplier = 1; - for (int i = 0; i < decimal_places; ++i) { - multiplier *= 10; - } - - int int_min = (int) (minimum * multiplier + 0.5); - int int_max = (int) (maximum * multiplier + 0.5); - - return (double) this.number(int_min, int_max) / (double) multiplier; - } - - /** - * @returns a random alphabetic string with length in range [minimum_length, maximum_length]. - */ - public String astring(int minimum_length, int maximum_length) { - return randomString(minimum_length, maximum_length, 'a', 26); - } - - - /** - * @returns a random numeric string with length in range [minimum_length, maximum_length]. - */ - public String nstring(int minimum_length, int maximum_length) { - return randomString(minimum_length, maximum_length, '0', 10); + static final long serialVersionUID = 0; + + /** + * Constructor + * + * @param seed + */ + public RandomGenerator(int seed) { + super(seed); + } + + /** + * Returns a random int value between minimum and maximum (inclusive) + * + * @param minimum + * @param maximum + * @returns a int in the range [minimum, maximum]. Note that this is inclusive. + */ + public int number(int minimum, int maximum) { + + int range_size = maximum - minimum + 1; + int value = this.nextInt(range_size); + value += minimum; + + return value; + } + + /** + * Returns a random long value between minimum and maximum (inclusive) + * + * @param minimum + * @param maximum + * @return + */ + public long number(long minimum, long maximum) { + + long range_size = (maximum - minimum) + 1; + + // error checking and 2^x checking removed for simplicity. + long bits, val; + do { + bits = (this.nextLong() << 1) >>> 1; + val = bits % range_size; + } while (bits - val + range_size < 0L); + val += minimum; + + return val; + } + + /** + * @param decimal_places + * @param minimum + * @param maximum + * @return + */ + public double fixedPoint(int decimal_places, double minimum, double maximum) { + + int multiplier = 1; + for (int i = 0; i < decimal_places; ++i) { + multiplier *= 10; } - /** - * @param minimum_length - * @param maximum_length - * @param base - * @param numCharacters - * @return - */ - private String randomString(int minimum_length, int maximum_length, char base, int numCharacters) { - int length = number(minimum_length, maximum_length); - byte baseByte = (byte) base; - byte[] bytes = new byte[length]; - for (int i = 0; i < length; ++i) { - bytes[i] = (byte) (baseByte + number(0, numCharacters - 1)); - } - return new String(bytes); + int int_min = (int) (minimum * multiplier + 0.5); + int int_max = (int) (maximum * multiplier + 0.5); + + return (double) this.number(int_min, int_max) / (double) multiplier; + } + + /** + * @returns a random alphabetic string with length in range [minimum_length, maximum_length]. + */ + public String astring(int minimum_length, int maximum_length) { + return randomString(minimum_length, maximum_length, 'a', 26); + } + + /** + * @returns a random numeric string with length in range [minimum_length, maximum_length]. + */ + public String nstring(int minimum_length, int maximum_length) { + return randomString(minimum_length, maximum_length, '0', 10); + } + + /** + * @param minimum_length + * @param maximum_length + * @param base + * @param numCharacters + * @return + */ + private String randomString( + int minimum_length, int maximum_length, char base, int numCharacters) { + int length = number(minimum_length, maximum_length); + byte baseByte = (byte) base; + byte[] bytes = new byte[length]; + for (int i = 0; i < length; ++i) { + bytes[i] = (byte) (baseByte + number(0, numCharacters - 1)); } -} \ No newline at end of file + return new String(bytes); + } +} diff --git a/src/main/java/com/oltpbenchmark/util/ResultWriter.java b/src/main/java/com/oltpbenchmark/util/ResultWriter.java index 7e0a0a8c6..46864a0f3 100644 --- a/src/main/java/com/oltpbenchmark/util/ResultWriter.java +++ b/src/main/java/com/oltpbenchmark/util/ResultWriter.java @@ -25,210 +25,199 @@ import com.oltpbenchmark.api.collectors.DBParameterCollector; import com.oltpbenchmark.api.collectors.DBParameterCollectorGen; import com.oltpbenchmark.types.DatabaseType; +import java.io.PrintStream; +import java.util.*; import org.apache.commons.cli.CommandLine; import org.apache.commons.configuration2.XMLConfiguration; import org.apache.commons.configuration2.ex.ConfigurationException; import org.apache.commons.configuration2.io.FileHandler; -import java.io.PrintStream; -import java.util.*; - public class ResultWriter { - public static final double MILLISECONDS_FACTOR = 1e3; - - - private static final String[] IGNORE_CONF = { - "type", - "driver", - "url", - "username", - "password" - }; - - private static final String[] BENCHMARK_KEY_FIELD = { - "isolation", - "scalefactor", - "terminals" - }; - - private final XMLConfiguration expConf; - private final DBParameterCollector collector; - private final Results results; - private final DatabaseType dbType; - private final String benchType; - - - public ResultWriter(Results r, XMLConfiguration conf, CommandLine argsLine) { - this.expConf = conf; - this.results = r; - this.dbType = DatabaseType.valueOf(expConf.getString("type").toUpperCase()); - this.benchType = argsLine.getOptionValue("b"); - - String dbUrl = expConf.getString("url"); - String username = expConf.getString("username"); - String password = expConf.getString("password"); + public static final double MILLISECONDS_FACTOR = 1e3; + private static final String[] IGNORE_CONF = {"type", "driver", "url", "username", "password"}; - this.collector = DBParameterCollectorGen.getCollector(dbType, dbUrl, username, password); + private static final String[] BENCHMARK_KEY_FIELD = {"isolation", "scalefactor", "terminals"}; - } + private final XMLConfiguration expConf; + private final DBParameterCollector collector; + private final Results results; + private final DatabaseType dbType; + private final String benchType; - public void writeParams(PrintStream os) { - String dbConf = collector.collectParameters(); - os.print(dbConf); - } + public ResultWriter(Results r, XMLConfiguration conf, CommandLine argsLine) { + this.expConf = conf; + this.results = r; + this.dbType = DatabaseType.valueOf(expConf.getString("type").toUpperCase()); + this.benchType = argsLine.getOptionValue("b"); - public void writeMetrics(PrintStream os) { - os.print(collector.collectMetrics()); - } + String dbUrl = expConf.getString("url"); + String username = expConf.getString("username"); + String password = expConf.getString("password"); - public boolean hasMetrics() { - return collector.hasMetrics(); - } + this.collector = DBParameterCollectorGen.getCollector(dbType, dbUrl, username, password); + } - public void writeConfig(PrintStream os) throws ConfigurationException { + public void writeParams(PrintStream os) { + String dbConf = collector.collectParameters(); + os.print(dbConf); + } - XMLConfiguration outputConf = (XMLConfiguration) expConf.clone(); - for (String key : IGNORE_CONF) { - outputConf.clearProperty(key); - } + public void writeMetrics(PrintStream os) { + os.print(collector.collectMetrics()); + } - FileHandler handler = new FileHandler(outputConf); - handler.save(os); - } + public boolean hasMetrics() { + return collector.hasMetrics(); + } - public void writeSummary(PrintStream os) { - Map summaryMap = new LinkedHashMap<>(); - TimeZone.setDefault(TimeZone.getTimeZone("UTC")); - Date now = new Date(); - summaryMap.put("Start timestamp (milliseconds)", results.getStartTimestampMs()); - summaryMap.put("Current Timestamp (milliseconds)", now.getTime()); - summaryMap.put("Elapsed Time (nanoseconds)", results.getNanoseconds()); - summaryMap.put("DBMS Type", dbType); - summaryMap.put("DBMS Version", collector.collectVersion()); - summaryMap.put("Benchmark Type", benchType); - summaryMap.put("Measured Requests", results.getMeasuredRequests()); - for (String field : BENCHMARK_KEY_FIELD) { - summaryMap.put(field, expConf.getString(field)); - } - summaryMap.put("Latency Distribution", results.getDistributionStatistics().toMap()); - summaryMap.put("Throughput (requests/second)", results.requestsPerSecondThroughput()); - summaryMap.put("Goodput (requests/second)", results.requestsPerSecondGoodput()); - os.println(JSONUtil.format(JSONUtil.toJSONString(summaryMap))); - } + public void writeConfig(PrintStream os) throws ConfigurationException { - public void writeResults(int windowSizeSeconds, PrintStream out) { - writeResults(windowSizeSeconds, out, TransactionType.INVALID); + XMLConfiguration outputConf = (XMLConfiguration) expConf.clone(); + for (String key : IGNORE_CONF) { + outputConf.clearProperty(key); } - public void writeResults(int windowSizeSeconds, PrintStream out, TransactionType txType) { - String[] header = { - "Time (seconds)", - "Throughput (requests/second)", - "Average Latency (millisecond)", - "Minimum Latency (millisecond)", - "25th Percentile Latency (millisecond)", - "Median Latency (millisecond)", - "75th Percentile Latency (millisecond)", - "90th Percentile Latency (millisecond)", - "95th Percentile Latency (millisecond)", - "99th Percentile Latency (millisecond)", - "Maximum Latency (millisecond)", - "tp (req/s) scaled" - }; - out.println(StringUtil.join(",", header)); - int i = 0; - for (DistributionStatistics s : new ThreadBench.TimeBucketIterable(results.getLatencySamples(), windowSizeSeconds, txType)) { - out.printf("%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", - i * windowSizeSeconds, - (double) s.getCount() / windowSizeSeconds, - s.getAverage() / MILLISECONDS_FACTOR, - s.getMinimum() / MILLISECONDS_FACTOR, - s.get25thPercentile() / MILLISECONDS_FACTOR, - s.getMedian() / MILLISECONDS_FACTOR, - s.get75thPercentile() / MILLISECONDS_FACTOR, - s.get90thPercentile() / MILLISECONDS_FACTOR, - s.get95thPercentile() / MILLISECONDS_FACTOR, - s.get99thPercentile() / MILLISECONDS_FACTOR, - s.getMaximum() / MILLISECONDS_FACTOR, - MILLISECONDS_FACTOR / s.getAverage()); - i += 1; - } + FileHandler handler = new FileHandler(outputConf); + handler.save(os); + } + + public void writeSummary(PrintStream os) { + Map summaryMap = new LinkedHashMap<>(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + Date now = new Date(); + summaryMap.put("Start timestamp (milliseconds)", results.getStartTimestampMs()); + summaryMap.put("Current Timestamp (milliseconds)", now.getTime()); + summaryMap.put("Elapsed Time (nanoseconds)", results.getNanoseconds()); + summaryMap.put("DBMS Type", dbType); + summaryMap.put("DBMS Version", collector.collectVersion()); + summaryMap.put("Benchmark Type", benchType); + summaryMap.put("Measured Requests", results.getMeasuredRequests()); + for (String field : BENCHMARK_KEY_FIELD) { + summaryMap.put(field, expConf.getString(field)); } - - public void writeSamples(PrintStream out) { - writeSamples(1, out, TransactionType.INVALID); + summaryMap.put("Latency Distribution", results.getDistributionStatistics().toMap()); + summaryMap.put("Throughput (requests/second)", results.requestsPerSecondThroughput()); + summaryMap.put("Goodput (requests/second)", results.requestsPerSecondGoodput()); + os.println(JSONUtil.format(JSONUtil.toJSONString(summaryMap))); + } + + public void writeResults(int windowSizeSeconds, PrintStream out) { + writeResults(windowSizeSeconds, out, TransactionType.INVALID); + } + + public void writeResults(int windowSizeSeconds, PrintStream out, TransactionType txType) { + String[] header = { + "Time (seconds)", + "Throughput (requests/second)", + "Average Latency (millisecond)", + "Minimum Latency (millisecond)", + "25th Percentile Latency (millisecond)", + "Median Latency (millisecond)", + "75th Percentile Latency (millisecond)", + "90th Percentile Latency (millisecond)", + "95th Percentile Latency (millisecond)", + "99th Percentile Latency (millisecond)", + "Maximum Latency (millisecond)", + "tp (req/s) scaled" + }; + out.println(StringUtil.join(",", header)); + int i = 0; + for (DistributionStatistics s : + new ThreadBench.TimeBucketIterable( + results.getLatencySamples(), windowSizeSeconds, txType)) { + out.printf( + "%d,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3f\n", + i * windowSizeSeconds, + (double) s.getCount() / windowSizeSeconds, + s.getAverage() / MILLISECONDS_FACTOR, + s.getMinimum() / MILLISECONDS_FACTOR, + s.get25thPercentile() / MILLISECONDS_FACTOR, + s.getMedian() / MILLISECONDS_FACTOR, + s.get75thPercentile() / MILLISECONDS_FACTOR, + s.get90thPercentile() / MILLISECONDS_FACTOR, + s.get95thPercentile() / MILLISECONDS_FACTOR, + s.get99thPercentile() / MILLISECONDS_FACTOR, + s.getMaximum() / MILLISECONDS_FACTOR, + MILLISECONDS_FACTOR / s.getAverage()); + i += 1; } - - public void writeSamples(int windowSizeSeconds, PrintStream out, TransactionType txType) { - String[] header = { - "Time (seconds)", - "Requests", - "Throughput (requests/second)", - "Minimum Latency (microseconds)", - "25th Percentile Latency (microseconds)", - "Median Latency (microseconds)", - "Average Latency (microseconds)", - "75th Percentile Latency (microseconds)", - "90th Percentile Latency (microseconds)", - "95th Percentile Latency (microseconds)", - "99th Percentile Latency (microseconds)", - "Maximum Latency (microseconds)" - }; - out.println(StringUtil.join(",", header)); - int i = 0; - for (DistributionStatistics s : new ThreadBench.TimeBucketIterable(results.getLatencySamples(), windowSizeSeconds, txType)) { - out.printf("%d,%d,%.3f,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", - i * windowSizeSeconds, - s.getCount(), - (double) s.getCount() / windowSizeSeconds, - (int) s.getMinimum(), - (int) s.get25thPercentile(), - (int) s.getMedian(), - (int) s.getAverage(), - (int) s.get75thPercentile(), - (int) s.get90thPercentile(), - (int) s.get95thPercentile(), - (int) s.get99thPercentile(), - (int) s.getMaximum()); - i += 1; - } + } + + public void writeSamples(PrintStream out) { + writeSamples(1, out, TransactionType.INVALID); + } + + public void writeSamples(int windowSizeSeconds, PrintStream out, TransactionType txType) { + String[] header = { + "Time (seconds)", + "Requests", + "Throughput (requests/second)", + "Minimum Latency (microseconds)", + "25th Percentile Latency (microseconds)", + "Median Latency (microseconds)", + "Average Latency (microseconds)", + "75th Percentile Latency (microseconds)", + "90th Percentile Latency (microseconds)", + "95th Percentile Latency (microseconds)", + "99th Percentile Latency (microseconds)", + "Maximum Latency (microseconds)" + }; + out.println(StringUtil.join(",", header)); + int i = 0; + for (DistributionStatistics s : + new ThreadBench.TimeBucketIterable( + results.getLatencySamples(), windowSizeSeconds, txType)) { + out.printf( + "%d,%d,%.3f,%d,%d,%d,%d,%d,%d,%d,%d,%d\n", + i * windowSizeSeconds, + s.getCount(), + (double) s.getCount() / windowSizeSeconds, + (int) s.getMinimum(), + (int) s.get25thPercentile(), + (int) s.getMedian(), + (int) s.getAverage(), + (int) s.get75thPercentile(), + (int) s.get90thPercentile(), + (int) s.get95thPercentile(), + (int) s.get99thPercentile(), + (int) s.getMaximum()); + i += 1; } - - public void writeRaw(List activeTXTypes, PrintStream out) { - - // This is needed because nanTime does not guarantee offset... we - // ground it (and round it) to ms from 1970-01-01 like currentTime - double x = ((double) System.nanoTime() / (double) 1000000000); - double y = ((double) System.currentTimeMillis() / (double) 1000); - double offset = x - y; - - // long startNs = latencySamples.get(0).startNs; - String[] header = { - "Transaction Type Index", - "Transaction Name", - "Start Time (microseconds)", - "Latency (microseconds)", - "Worker Id (start number)", - "Phase Id (index in config file)" - }; - out.println(StringUtil.join(",", header)); - for (LatencyRecord.Sample s : results.getLatencySamples()) { - double startUs = ((double) s.getStartNanosecond() / (double) 1000000000); - String[] row = { - Integer.toString(s.getTransactionType()), - // Important! - // The TxnType offsets start at 1! - activeTXTypes.get(s.getTransactionType() - 1).getName(), - String.format("%10.6f", startUs - offset), - Integer.toString(s.getLatencyMicrosecond()), - Integer.toString(s.getWorkerId()), - Integer.toString(s.getPhaseId()), - }; - out.println(StringUtil.join(",", row)); - } + } + + public void writeRaw(List activeTXTypes, PrintStream out) { + + // This is needed because nanTime does not guarantee offset... we + // ground it (and round it) to ms from 1970-01-01 like currentTime + double x = ((double) System.nanoTime() / (double) 1000000000); + double y = ((double) System.currentTimeMillis() / (double) 1000); + double offset = x - y; + + // long startNs = latencySamples.get(0).startNs; + String[] header = { + "Transaction Type Index", + "Transaction Name", + "Start Time (microseconds)", + "Latency (microseconds)", + "Worker Id (start number)", + "Phase Id (index in config file)" + }; + out.println(StringUtil.join(",", header)); + for (LatencyRecord.Sample s : results.getLatencySamples()) { + double startUs = ((double) s.getStartNanosecond() / (double) 1000000000); + String[] row = { + Integer.toString(s.getTransactionType()), + // Important! + // The TxnType offsets start at 1! + activeTXTypes.get(s.getTransactionType() - 1).getName(), + String.format("%10.6f", startUs - offset), + Integer.toString(s.getLatencyMicrosecond()), + Integer.toString(s.getWorkerId()), + Integer.toString(s.getPhaseId()), + }; + out.println(StringUtil.join(",", row)); } - - + } } diff --git a/src/main/java/com/oltpbenchmark/util/RowRandomBoundedInt.java b/src/main/java/com/oltpbenchmark/util/RowRandomBoundedInt.java index 3ec59fd08..07a3cb4d8 100644 --- a/src/main/java/com/oltpbenchmark/util/RowRandomBoundedInt.java +++ b/src/main/java/com/oltpbenchmark/util/RowRandomBoundedInt.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -15,22 +15,21 @@ */ package com.oltpbenchmark.util; -public class RowRandomBoundedInt - extends RowRandomInt { - private final int lowValue; - private final int highValue; +public class RowRandomBoundedInt extends RowRandomInt { + private final int lowValue; + private final int highValue; - public RowRandomBoundedInt(long seed, int lowValue, int highValue) { - this(seed, lowValue, highValue, 1); - } + public RowRandomBoundedInt(long seed, int lowValue, int highValue) { + this(seed, lowValue, highValue, 1); + } - public RowRandomBoundedInt(long seed, int lowValue, int highValue, int seedsPerRow) { - super(seed, seedsPerRow); - this.lowValue = lowValue; - this.highValue = highValue; - } + public RowRandomBoundedInt(long seed, int lowValue, int highValue, int seedsPerRow) { + super(seed, seedsPerRow); + this.lowValue = lowValue; + this.highValue = highValue; + } - public int nextValue() { - return nextInt(lowValue, highValue); - } + public int nextValue() { + return nextInt(lowValue, highValue); + } } diff --git a/src/main/java/com/oltpbenchmark/util/RowRandomBoundedLong.java b/src/main/java/com/oltpbenchmark/util/RowRandomBoundedLong.java index c4aee8186..3b74deb77 100644 --- a/src/main/java/com/oltpbenchmark/util/RowRandomBoundedLong.java +++ b/src/main/java/com/oltpbenchmark/util/RowRandomBoundedLong.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,49 +16,50 @@ package com.oltpbenchmark.util; public class RowRandomBoundedLong { - private final RowRandomLong randomLong; - private final RowRandomInt randomInt; - - private final long lowValue; - private final long highValue; + private final RowRandomLong randomLong; + private final RowRandomInt randomInt; - public RowRandomBoundedLong(long seed, boolean use64Bits, long lowValue, long highValue) { - this(seed, use64Bits, lowValue, highValue, 1); - } + private final long lowValue; + private final long highValue; - public RowRandomBoundedLong(long seed, boolean use64Bits, long lowValue, long highValue, int seedsPerRow) { - if (use64Bits) { - this.randomLong = new RowRandomLong(seed, seedsPerRow); - this.randomInt = null; - } else { - this.randomLong = null; - this.randomInt = new RowRandomInt(seed, seedsPerRow); - } + public RowRandomBoundedLong(long seed, boolean use64Bits, long lowValue, long highValue) { + this(seed, use64Bits, lowValue, highValue, 1); + } - this.lowValue = lowValue; - this.highValue = highValue; + public RowRandomBoundedLong( + long seed, boolean use64Bits, long lowValue, long highValue, int seedsPerRow) { + if (use64Bits) { + this.randomLong = new RowRandomLong(seed, seedsPerRow); + this.randomInt = null; + } else { + this.randomLong = null; + this.randomInt = new RowRandomInt(seed, seedsPerRow); } - public long nextValue() { - if (randomLong != null) { - return randomLong.nextLong(lowValue, highValue); - } - return randomInt.nextInt((int) lowValue, (int) highValue); + this.lowValue = lowValue; + this.highValue = highValue; + } + + public long nextValue() { + if (randomLong != null) { + return randomLong.nextLong(lowValue, highValue); } + return randomInt.nextInt((int) lowValue, (int) highValue); + } - public void rowFinished() { - if (randomLong != null) { - randomLong.rowFinished(); - } else { - randomInt.rowFinished(); - } + public void rowFinished() { + if (randomLong != null) { + randomLong.rowFinished(); + } else { + randomInt.rowFinished(); } + } - public void advanceRows(long rowCount) { - if (randomLong != null) { - randomLong.advanceRows(rowCount); - } else { - randomInt.advanceRows(rowCount); - } + public void advanceRows(long rowCount) { + if (randomLong != null) { + randomLong.advanceRows(rowCount); + } else { + randomInt.advanceRows(rowCount); } + } } diff --git a/src/main/java/com/oltpbenchmark/util/RowRandomInt.java b/src/main/java/com/oltpbenchmark/util/RowRandomInt.java index d9dacc7a9..5de3eba85 100644 --- a/src/main/java/com/oltpbenchmark/util/RowRandomInt.java +++ b/src/main/java/com/oltpbenchmark/util/RowRandomInt.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,99 +16,94 @@ package com.oltpbenchmark.util; public class RowRandomInt { - private static final long MULTIPLIER = 16807; - private static final long MODULUS = 2147483647; - private static final long DEFAULT_SEED = 19620718; + private static final long MULTIPLIER = 16807; + private static final long MODULUS = 2147483647; + private static final long DEFAULT_SEED = 19620718; - private final int seedsPerRow; + private final int seedsPerRow; - private long seed; - private int usage; + private long seed; + private int usage; - /** - * Creates a new random number generator with the specified seed and - * specified number of random values per row. - */ - public RowRandomInt(long seed, int seedsPerRow) { - this.seed = seed; - this.seedsPerRow = seedsPerRow; - } + /** + * Creates a new random number generator with the specified seed and specified number of random + * values per row. + */ + public RowRandomInt(long seed, int seedsPerRow) { + this.seed = seed; + this.seedsPerRow = seedsPerRow; + } - /** - * Creates a new random generator with specified column number - * and specified number of random values per row. - * Seed is base + colnum * Constant. - */ - public RowRandomInt(int globalColumnNumber, int seedsPerRow) { - this(globalColumnNumber, DEFAULT_SEED, seedsPerRow); - } + /** + * Creates a new random generator with specified column number and specified number of random + * values per row. Seed is base + colnum * Constant. + */ + public RowRandomInt(int globalColumnNumber, int seedsPerRow) { + this(globalColumnNumber, DEFAULT_SEED, seedsPerRow); + } - /** - * Creates a new random generator with specified column number - * and specified number of random values per row. - * Seed is base + colnum * Constant. - */ - public RowRandomInt(int globalColumnNumber, long seed, int seedsPerRow) { - this.seed = seed + globalColumnNumber * (MODULUS / 799); - this.seedsPerRow = seedsPerRow; - } + /** + * Creates a new random generator with specified column number and specified number of random + * values per row. Seed is base + colnum * Constant. + */ + public RowRandomInt(int globalColumnNumber, long seed, int seedsPerRow) { + this.seed = seed + globalColumnNumber * (MODULUS / 799); + this.seedsPerRow = seedsPerRow; + } - /** - * Get a random value between lowValue (inclusive) and highValue (inclusive). - */ - public int nextInt(int lowValue, int highValue) { - nextRand(); + /** Get a random value between lowValue (inclusive) and highValue (inclusive). */ + public int nextInt(int lowValue, int highValue) { + nextRand(); - // This will result in overflow when high is max int and low is 0, - // which is a bug since you will get a value outside of the - // specified range. There is code that relies on this bug. - int intRange = highValue - lowValue + 1; - double doubleRange = (double) intRange; - int valueInRange = (int) ((1.0 * seed / MODULUS) * doubleRange); + // This will result in overflow when high is max int and low is 0, + // which is a bug since you will get a value outside of the + // specified range. There is code that relies on this bug. + int intRange = highValue - lowValue + 1; + double doubleRange = (double) intRange; + int valueInRange = (int) ((1.0 * seed / MODULUS) * doubleRange); - return lowValue + valueInRange; - } + return lowValue + valueInRange; + } - public long nextRand() { - seed = (seed * MULTIPLIER) % MODULUS; - usage++; - return seed; - } - - /** - * Advances the random number generator to the start of the sequence for - * the next row. Each row uses a specified number of random values, so the - * random number generator can be quickly advanced for partitioned data - * sets. - */ - public void rowFinished() { - advanceSeed(seedsPerRow - usage); - usage = 0; - } + public long nextRand() { + seed = (seed * MULTIPLIER) % MODULUS; + usage++; + return seed; + } - /** - * Advance the specified number of rows. Advancing to a specific row is - * needed for partitioned data sets. - */ - public void advanceRows(long rowCount) { - // finish the current row - if (usage != 0) { - rowFinished(); - } + /** + * Advances the random number generator to the start of the sequence for the next row. Each row + * uses a specified number of random values, so the random number generator can be quickly + * advanced for partitioned data sets. + */ + public void rowFinished() { + advanceSeed(seedsPerRow - usage); + usage = 0; + } - // advance the seed - advanceSeed(seedsPerRow * rowCount); + /** + * Advance the specified number of rows. Advancing to a specific row is needed for partitioned + * data sets. + */ + public void advanceRows(long rowCount) { + // finish the current row + if (usage != 0) { + rowFinished(); } - private void advanceSeed(long count) { - long multiplier = MULTIPLIER; - while (count > 0) { - if (count % 2 != 0) { - seed = (multiplier * seed) % MODULUS; - } - // integer division, truncates - count = count / 2; - multiplier = (multiplier * multiplier) % MODULUS; - } + // advance the seed + advanceSeed(seedsPerRow * rowCount); + } + + private void advanceSeed(long count) { + long multiplier = MULTIPLIER; + while (count > 0) { + if (count % 2 != 0) { + seed = (multiplier * seed) % MODULUS; + } + // integer division, truncates + count = count / 2; + multiplier = (multiplier * multiplier) % MODULUS; } + } } diff --git a/src/main/java/com/oltpbenchmark/util/RowRandomLong.java b/src/main/java/com/oltpbenchmark/util/RowRandomLong.java index c0e5275dc..a44986cfb 100644 --- a/src/main/java/com/oltpbenchmark/util/RowRandomLong.java +++ b/src/main/java/com/oltpbenchmark/util/RowRandomLong.java @@ -1,6 +1,6 @@ /* * Copyright 2020 Trino - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,78 +16,75 @@ package com.oltpbenchmark.util; public class RowRandomLong { - private static final long MULTIPLIER = 6364136223846793005L; - private static final long INCREMENT = 1; + private static final long MULTIPLIER = 6364136223846793005L; + private static final long INCREMENT = 1; - private final int seedsPerRow; + private final int seedsPerRow; - private long seed; - private int usage; + private long seed; + private int usage; - /** - * Creates a new random number generator with the specified seed and - * specified number of random values per row. - */ - public RowRandomLong(long seed, int seedsPerRow) { - this.seed = seed; - this.seedsPerRow = seedsPerRow; - } + /** + * Creates a new random number generator with the specified seed and specified number of random + * values per row. + */ + public RowRandomLong(long seed, int seedsPerRow) { + this.seed = seed; + this.seedsPerRow = seedsPerRow; + } - /** - * Get a random value between lowValue (inclusive) and highValue (inclusive). - */ - protected long nextLong(long lowValue, long highValue) { - nextRand(); + /** Get a random value between lowValue (inclusive) and highValue (inclusive). */ + protected long nextLong(long lowValue, long highValue) { + nextRand(); - long valueInRange = Math.abs(seed) % (highValue - lowValue + 1); + long valueInRange = Math.abs(seed) % (highValue - lowValue + 1); - return lowValue + valueInRange; - } + return lowValue + valueInRange; + } - protected long nextRand() { - seed = (seed * MULTIPLIER) + INCREMENT; - usage++; - return seed; - } + protected long nextRand() { + seed = (seed * MULTIPLIER) + INCREMENT; + usage++; + return seed; + } - /** - * Advances the random number generator to the start of the sequence for - * the next row. Each row uses a specified number of random values, so the - * random number generator can be quickly advanced for partitioned data - * sets. - */ - public void rowFinished() { - advanceSeed32(seedsPerRow - usage); - usage = 0; - } - - /** - * Advance the specified number of rows. Advancing to a specific row is - * needed for partitioned data sets. - */ - public void advanceRows(long rowCount) { - // finish the current row - if (usage != 0) { - rowFinished(); - } + /** + * Advances the random number generator to the start of the sequence for the next row. Each row + * uses a specified number of random values, so the random number generator can be quickly + * advanced for partitioned data sets. + */ + public void rowFinished() { + advanceSeed32(seedsPerRow - usage); + usage = 0; + } - // advance the seed - advanceSeed32(seedsPerRow * rowCount); + /** + * Advance the specified number of rows. Advancing to a specific row is needed for partitioned + * data sets. + */ + public void advanceRows(long rowCount) { + // finish the current row + if (usage != 0) { + rowFinished(); } - private static final long MULTIPLIER_32 = 16807; - private static final long MODULUS_32 = 2147483647; + // advance the seed + advanceSeed32(seedsPerRow * rowCount); + } + + private static final long MULTIPLIER_32 = 16807; + private static final long MODULUS_32 = 2147483647; - private void advanceSeed32(long count) { - long multiplier = MULTIPLIER_32; - while (count > 0) { - // testing for oddness, this seems portable - if (count % 2 != 0) { - seed = (multiplier * seed) % MODULUS_32; - } - // integer division, truncates - count = count / 2; - multiplier = (multiplier * multiplier) % MODULUS_32; - } + private void advanceSeed32(long count) { + long multiplier = MULTIPLIER_32; + while (count > 0) { + // testing for oddness, this seems portable + if (count % 2 != 0) { + seed = (multiplier * seed) % MODULUS_32; + } + // integer division, truncates + count = count / 2; + multiplier = (multiplier * multiplier) % MODULUS_32; } + } } diff --git a/src/main/java/com/oltpbenchmark/util/SQLUtil.java b/src/main/java/com/oltpbenchmark/util/SQLUtil.java index 9574d6f3c..7a157a941 100644 --- a/src/main/java/com/oltpbenchmark/util/SQLUtil.java +++ b/src/main/java/com/oltpbenchmark/util/SQLUtil.java @@ -21,651 +21,672 @@ import com.oltpbenchmark.catalog.*; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.types.SortDirectionType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; -import java.sql.Date; import java.sql.*; +import java.sql.Date; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class SQLUtil { - private static final Logger LOG = LoggerFactory.getLogger(SQLUtil.class); - - private static final DateFormat[] timestamp_formats = new DateFormat[]{ - new SimpleDateFormat("yyyy-MM-dd"), - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"), - }; - - /** - * Return a long from the given object - * Handles the different cases from the various DBMSs - * - * @param obj - * @return - */ - public static Long getLong(Object obj) { - if (obj == null) { - return (null); - } + private static final Logger LOG = LoggerFactory.getLogger(SQLUtil.class); + + private static final DateFormat[] timestamp_formats = + new DateFormat[] { + new SimpleDateFormat("yyyy-MM-dd"), + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"), + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"), + }; + + /** + * Return a long from the given object Handles the different cases from the various DBMSs + * + * @param obj + * @return + */ + public static Long getLong(Object obj) { + if (obj == null) { + return (null); + } - if (obj instanceof Long) { - return (Long) obj; - } else if (obj instanceof Integer) { - return ((Integer) obj).longValue(); - } else if (obj instanceof BigDecimal) { - return ((BigDecimal) obj).longValue(); - } + if (obj instanceof Long) { + return (Long) obj; + } else if (obj instanceof Integer) { + return ((Integer) obj).longValue(); + } else if (obj instanceof BigDecimal) { + return ((BigDecimal) obj).longValue(); + } + + LOG.warn("BAD BAD BAD: returning null because getLong does not support {}", obj.getClass()); - LOG.warn("BAD BAD BAD: returning null because getLong does not support {}", obj.getClass()); + return (null); + } - return (null); + public static Integer getInteger(Object obj) { + if (obj == null) { + return (null); } - public static Integer getInteger(Object obj) { - if (obj == null) { - return (null); - } + if (obj instanceof Integer) { + return (Integer) obj; + } else if (obj instanceof Long) { + return ((Long) obj).intValue(); + } else if (obj instanceof BigDecimal) { + return ((BigDecimal) obj).intValue(); + } - if (obj instanceof Integer) { - return (Integer) obj; - } else if (obj instanceof Long) { - return ((Long) obj).intValue(); - } else if (obj instanceof BigDecimal) { - return ((BigDecimal) obj).intValue(); - } + LOG.warn("BAD BAD BAD: returning null because getInteger does not support {}", obj.getClass()); - LOG.warn("BAD BAD BAD: returning null because getInteger does not support {}", obj.getClass()); + return (null); + } - return (null); + /** + * Return a double from the given object Handles the different cases from the various DBMSs + * + * @param obj + * @return + */ + public static Double getDouble(Object obj) { + if (obj == null) { + return (null); } - /** - * Return a double from the given object - * Handles the different cases from the various DBMSs - * - * @param obj - * @return - */ - public static Double getDouble(Object obj) { - if (obj == null) { - return (null); - } + if (obj instanceof Double) { + return (Double) obj; + } else if (obj instanceof Float) { + return ((Float) obj).doubleValue(); + } else if (obj instanceof BigDecimal) { + return ((BigDecimal) obj).doubleValue(); + } - if (obj instanceof Double) { - return (Double) obj; - } else if (obj instanceof Float) { - return ((Float) obj).doubleValue(); - } else if (obj instanceof BigDecimal) { - return ((BigDecimal) obj).doubleValue(); - } + LOG.warn("BAD BAD BAD: returning null because getDouble does not support {}", obj.getClass()); - LOG.warn("BAD BAD BAD: returning null because getDouble does not support {}", obj.getClass()); + return (null); + } - return (null); + public static String clobToString(Object obj) { + try { + Clob clob = (Clob) obj; + return clob.getSubString(1, (int) clob.length()); + } catch (SQLException e) { + throw new RuntimeException(e); } + } - public static String clobToString(Object obj) { - try { - Clob clob = (Clob) obj; - return clob.getSubString(1, (int) clob.length()); - } catch (SQLException e) { - throw new RuntimeException(e); - } + public static String getString(Object obj) { + if (obj == null) { + return (null); } - public static String getString(Object obj) { - if (obj == null) { - return (null); - } - - if (obj instanceof String) { - return (String) obj; - } else if (obj instanceof BigDecimal bigDecimal) { - return bigDecimal.toString(); - } + if (obj instanceof String) { + return (String) obj; + } else if (obj instanceof BigDecimal bigDecimal) { + return bigDecimal.toString(); + } - LOG.warn("BAD BAD BAD: returning null because getString does not support {}", obj.getClass()); - - return (null); - } - - /** - * Support for Oracle DB introduced TIMESTAMP fields in Oracle DDL (for example, auctionmark CONFIG_PROFILE table), - * which results in OJDBC-specific {@code oracle.sql.TIMESTAMP} object. - * {@link #getTimestamp(Object)} needs to be able to convert {@code oracle.sql.TIMESTAMP} into {@code java.sql.TIMESTAMP}. - * - * The main issue is that {@code oracle.sql.TIMESTAMP} is not available in JDBC, so trying to import and resolve the - * type normally will break other database profiles. - * This can be solved by loading OJDBC-specific class + method reflectively. - */ - private static final Class ORACLE_TIMESTAMP; - private static final Method TIMESTAMP_VALUE_METHOD; - static { - Method timestampValueMethod; - Class oracleTimestamp; - try { - // If oracle.sql.TIMESTAMP can be loaded - oracleTimestamp = Class.forName("oracle.sql.TIMESTAMP"); - // Then java.sql.Timestamp oracle.sql.TIMESTAMP.timestampValue() can be loaded - timestampValueMethod = oracleTimestamp.getDeclaredMethod("timestampValue"); - } catch (ClassNotFoundException | NoSuchMethodException e) { - oracleTimestamp = null; - timestampValueMethod = null; - } - // If loading is successful then both variables won't be null. - TIMESTAMP_VALUE_METHOD = timestampValueMethod; - ORACLE_TIMESTAMP = oracleTimestamp; - } - - /** - * Return a double from the given object - * Handles the different cases from the various DBMSs - * - * @param obj - * @return - */ - public static Timestamp getTimestamp(Object obj) { - if (obj == null) { - return (null); - } + LOG.warn("BAD BAD BAD: returning null because getString does not support {}", obj.getClass()); + + return (null); + } + + /** + * Support for Oracle DB introduced TIMESTAMP fields in Oracle DDL (for example, auctionmark + * CONFIG_PROFILE table), which results in OJDBC-specific {@code oracle.sql.TIMESTAMP} object. + * {@link #getTimestamp(Object)} needs to be able to convert {@code oracle.sql.TIMESTAMP} into + * {@code java.sql.TIMESTAMP}. + * + *

The main issue is that {@code oracle.sql.TIMESTAMP} is not available in JDBC, so trying to + * import and resolve the type normally will break other database profiles. This can be solved by + * loading OJDBC-specific class + method reflectively. + */ + private static final Class ORACLE_TIMESTAMP; + + private static final Method TIMESTAMP_VALUE_METHOD; + + static { + Method timestampValueMethod; + Class oracleTimestamp; + try { + // If oracle.sql.TIMESTAMP can be loaded + oracleTimestamp = Class.forName("oracle.sql.TIMESTAMP"); + // Then java.sql.Timestamp oracle.sql.TIMESTAMP.timestampValue() can be loaded + timestampValueMethod = oracleTimestamp.getDeclaredMethod("timestampValue"); + } catch (ClassNotFoundException | NoSuchMethodException e) { + oracleTimestamp = null; + timestampValueMethod = null; + } + // If loading is successful then both variables won't be null. + TIMESTAMP_VALUE_METHOD = timestampValueMethod; + ORACLE_TIMESTAMP = oracleTimestamp; + } + + /** + * Return a double from the given object Handles the different cases from the various DBMSs + * + * @param obj + * @return + */ + public static Timestamp getTimestamp(Object obj) { + if (obj == null) { + return (null); + } - if (obj instanceof Timestamp) { - return (Timestamp) obj; - } else if (obj instanceof Date) { - return new Timestamp(((Date) obj).getTime()); - } else if (ORACLE_TIMESTAMP != null && ORACLE_TIMESTAMP.isInstance(obj)) { - try { - // https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/sql/TIMESTAMP.html#timestampValue__ - return (Timestamp) TIMESTAMP_VALUE_METHOD.invoke(ORACLE_TIMESTAMP.cast(obj)); - } catch (IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } + if (obj instanceof Timestamp) { + return (Timestamp) obj; + } else if (obj instanceof Date) { + return new Timestamp(((Date) obj).getTime()); + } else if (ORACLE_TIMESTAMP != null && ORACLE_TIMESTAMP.isInstance(obj)) { + try { + // https://docs.oracle.com/en/database/oracle/oracle-database/21/jajdb/oracle/sql/TIMESTAMP.html#timestampValue__ + return (Timestamp) TIMESTAMP_VALUE_METHOD.invoke(ORACLE_TIMESTAMP.cast(obj)); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } - Long timestamp = SQLUtil.getLong(obj); - return (timestamp != null ? new Timestamp(timestamp) : null); - } - - /** - * Return the internal sequence name for the given Column - * - * @param conn - * @param dbType - * @param catalog_col - * @return - */ - public static String getSequenceName(Connection conn, DatabaseType dbType, Column catalog_col) throws SQLException { - Table catalog_tbl = catalog_col.getTable(); - - String seqName = null; - String sql = null; - if (dbType == DatabaseType.POSTGRES) { - sql = String.format("SELECT pg_get_serial_sequence('%s', '%s')", - catalog_tbl.getName(), catalog_col.getName()); - } else if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { - // NOTE: This likely only handles certain syntaxes for defaults. - sql = String.format(""" + Long timestamp = SQLUtil.getLong(obj); + return (timestamp != null ? new Timestamp(timestamp) : null); + } + + /** + * Return the internal sequence name for the given Column + * + * @param conn + * @param dbType + * @param catalog_col + * @return + */ + public static String getSequenceName(Connection conn, DatabaseType dbType, Column catalog_col) + throws SQLException { + Table catalog_tbl = catalog_col.getTable(); + + String seqName = null; + String sql = null; + if (dbType == DatabaseType.POSTGRES) { + sql = + String.format( + "SELECT pg_get_serial_sequence('%s', '%s')", + catalog_tbl.getName(), catalog_col.getName()); + } else if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { + // NOTE: This likely only handles certain syntaxes for defaults. + sql = + String.format( + """ SELECT REPLACE(REPLACE([definition], '(NEXT VALUE FOR [', ''), '])', '') AS seq FROM sys.default_constraints dc JOIN sys.columns c ON c.default_object_id=dc.object_id JOIN sys.tables t ON c.object_id=t.object_id WHERE t.name='%s' AND c.name='%s' """, - catalog_tbl.getName(), catalog_col.getName()); - } else { - if (LOG.isDebugEnabled()) { - LOG.debug("Unexpected request for sequence name on {} using {}", catalog_col, dbType); - } - } - - if (sql != null) { - try (Statement stmt = conn.createStatement()) { - try (ResultSet result = stmt.executeQuery(sql)) { - if (result.next()) { - seqName = result.getString(1); - } - } - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s => [%s]", sql, seqName)); - } - } - } + catalog_tbl.getName(), catalog_col.getName()); + } else { + if (LOG.isDebugEnabled()) { + LOG.debug("Unexpected request for sequence name on {} using {}", catalog_col, dbType); + } + } - return seqName; - } - - /** - * Mark the given table which has an identity column to be able to be - * inserted into with explicit values. - * - * @param conn - * @param dbType - * @param catalog_tbl - * @param on - */ - public static void setIdentityInsert(Connection conn, DatabaseType dbType, Table catalog_tbl, boolean on) throws SQLException { - String sql = null; - if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { - sql = "SET IDENTITY_INSERT " + catalog_tbl.getName() + " " + (on ? "ON" : "OFF"); + if (sql != null) { + try (Statement stmt = conn.createStatement()) { + try (ResultSet result = stmt.executeQuery(sql)) { + if (result.next()) { + seqName = result.getString(1); + } } - - if (sql != null) { - try (Statement stmt = conn.createStatement()) { - boolean result = stmt.execute(sql); - if (LOG.isDebugEnabled()) { - LOG.debug(String.format("%s => [%s]", sql, result)); - SQLWarning warnings = stmt.getWarnings(); - if (warnings != null) { - LOG.debug(warnings.toString()); - } - } - } + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s => [%s]", sql, seqName)); } + } } - public static Object[] getRowAsArray(ResultSet rs) throws SQLException { - ResultSetMetaData rs_md = rs.getMetaData(); - int num_cols = rs_md.getColumnCount(); - Object[] data = new Object[num_cols]; - for (int i = 0; i < num_cols; i++) { - data[i] = rs.getObject(i + 1); - } - return data; + return seqName; + } + + /** + * Mark the given table which has an identity column to be able to be inserted into with explicit + * values. + * + * @param conn + * @param dbType + * @param catalog_tbl + * @param on + */ + public static void setIdentityInsert( + Connection conn, DatabaseType dbType, Table catalog_tbl, boolean on) throws SQLException { + String sql = null; + if (dbType == DatabaseType.SQLSERVER || dbType == DatabaseType.SQLAZURE) { + sql = "SET IDENTITY_INSERT " + catalog_tbl.getName() + " " + (on ? "ON" : "OFF"); } - public static List toList(ResultSet rs) throws SQLException { - ResultSetMetaData rs_md = rs.getMetaData(); - int num_cols = rs_md.getColumnCount(); - - List results = new ArrayList<>(); - while (rs.next()) { - Object[] row = new Object[num_cols]; - for (int i = 0; i < num_cols; i++) { - row[i] = rs.getObject(i + 1); - } - results.add(row); - } + if (sql != null) { + try (Statement stmt = conn.createStatement()) { + boolean result = stmt.execute(sql); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("%s => [%s]", sql, result)); + SQLWarning warnings = stmt.getWarnings(); + if (warnings != null) { + LOG.debug(warnings.toString()); + } + } + } + } + } + + public static Object[] getRowAsArray(ResultSet rs) throws SQLException { + ResultSetMetaData rs_md = rs.getMetaData(); + int num_cols = rs_md.getColumnCount(); + Object[] data = new Object[num_cols]; + for (int i = 0; i < num_cols; i++) { + data[i] = rs.getObject(i + 1); + } + return data; + } + + public static List toList(ResultSet rs) throws SQLException { + ResultSetMetaData rs_md = rs.getMetaData(); + int num_cols = rs_md.getColumnCount(); + + List results = new ArrayList<>(); + while (rs.next()) { + Object[] row = new Object[num_cols]; + for (int i = 0; i < num_cols; i++) { + row[i] = rs.getObject(i + 1); + } + results.add(row); + } - return results; - } - - /** - * For the given string representation of a value, convert it to the proper - * object based on its sqlType - * - * @param sqlType - * @param value - * @return - * @see java.sql.Types - */ - public static Object castValue(int sqlType, String value) { - Object ret = null; - switch (sqlType) { - case Types.CHAR: - case Types.VARCHAR: - case Types.NCHAR: - case Types.NVARCHAR: { - ret = value; - break; - } - case Types.TINYINT: - case Types.SMALLINT: { - ret = Short.parseShort(value); - break; - } - case Types.INTEGER: { - ret = Integer.parseInt(value); - break; - } - case Types.BIGINT: { - ret = Long.parseLong(value); - break; - } - case Types.BOOLEAN: { - ret = Boolean.parseBoolean(value); - break; - } - case Types.DECIMAL: - case Types.REAL: - case Types.NUMERIC: - case Types.DOUBLE: { - ret = Double.parseDouble(value); - break; - } - case Types.FLOAT: { - ret = Float.parseFloat(value); - break; - } - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: { - for (DateFormat f : timestamp_formats) { - try { - ret = f.parse(value); - } catch (ParseException ex) { - // Ignore... - } - if (ret != null) { - break; - } - } - if (ret == null) { - throw new RuntimeException("Failed to parse timestamp '" + value + "'"); - } - break; + return results; + } + + /** + * For the given string representation of a value, convert it to the proper object based on its + * sqlType + * + * @param sqlType + * @param value + * @return + * @see java.sql.Types + */ + public static Object castValue(int sqlType, String value) { + Object ret = null; + switch (sqlType) { + case Types.CHAR: + case Types.VARCHAR: + case Types.NCHAR: + case Types.NVARCHAR: + { + ret = value; + break; + } + case Types.TINYINT: + case Types.SMALLINT: + { + ret = Short.parseShort(value); + break; + } + case Types.INTEGER: + { + ret = Integer.parseInt(value); + break; + } + case Types.BIGINT: + { + ret = Long.parseLong(value); + break; + } + case Types.BOOLEAN: + { + ret = Boolean.parseBoolean(value); + break; + } + case Types.DECIMAL: + case Types.REAL: + case Types.NUMERIC: + case Types.DOUBLE: + { + ret = Double.parseDouble(value); + break; + } + case Types.FLOAT: + { + ret = Float.parseFloat(value); + break; + } + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + { + for (DateFormat f : timestamp_formats) { + try { + ret = f.parse(value); + } catch (ParseException ex) { + // Ignore... } - default: - LOG.warn("Unexpected SQL Type '{}' for value '{}'", sqlType, value); - } - return (ret); - } - - /** - * Returns true if the given sqlType identifier is a String data type - * - * @param sqlType - * @return - * @see java.sql.Types - */ - public static boolean isStringType(int sqlType) { - switch (sqlType) { - case Types.CHAR: - case Types.VARCHAR: - case Types.NCHAR: - case Types.NVARCHAR: { - return (true); + if (ret != null) { + break; } - default: - return (false); - } + } + if (ret == null) { + throw new RuntimeException("Failed to parse timestamp '" + value + "'"); + } + break; + } + default: + LOG.warn("Unexpected SQL Type '{}' for value '{}'", sqlType, value); } - - /** - * Returns true if the given sqlType identifier is an Integer data type - * - * @param sqlType - * @return - * @see java.sql.Types - */ - public static boolean isIntegerType(int sqlType) { - switch (sqlType) { - case Types.TINYINT: - case Types.SMALLINT: - case Types.INTEGER: - case Types.BIGINT: { - return (true); - } - default: - return (false); - } + return (ret); + } + + /** + * Returns true if the given sqlType identifier is a String data type + * + * @param sqlType + * @return + * @see java.sql.Types + */ + public static boolean isStringType(int sqlType) { + switch (sqlType) { + case Types.CHAR: + case Types.VARCHAR: + case Types.NCHAR: + case Types.NVARCHAR: + { + return (true); + } + default: + return (false); } + } + + /** + * Returns true if the given sqlType identifier is an Integer data type + * + * @param sqlType + * @return + * @see java.sql.Types + */ + public static boolean isIntegerType(int sqlType) { + switch (sqlType) { + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: + { + return (true); + } + default: + return (false); + } + } + + /** + * Return the COUNT(*) SQL to calculate the number of records + * + * @param dbType + * @param catalog_tbl + * @return SQL for select count execution + */ + public static String getCountSQL(DatabaseType dbType, Table catalog_tbl) { + return SQLUtil.getCountSQL(dbType, catalog_tbl, "*"); + } + + /** + * Return the COUNT() SQL to calculate the number of records. Will use the col parameter as the + * column that is counted + * + * @param dbType + * @param catalog_tbl + * @param col + * @return SQL for select count execution + */ + public static String getCountSQL(DatabaseType dbType, Table catalog_tbl, String col) { + String tableName = + (dbType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); + return String.format("SELECT COUNT(%s) FROM %s", col, tableName.trim()); + } + + /** + * Automatically generate the 'INSERT' SQL string for this table with a batch size of 1 + * + * @param catalog_tbl + * @param db_type + * @param exclude_columns + * @return + */ + public static String getInsertSQL( + Table catalog_tbl, DatabaseType db_type, int... exclude_columns) { + return SQLUtil.getInsertSQL(catalog_tbl, db_type, 1, exclude_columns); + } + + /** + * Automatically generate the 'INSERT' SQL string for this table + * + * @param catalog_tbl + * @param db_type + * @param batchSize the number of sets of parameters that should be included in the insert + * @param exclude_columns + * @return + */ + public static String getInsertSQL( + Table catalog_tbl, DatabaseType db_type, int batchSize, int... exclude_columns) { + boolean show_cols = db_type.shouldIncludeColumnNames(); + boolean escape_names = db_type.shouldEscapeNames(); + + StringBuilder sb = new StringBuilder(); + if (db_type.equals(DatabaseType.PHOENIX)) { + sb.append("UPSERT"); + } else { + sb.append("INSERT"); + } + sb.append(" INTO ").append(escape_names ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); - /** - * Return the COUNT(*) SQL to calculate the number of records - * - * @param dbType - * @param catalog_tbl - * @return SQL for select count execution - */ - public static String getCountSQL(DatabaseType dbType, Table catalog_tbl) { - return SQLUtil.getCountSQL(dbType, catalog_tbl, "*"); - } - - /** - * Return the COUNT() SQL to calculate the number of records. - * Will use the col parameter as the column that is counted - * - * @param dbType - * @param catalog_tbl - * @param col - * @return SQL for select count execution - */ - public static String getCountSQL(DatabaseType dbType, Table catalog_tbl, String col) { - String tableName = (dbType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); - return String.format("SELECT COUNT(%s) FROM %s", col, tableName.trim()); - } - - /** - * Automatically generate the 'INSERT' SQL string for this table - * with a batch size of 1 - * - * @param catalog_tbl - * @param db_type - * @param exclude_columns - * @return - */ - public static String getInsertSQL(Table catalog_tbl, DatabaseType db_type, int... exclude_columns) { - return SQLUtil.getInsertSQL(catalog_tbl, db_type, 1, exclude_columns); - } - - /** - * Automatically generate the 'INSERT' SQL string for this table - * - * @param catalog_tbl - * @param db_type - * @param batchSize the number of sets of parameters - * that should be included in the insert - * @param exclude_columns - * @return - */ - public static String getInsertSQL(Table catalog_tbl, DatabaseType db_type, int batchSize, int... exclude_columns) { - boolean show_cols = db_type.shouldIncludeColumnNames(); - boolean escape_names = db_type.shouldEscapeNames(); - - StringBuilder sb = new StringBuilder(); - if(db_type.equals(DatabaseType.PHOENIX)) { - sb.append("UPSERT"); - } else { - sb.append("INSERT"); - } - sb.append(" INTO ") - .append(escape_names ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); - - StringBuilder values = new StringBuilder(); - boolean first; + StringBuilder values = new StringBuilder(); + boolean first; - // Column Names - // XXX: Disabled because of case issues with HSQLDB - if (show_cols) { - sb.append(" ("); - } - first = true; + // Column Names + // XXX: Disabled because of case issues with HSQLDB + if (show_cols) { + sb.append(" ("); + } + first = true; - // These are the column offset that we want to exclude - Set excluded = new HashSet<>(); - for (int ex : exclude_columns) { - excluded.add(ex); - } + // These are the column offset that we want to exclude + Set excluded = new HashSet<>(); + for (int ex : exclude_columns) { + excluded.add(ex); + } - for (Column catalog_col : catalog_tbl.getColumns()) { - if (excluded.contains(catalog_col.getIndex())) { - continue; - } - if (!first) { - if (show_cols) { - sb.append(", "); - } - values.append(", "); - } - if (show_cols) { - sb.append(escape_names ? catalog_col.getEscapedName() : catalog_col.getName()); - } - values.append("?"); - first = false; - } + for (Column catalog_col : catalog_tbl.getColumns()) { + if (excluded.contains(catalog_col.getIndex())) { + continue; + } + if (!first) { if (show_cols) { - sb.append(")"); - } - - // Values - sb.append(" VALUES "); - for (int i = 0; i < batchSize; i++) { - sb.append("(").append(values.toString()).append(")"); - } - - return (sb.toString()); + sb.append(", "); + } + values.append(", "); + } + if (show_cols) { + sb.append(escape_names ? catalog_col.getEscapedName() : catalog_col.getName()); + } + values.append("?"); + first = false; + } + if (show_cols) { + sb.append(")"); } - public static String getMaxColSQL(DatabaseType dbType, Table catalog_tbl, String col) { - String tableName = (dbType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); - return String.format("SELECT MAX(%s) FROM %s", col, tableName); + // Values + sb.append(" VALUES "); + for (int i = 0; i < batchSize; i++) { + sb.append("(").append(values.toString()).append(")"); } - public static String selectColValues(DatabaseType databaseType, Table catalog_tbl, String col) { - String tableName = (databaseType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); - return String.format("SELECT %s FROM %s", - col, tableName); + return (sb.toString()); + } + + public static String getMaxColSQL(DatabaseType dbType, Table catalog_tbl, String col) { + String tableName = + (dbType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); + return String.format("SELECT MAX(%s) FROM %s", col, tableName); + } + + public static String selectColValues(DatabaseType databaseType, Table catalog_tbl, String col) { + String tableName = + (databaseType.shouldEscapeNames() ? catalog_tbl.getEscapedName() : catalog_tbl.getName()); + return String.format("SELECT %s FROM %s", col, tableName); + } + + /** Extract the catalog from the database. */ + public static AbstractCatalog getCatalog( + BenchmarkModule benchmarkModule, DatabaseType databaseType, Connection connection) + throws SQLException { + switch (databaseType) { + case NOISEPAGE: // fall-through + case HSQLDB: + return getCatalogHSQLDB(benchmarkModule); + default: + return getCatalogDirect(databaseType, connection); + } + } + + /** + * Create an in-memory instance of HSQLDB to extract all of the catalog information. + * + *

This supports databases that may not support all of the SQL standard just yet. + * + * @return + */ + private static AbstractCatalog getCatalogHSQLDB(BenchmarkModule benchmarkModule) { + return new HSQLDBCatalog(benchmarkModule); + } + + /** Extract catalog information from the database directly. */ + private static AbstractCatalog getCatalogDirect(DatabaseType databaseType, Connection connection) + throws SQLException { + DatabaseMetaData md = connection.getMetaData(); + + String separator = md.getIdentifierQuoteString(); + String catalog = connection.getCatalog(); + String schema = connection.getSchema(); + + Map tables = new HashMap<>(); + + List excludedColumns = new ArrayList<>(); + + if (databaseType.equals(DatabaseType.COCKROACHDB)) { + // cockroachdb has a hidden column called "ROWID" that should not be directly used via the + // catalog + excludedColumns.add("ROWID"); } - /** - * Extract the catalog from the database. - */ - public static AbstractCatalog getCatalog(BenchmarkModule benchmarkModule, DatabaseType databaseType, Connection connection) throws SQLException { - switch (databaseType) { - case NOISEPAGE: // fall-through - case HSQLDB: - return getCatalogHSQLDB(benchmarkModule); - default: - return getCatalogDirect(databaseType, connection); + try (ResultSet table_rs = md.getTables(catalog, schema, null, new String[] {"TABLE"})) { + while (table_rs.next()) { + + String table_type = table_rs.getString("TABLE_TYPE"); + if (!table_type.equalsIgnoreCase("TABLE")) { + continue; } - } - /** - * Create an in-memory instance of HSQLDB to extract all of the catalog information. - *

- * This supports databases that may not support all of the SQL standard just yet. - * - * @return - */ - private static AbstractCatalog getCatalogHSQLDB(BenchmarkModule benchmarkModule) { - return new HSQLDBCatalog(benchmarkModule); - } + String table_name = table_rs.getString("TABLE_NAME"); + Table catalog_tbl = new Table(table_name, separator); - /** - * Extract catalog information from the database directly. - */ - private static AbstractCatalog getCatalogDirect(DatabaseType databaseType, Connection connection) throws SQLException { - DatabaseMetaData md = connection.getMetaData(); + try (ResultSet col_rs = md.getColumns(catalog, schema, table_name, null)) { + while (col_rs.next()) { + String col_name = col_rs.getString("COLUMN_NAME"); - String separator = md.getIdentifierQuoteString(); - String catalog = connection.getCatalog(); - String schema = connection.getSchema(); + if (excludedColumns.contains(col_name.toUpperCase())) { + LOG.debug( + "found excluded column [{}] for in database type [{}]. Skipping...", + col_name, + databaseType); + continue; + } - Map tables = new HashMap<>(); + int col_type = col_rs.getInt("DATA_TYPE"); + Integer col_size = col_rs.getInt("COLUMN_SIZE"); + boolean col_nullable = col_rs.getString("IS_NULLABLE").equalsIgnoreCase("YES"); - List excludedColumns = new ArrayList<>(); + Column catalog_col = + new Column(col_name, separator, catalog_tbl, col_type, col_size, col_nullable); - if (databaseType.equals(DatabaseType.COCKROACHDB)) { - // cockroachdb has a hidden column called "ROWID" that should not be directly used via the catalog - excludedColumns.add("ROWID"); + catalog_tbl.addColumn(catalog_col); + } } + try (ResultSet idx_rs = md.getIndexInfo(catalog, schema, table_name, false, false)) { + while (idx_rs.next()) { + int idx_type = idx_rs.getShort("TYPE"); + if (idx_type == DatabaseMetaData.tableIndexStatistic) { + continue; + } + boolean idx_unique = (!idx_rs.getBoolean("NON_UNIQUE")); + String idx_name = idx_rs.getString("INDEX_NAME"); + int idx_col_pos = idx_rs.getInt("ORDINAL_POSITION") - 1; + String idx_col_name = idx_rs.getString("COLUMN_NAME"); + String sort = idx_rs.getString("ASC_OR_DESC"); + SortDirectionType idx_direction; + if (sort != null) { + idx_direction = + sort.equalsIgnoreCase("A") ? SortDirectionType.ASC : SortDirectionType.DESC; + } else { + idx_direction = null; + } - try (ResultSet table_rs = md.getTables(catalog, schema, null, new String[]{"TABLE"})) { - while (table_rs.next()) { - - String table_type = table_rs.getString("TABLE_TYPE"); - if (!table_type.equalsIgnoreCase("TABLE")) { - continue; - } - - String table_name = table_rs.getString("TABLE_NAME"); - Table catalog_tbl = new Table(table_name, separator); - - try (ResultSet col_rs = md.getColumns(catalog, schema, table_name, null)) { - while (col_rs.next()) { - String col_name = col_rs.getString("COLUMN_NAME"); - - if (excludedColumns.contains(col_name.toUpperCase())) { - LOG.debug("found excluded column [{}] for in database type [{}]. Skipping...", col_name, databaseType); - continue; - } - - int col_type = col_rs.getInt("DATA_TYPE"); - Integer col_size = col_rs.getInt("COLUMN_SIZE"); - boolean col_nullable = col_rs.getString("IS_NULLABLE").equalsIgnoreCase("YES"); - - Column catalog_col = new Column(col_name, separator, catalog_tbl, col_type, col_size, col_nullable); - - catalog_tbl.addColumn(catalog_col); - } - } - - try (ResultSet idx_rs = md.getIndexInfo(catalog, schema, table_name, false, false)) { - while (idx_rs.next()) { - int idx_type = idx_rs.getShort("TYPE"); - if (idx_type == DatabaseMetaData.tableIndexStatistic) { - continue; - } - boolean idx_unique = (!idx_rs.getBoolean("NON_UNIQUE")); - String idx_name = idx_rs.getString("INDEX_NAME"); - int idx_col_pos = idx_rs.getInt("ORDINAL_POSITION") - 1; - String idx_col_name = idx_rs.getString("COLUMN_NAME"); - String sort = idx_rs.getString("ASC_OR_DESC"); - SortDirectionType idx_direction; - if (sort != null) { - idx_direction = sort.equalsIgnoreCase("A") ? SortDirectionType.ASC : SortDirectionType.DESC; - } else { - idx_direction = null; - } - - Index catalog_idx = catalog_tbl.getIndex(idx_name); - if (catalog_idx == null) { - catalog_idx = new Index(idx_name, separator, catalog_tbl, idx_type, idx_unique); - catalog_tbl.addIndex(catalog_idx); - } - - catalog_idx.addColumn(idx_col_name, idx_direction, idx_col_pos); - } - } - - tables.put(table_name, catalog_tbl); + Index catalog_idx = catalog_tbl.getIndex(idx_name); + if (catalog_idx == null) { + catalog_idx = new Index(idx_name, separator, catalog_tbl, idx_type, idx_unique); + catalog_tbl.addIndex(catalog_idx); } + + catalog_idx.addColumn(idx_col_name, idx_direction, idx_col_pos); + } } - for (Table table : tables.values()) { - try (ResultSet fk_rs = md.getImportedKeys(catalog, schema, table.getName())) { - while (fk_rs.next()) { - String colName = fk_rs.getString("FKCOLUMN_NAME"); + tables.put(table_name, catalog_tbl); + } + } - String fk_tableName = fk_rs.getString("PKTABLE_NAME"); - String fk_colName = fk_rs.getString("PKCOLUMN_NAME"); + for (Table table : tables.values()) { + try (ResultSet fk_rs = md.getImportedKeys(catalog, schema, table.getName())) { + while (fk_rs.next()) { + String colName = fk_rs.getString("FKCOLUMN_NAME"); - Table fk_table = tables.get(fk_tableName); - Column fk_col = fk_table.getColumnByName(fk_colName); + String fk_tableName = fk_rs.getString("PKTABLE_NAME"); + String fk_colName = fk_rs.getString("PKCOLUMN_NAME"); - Column catalog_col = table.getColumnByName(colName); - catalog_col.setForeignKey(fk_col); - } - } - } + Table fk_table = tables.get(fk_tableName); + Column fk_col = fk_table.getColumnByName(fk_colName); - return new Catalog(tables); + Column catalog_col = table.getColumnByName(colName); + catalog_col.setForeignKey(fk_col); + } + } } - public static boolean isDuplicateKeyException(Exception ex) { - // MYSQL - if (ex instanceof SQLIntegrityConstraintViolationException) { - return (true); - } else if (ex instanceof SQLException) { - SQLException sqlEx = (SQLException) ex; - - // POSTGRES - if (sqlEx.getSQLState().contains("23505")) { - return (true); - } - // SQLSERVER - else if (sqlEx.getSQLState().equals("23000") && sqlEx.getErrorCode() == 2627) { - return (true); - } - } - return (false); + return new Catalog(tables); + } + + public static boolean isDuplicateKeyException(Exception ex) { + // MYSQL + if (ex instanceof SQLIntegrityConstraintViolationException) { + return (true); + } else if (ex instanceof SQLException) { + SQLException sqlEx = (SQLException) ex; + + // POSTGRES + if (sqlEx.getSQLState().contains("23505")) { + return (true); + } + // SQLSERVER + else if (sqlEx.getSQLState().equals("23000") && sqlEx.getErrorCode() == 2627) { + return (true); + } } -} \ No newline at end of file + return (false); + } +} diff --git a/src/main/java/com/oltpbenchmark/util/ScriptRunner.java b/src/main/java/com/oltpbenchmark/util/ScriptRunner.java index e16397fc0..9b192aa6b 100644 --- a/src/main/java/com/oltpbenchmark/util/ScriptRunner.java +++ b/src/main/java/com/oltpbenchmark/util/ScriptRunner.java @@ -22,163 +22,152 @@ */ package com.oltpbenchmark.util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.io.*; import java.sql.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -/** - * Tool to run database scripts - * http://pastebin.com/f10584951 - */ +/** Tool to run database scripts http://pastebin.com/f10584951 */ public class ScriptRunner { - private static final Logger LOG = LoggerFactory.getLogger(ScriptRunner.class); + private static final Logger LOG = LoggerFactory.getLogger(ScriptRunner.class); - private static final String DEFAULT_DELIMITER = ";"; + private static final String DEFAULT_DELIMITER = ";"; - private final Connection connection; - private final boolean stopOnError; - private final boolean autoCommit; + private final Connection connection; + private final boolean stopOnError; + private final boolean autoCommit; - /** - * Default constructor - */ - public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) { - this.connection = connection; - this.autoCommit = autoCommit; - this.stopOnError = stopOnError; - } + /** Default constructor */ + public ScriptRunner(Connection connection, boolean autoCommit, boolean stopOnError) { + this.connection = connection; + this.autoCommit = autoCommit; + this.stopOnError = stopOnError; + } + public void runExternalScript(String path) throws IOException, SQLException { - public void runExternalScript(String path) throws IOException, SQLException { + LOG.debug("trying to find external file by path {}", path); - LOG.debug("trying to find external file by path {}", path); + try (FileReader reader = new FileReader(path)) { - try (FileReader reader = new FileReader(path)) { - - runScript(reader); - } + runScript(reader); } + } - public void runScript(String path) throws IOException, SQLException { + public void runScript(String path) throws IOException, SQLException { - LOG.debug("trying to find file by path {}", path); + LOG.debug("trying to find file by path {}", path); - try (InputStream in = this.getClass().getResourceAsStream(path); - Reader reader = new InputStreamReader(in)) { + try (InputStream in = this.getClass().getResourceAsStream(path); + Reader reader = new InputStreamReader(in)) { - runScript(reader); - } + runScript(reader); } - - private void runScript(Reader reader) throws IOException, SQLException { - boolean originalAutoCommit = connection.getAutoCommit(); - - try { - if (originalAutoCommit != this.autoCommit) { - connection.setAutoCommit(this.autoCommit); - } - runScript(connection, reader); - } finally { - connection.setAutoCommit(originalAutoCommit); - } + } + + private void runScript(Reader reader) throws IOException, SQLException { + boolean originalAutoCommit = connection.getAutoCommit(); + + try { + if (originalAutoCommit != this.autoCommit) { + connection.setAutoCommit(this.autoCommit); + } + runScript(connection, reader); + } finally { + connection.setAutoCommit(originalAutoCommit); } + } + + /** + * Runs an SQL script (read in using the Reader parameter) using the connection passed in + * + * @param conn - the connection to use for the script + * @param reader - the source of the script + * @throws SQLException if any SQL errors occur + * @throws IOException if there is an error reading from the Reader + */ + private void runScript(Connection conn, Reader reader) throws IOException, SQLException { + StringBuffer command = null; + try (LineNumberReader lineReader = new LineNumberReader(reader)) { + String line = null; + while ((line = lineReader.readLine()) != null) { + if (LOG.isDebugEnabled()) { + LOG.debug(line); + } + if (command == null) { + command = new StringBuffer(); + } + String trimmedLine = line.trim(); + line = line.replaceAll("\\-\\-.*$", ""); // remove comments in line; + + if (trimmedLine.startsWith("--") || trimmedLine.startsWith("//")) { + LOG.debug(trimmedLine); + } else if (trimmedLine.length() < 1) { + // Do nothing + } else if (trimmedLine.endsWith(getDelimiter())) { + command.append(line, 0, line.lastIndexOf(getDelimiter())); + command.append(" "); + + try (Statement statement = conn.createStatement()) { + + boolean hasResults = false; + final String sql = command.toString().trim(); + if (stopOnError) { + hasResults = statement.execute(sql); + } else { + try { + statement.execute(sql); + } catch (SQLException e) { + LOG.error(e.getMessage(), e); + } + } + if (autoCommit && !conn.getAutoCommit()) { + conn.commit(); + } - /** - * Runs an SQL script (read in using the Reader parameter) using the - * connection passed in - * - * @param conn - the connection to use for the script - * @param reader - the source of the script - * @throws SQLException if any SQL errors occur - * @throws IOException if there is an error reading from the Reader - */ - private void runScript(Connection conn, Reader reader) throws IOException, SQLException { - StringBuffer command = null; - try (LineNumberReader lineReader = new LineNumberReader(reader)) { - String line = null; - while ((line = lineReader.readLine()) != null) { - if (LOG.isDebugEnabled()) { - LOG.debug(line); - } - if (command == null) { - command = new StringBuffer(); - } - String trimmedLine = line.trim(); - line = line.replaceAll("\\-\\-.*$", ""); // remove comments in line; - - if (trimmedLine.startsWith("--") || trimmedLine.startsWith("//")) { - LOG.debug(trimmedLine); - } else if (trimmedLine.length() < 1) { - // Do nothing - } else if (trimmedLine.endsWith(getDelimiter())) { - command.append(line, 0, line.lastIndexOf(getDelimiter())); - command.append(" "); - - try (Statement statement = conn.createStatement()) { - - boolean hasResults = false; - final String sql = command.toString().trim(); - if (stopOnError) { - hasResults = statement.execute(sql); - } else { - try { - statement.execute(sql); - } catch (SQLException e) { - LOG.error(e.getMessage(), e); - } - } - - if (autoCommit && !conn.getAutoCommit()) { - conn.commit(); - } - - // HACK - if (hasResults && !sql.toUpperCase().startsWith("CREATE")) { - try (ResultSet rs = statement.getResultSet()) { - if (hasResults && rs != null) { - ResultSetMetaData md = rs.getMetaData(); - int cols = md.getColumnCount(); - for (int i = 0; i < cols; i++) { - String name = md.getColumnLabel(i); - LOG.debug(name); - } - - while (rs.next()) { - for (int i = 0; i < cols; i++) { - String value = rs.getString(i); - LOG.debug(value); - } - } - - } - } - } - - command = null; - } finally { - - Thread.yield(); + // HACK + if (hasResults && !sql.toUpperCase().startsWith("CREATE")) { + try (ResultSet rs = statement.getResultSet()) { + if (hasResults && rs != null) { + ResultSetMetaData md = rs.getMetaData(); + int cols = md.getColumnCount(); + for (int i = 0; i < cols; i++) { + String name = md.getColumnLabel(i); + LOG.debug(name); + } + + while (rs.next()) { + for (int i = 0; i < cols; i++) { + String value = rs.getString(i); + LOG.debug(value); } - } else { - command.append(line); - command.append(" "); + } } + } } - if (!autoCommit) { - conn.commit(); - } - } finally { - if (!autoCommit) { - conn.rollback(); - } - } - } - private String getDelimiter() { - return DEFAULT_DELIMITER; + command = null; + } finally { + + Thread.yield(); + } + } else { + command.append(line); + command.append(" "); + } + } + if (!autoCommit) { + conn.commit(); + } + } finally { + if (!autoCommit) { + conn.rollback(); + } } + } + private String getDelimiter() { + return DEFAULT_DELIMITER; + } } diff --git a/src/main/java/com/oltpbenchmark/util/StringUtil.java b/src/main/java/com/oltpbenchmark/util/StringUtil.java index 263d08384..fc5441e1a 100644 --- a/src/main/java/com/oltpbenchmark/util/StringUtil.java +++ b/src/main/java/com/oltpbenchmark/util/StringUtil.java @@ -17,10 +17,10 @@ package com.oltpbenchmark.util; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.ArrayList; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; @@ -31,422 +31,441 @@ */ public abstract class StringUtil { - private static final Pattern LINE_SPLIT = Pattern.compile("\n"); - private static final Pattern TITLE_SPLIT = Pattern.compile(" "); - public static final Pattern WHITESPACE = Pattern.compile("[" - + "\\u0009" // CHARACTER TABULATION - + "\\u000A" // LINE FEED (LF) - + "\\u000B" // LINE TABULATION - + "\\u000C" // FORM FEED (FF) - + "\\u000D" // CARRIAGE RETURN (CR) - + "\\u0020" // SPACE - + "\\u0085" // NEXT LINE (NEL) - + "\\u00A0" // NO-BREAK SPACE - + "\\u1680" // OGHAM SPACE MARK - + "\\u180E" // MONGOLIAN VOWEL SEPARATOR - + "\\u2000" // EN QUAD - + "\\u2001" // EM QUAD - + "\\u2002" // EN SPACE - + "\\u2003" // EM SPACE - + "\\u2004" // THREE-PER-EM SPACE - + "\\u2005" // FOUR-PER-EM SPACE - + "\\u2006" // SIX-PER-EM SPACE - + "\\u2007" // FIGURE SPACE - + "\\u2008" // PUNCTUATION SPACE - + "\\u2009" // THIN SPACE - + "\\u200A" // HAIR SPACE - + "\\u2028" // LINE SEPARATOR - + "\\u2029" // PARAGRAPH SEPARATOR - + "\\u202F" // NARROW NO-BREAK SPACE - + "\\u205F" // MEDIUM MATHEMATICAL SPACE - + "\\u3000" // IDEOGRAPHIC SPACE) - + "]"); - - private static final String SET_PLAIN_TEXT = "\033[0;0m"; - private static final String SET_BOLD_TEXT = "\033[0;1m"; - - private static String CACHE_REPEAT_STR = null; - private static Integer CACHE_REPEAT_SIZE = null; - private static String CACHE_REPEAT_RESULT = null; - - /** - * Return key/value maps into a nicely formatted table - * Delimiter ":", No UpperCase Keys, No Boxing - * - * @param maps - * @return - */ - public static String formatMaps(Map... maps) { - return (formatMaps(":", false, false, false, false, true, true, maps)); + private static final Pattern LINE_SPLIT = Pattern.compile("\n"); + private static final Pattern TITLE_SPLIT = Pattern.compile(" "); + public static final Pattern WHITESPACE = + Pattern.compile( + "[" + + "\\u0009" // CHARACTER TABULATION + + "\\u000A" // LINE FEED (LF) + + "\\u000B" // LINE TABULATION + + "\\u000C" // FORM FEED (FF) + + "\\u000D" // CARRIAGE RETURN (CR) + + "\\u0020" // SPACE + + "\\u0085" // NEXT LINE (NEL) + + "\\u00A0" // NO-BREAK SPACE + + "\\u1680" // OGHAM SPACE MARK + + "\\u180E" // MONGOLIAN VOWEL SEPARATOR + + "\\u2000" // EN QUAD + + "\\u2001" // EM QUAD + + "\\u2002" // EN SPACE + + "\\u2003" // EM SPACE + + "\\u2004" // THREE-PER-EM SPACE + + "\\u2005" // FOUR-PER-EM SPACE + + "\\u2006" // SIX-PER-EM SPACE + + "\\u2007" // FIGURE SPACE + + "\\u2008" // PUNCTUATION SPACE + + "\\u2009" // THIN SPACE + + "\\u200A" // HAIR SPACE + + "\\u2028" // LINE SEPARATOR + + "\\u2029" // PARAGRAPH SEPARATOR + + "\\u202F" // NARROW NO-BREAK SPACE + + "\\u205F" // MEDIUM MATHEMATICAL SPACE + + "\\u3000" // IDEOGRAPHIC SPACE) + + "]"); + + private static final String SET_PLAIN_TEXT = "\033[0;0m"; + private static final String SET_BOLD_TEXT = "\033[0;1m"; + + private static String CACHE_REPEAT_STR = null; + private static Integer CACHE_REPEAT_SIZE = null; + private static String CACHE_REPEAT_RESULT = null; + + /** + * Return key/value maps into a nicely formatted table Delimiter ":", No UpperCase Keys, No Boxing + * + * @param maps + * @return + */ + public static String formatMaps(Map... maps) { + return (formatMaps(":", false, false, false, false, true, true, maps)); + } + + /** + * Return key/value maps into a nicely formatted table The maps are displayed in order from first + * to last, and there will be a spacer created between each map. The format for each record is: + * + *

+ * + *

If the delimiter is an equal sign, then the format is: + * + *

+ * + * @param delimiter + * @param upper Upper-case all keys + * @param box Box results + * @param border_top TODO + * @param border_bottom TODO + * @param recursive TODO + * @param first_element_title TODO + * @param maps + * @return + */ + public static String formatMaps( + String delimiter, + boolean upper, + boolean box, + boolean border_top, + boolean border_bottom, + boolean recursive, + boolean first_element_title, + Map... maps) { + boolean need_divider = (maps.length > 1 || border_bottom || border_top); + + // Figure out the largest key size so we can get spacing right + int max_key_size = 0; + int max_title_size = 0; + @SuppressWarnings({"unchecked", "rawtypes"}) + final Map[] map_keys = (Map[]) new Map[maps.length]; + final boolean[] map_titles = new boolean[maps.length]; + for (int i = 0; i < maps.length; i++) { + Map m = maps[i]; + if (m == null) { + continue; + } + Map keys = new HashMap<>(); + boolean first = true; + for (Object k : m.keySet()) { + String[] k_str = LINE_SPLIT.split(k != null ? k.toString() : ""); + keys.put(k, k_str); + + // If the first element has a null value, then we can let it be the title for + // this map + // It's length doesn't affect the other keys, but will affect the total size of + // the map + if (first && first_element_title && m.get(k) == null) { + for (String line : k_str) { + max_title_size = Math.max(max_title_size, line.length()); + } + map_titles[i] = true; + } else { + for (String line : k_str) { + max_key_size = Math.max(max_key_size, line.length()); + } + if (first) { + map_titles[i] = false; + } + } + first = false; + } + map_keys[i] = keys; } - /** - * Return key/value maps into a nicely formatted table - * The maps are displayed in order from first to last, and there will be a - * spacer - * created between each map. The format for each record is: - * - * - *

- * If the delimiter is an equal sign, then the format is: - * - * - * - * @param delimiter - * @param upper Upper-case all keys - * @param box Box results - * @param border_top TODO - * @param border_bottom TODO - * @param recursive TODO - * @param first_element_title TODO - * @param maps - * @return - */ - public static String formatMaps(String delimiter, boolean upper, boolean box, boolean border_top, - boolean border_bottom, boolean recursive, boolean first_element_title, Map... maps) { - boolean need_divider = (maps.length > 1 || border_bottom || border_top); - - // Figure out the largest key size so we can get spacing right - int max_key_size = 0; - int max_title_size = 0; - @SuppressWarnings({"unchecked", "rawtypes"}) - final Map[] map_keys = (Map[]) new Map[maps.length]; - final boolean[] map_titles = new boolean[maps.length]; - for (int i = 0; i < maps.length; i++) { - Map m = maps[i]; - if (m == null) { - continue; - } - Map keys = new HashMap<>(); - boolean first = true; - for (Object k : m.keySet()) { - String[] k_str = LINE_SPLIT.split(k != null ? k.toString() : ""); - keys.put(k, k_str); - - // If the first element has a null value, then we can let it be the title for - // this map - // It's length doesn't affect the other keys, but will affect the total size of - // the map - if (first && first_element_title && m.get(k) == null) { - for (String line : k_str) { - max_title_size = Math.max(max_title_size, line.length()); - } - map_titles[i] = true; - } else { - for (String line : k_str) { - max_key_size = Math.max(max_key_size, line.length()); - } - if (first) { - map_titles[i] = false; - } - } - first = false; - } - map_keys[i] = keys; - } + boolean equalsDelimiter = delimiter.equals("="); + final String f = + "%-" + + (max_key_size + delimiter.length() + 1) + + "s" + + (equalsDelimiter ? "= " : "") + + "%s\n"; + + // Now make StringBuilder blocks for each map + // We do it in this way so that we can get the max length of the values + int max_value_size = 0; + StringBuilder[] blocks = new StringBuilder[maps.length]; + for (int map_i = 0; map_i < maps.length; map_i++) { + blocks[map_i] = new StringBuilder(); + Map m = maps[map_i]; + if (m == null) { + continue; + } + Map keys = map_keys[map_i]; + + boolean first = true; + for (Entry e : m.entrySet()) { + String[] key = keys.get(e.getKey()); + + if (first && map_titles[map_i]) { + blocks[map_i].append(StringUtil.join("\n", key)); + if (!CollectionUtil.last(key).endsWith("\n")) { + blocks[map_i].append("\n"); + } - boolean equalsDelimiter = delimiter.equals("="); - final String f = "%-" + (max_key_size + delimiter.length() + 1) + "s" + - (equalsDelimiter ? "= " : "") + - "%s\n"; - - // Now make StringBuilder blocks for each map - // We do it in this way so that we can get the max length of the values - int max_value_size = 0; - StringBuilder[] blocks = new StringBuilder[maps.length]; - for (int map_i = 0; map_i < maps.length; map_i++) { - blocks[map_i] = new StringBuilder(); - Map m = maps[map_i]; - if (m == null) { - continue; + } else { + Object v_obj = e.getValue(); + String v = null; + if (recursive && v_obj instanceof Map) { + v = + formatMaps( + delimiter, + upper, + box, + border_top, + border_bottom, + recursive, + first_element_title, + (Map) v_obj) + .trim(); + } else if (key.length == 1 && key[0].trim().isEmpty() && v_obj == null) { + blocks[map_i].append("\n"); + continue; + } else if (v_obj == null) { + v = "null"; + } else { + v = v_obj.toString(); + } + + // If the key or value is multiple lines, format them nicely! + String[] value = LINE_SPLIT.split(v); + int total_lines = Math.max(key.length, value.length); + for (int line_i = 0; line_i < total_lines; line_i++) { + String k_line = (line_i < key.length ? key[line_i] : ""); + if (upper) { + k_line = k_line.toUpperCase(); } - Map keys = map_keys[map_i]; - - boolean first = true; - for (Entry e : m.entrySet()) { - String[] key = keys.get(e.getKey()); - - if (first && map_titles[map_i]) { - blocks[map_i].append(StringUtil.join("\n", key)); - if (!CollectionUtil.last(key).endsWith("\n")) { - blocks[map_i].append("\n"); - } - - } else { - Object v_obj = e.getValue(); - String v = null; - if (recursive && v_obj instanceof Map) { - v = formatMaps(delimiter, upper, box, border_top, border_bottom, recursive, first_element_title, - (Map) v_obj).trim(); - } else if (key.length == 1 && key[0].trim().isEmpty() && v_obj == null) { - blocks[map_i].append("\n"); - continue; - } else if (v_obj == null) { - v = "null"; - } else { - v = v_obj.toString(); - } - - // If the key or value is multiple lines, format them nicely! - String[] value = LINE_SPLIT.split(v); - int total_lines = Math.max(key.length, value.length); - for (int line_i = 0; line_i < total_lines; line_i++) { - String k_line = (line_i < key.length ? key[line_i] : ""); - if (upper) { - k_line = k_line.toUpperCase(); - } - - String v_line = (line_i < value.length ? value[line_i] : ""); - - if (line_i == (key.length - 1) && (!first || (first && !v_line.isEmpty()))) { - if (!equalsDelimiter && !k_line.trim().isEmpty()) { - k_line += ":"; - } - } - - blocks[map_i].append(String.format(f, k_line, v_line)); - if (need_divider) { - max_value_size = Math.max(max_value_size, v_line.length()); - } - } - if (v.endsWith("\n")) { - blocks[map_i].append("\n"); - } - } - first = false; + + String v_line = (line_i < value.length ? value[line_i] : ""); + + if (line_i == (key.length - 1) && (!first || (first && !v_line.isEmpty()))) { + if (!equalsDelimiter && !k_line.trim().isEmpty()) { + k_line += ":"; + } } - } - // Put it all together! - // System.err.println("max_title_size=" + max_title_size + ", max_key_size=" + - // max_key_size + ", max_value_size=" + max_value_size + ", delimiter=" + - // delimiter.length()); - int total_width = Math.max(max_title_size, (max_key_size + max_value_size + delimiter.length())) + 1; - String dividing_line = (need_divider ? repeat("-", total_width) : ""); - StringBuilder sb = null; - if (maps.length == 1) { - sb = blocks[0]; - } else { - sb = new StringBuilder(); - for (int i = 0; i < maps.length; i++) { - if (blocks[i].length() == 0) { - continue; - } - if (i != 0 && maps[i].size() > 0) { - sb.append(dividing_line).append("\n"); - } - sb.append(blocks[i]); + blocks[map_i].append(String.format(f, k_line, v_line)); + if (need_divider) { + max_value_size = Math.max(max_value_size, v_line.length()); } + } + if (v.endsWith("\n")) { + blocks[map_i].append("\n"); + } } - return (box ? StringUtil.box(sb.toString()) - : (border_top ? dividing_line + "\n" : "") + sb.toString() + (border_bottom ? dividing_line : "")); + first = false; + } } - /** - * Returns the given string repeated the given # of times - * - * @param str - * @param size - * @return - */ - public static String repeat(String str, int size) { - // We cache the last call in case they are making repeated calls for the same - // thing - if (CACHE_REPEAT_STR != null && CACHE_REPEAT_SIZE != null && - CACHE_REPEAT_STR.equals(str) && - CACHE_REPEAT_SIZE.equals(size)) { - return (CACHE_REPEAT_RESULT); + // Put it all together! + // System.err.println("max_title_size=" + max_title_size + ", max_key_size=" + + // max_key_size + ", max_value_size=" + max_value_size + ", delimiter=" + + // delimiter.length()); + int total_width = + Math.max(max_title_size, (max_key_size + max_value_size + delimiter.length())) + 1; + String dividing_line = (need_divider ? repeat("-", total_width) : ""); + StringBuilder sb = null; + if (maps.length == 1) { + sb = blocks[0]; + } else { + sb = new StringBuilder(); + for (int i = 0; i < maps.length; i++) { + if (blocks[i].length() == 0) { + continue; } - - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < size; i++) { - sb.append(str); + if (i != 0 && maps[i].size() > 0) { + sb.append(dividing_line).append("\n"); } - CACHE_REPEAT_RESULT = sb.toString(); - CACHE_REPEAT_STR = str; - CACHE_REPEAT_SIZE = size; - return (CACHE_REPEAT_RESULT); + sb.append(blocks[i]); + } } - - /** - * Make a box around some text. If str has multiple lines, then the box will be - * the length - * of the longest string. - * - * @param str - * @return - */ - public static String box(String str) { - return (StringUtil.box(str, "*", null)); + return (box + ? StringUtil.box(sb.toString()) + : (border_top ? dividing_line + "\n" : "") + + sb.toString() + + (border_bottom ? dividing_line : "")); + } + + /** + * Returns the given string repeated the given # of times + * + * @param str + * @param size + * @return + */ + public static String repeat(String str, int size) { + // We cache the last call in case they are making repeated calls for the same + // thing + if (CACHE_REPEAT_STR != null + && CACHE_REPEAT_SIZE != null + && CACHE_REPEAT_STR.equals(str) + && CACHE_REPEAT_SIZE.equals(size)) { + return (CACHE_REPEAT_RESULT); } - /** - * Create a box around some text - * - * @param str - * @param mark - * @param max_len - * @return - */ - public static String box(String str, String mark, Integer max_len) { - String[] lines = LINE_SPLIT.split(str); - if (lines.length == 0) { - return ""; - } - - if (max_len == null) { - for (String line : lines) { - if (max_len == null || line.length() > max_len) { - max_len = line.length(); - } - } - } - - final String top_line = StringUtil.repeat(mark, max_len + 4); // padding - final String f = "%s %-" + max_len + "s %s\n"; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < size; i++) { + sb.append(str); + } + CACHE_REPEAT_RESULT = sb.toString(); + CACHE_REPEAT_STR = str; + CACHE_REPEAT_SIZE = size; + return (CACHE_REPEAT_RESULT); + } + + /** + * Make a box around some text. If str has multiple lines, then the box will be the length of the + * longest string. + * + * @param str + * @return + */ + public static String box(String str) { + return (StringUtil.box(str, "*", null)); + } + + /** + * Create a box around some text + * + * @param str + * @param mark + * @param max_len + * @return + */ + public static String box(String str, String mark, Integer max_len) { + String[] lines = LINE_SPLIT.split(str); + if (lines.length == 0) { + return ""; + } - StringBuilder sb = new StringBuilder(); - sb.append(top_line).append("\n"); - for (String line : lines) { - sb.append(String.format(f, mark, line, mark)); + if (max_len == null) { + for (String line : lines) { + if (max_len == null || line.length() > max_len) { + max_len = line.length(); } - sb.append(top_line); - - return (sb.toString()); + } } - /** - * Converts a string to title case (ala Python) - * - * @param string - * @return - */ - public static String title(String string) { - return (StringUtil.title(string, false)); - } + final String top_line = StringUtil.repeat(mark, max_len + 4); // padding + final String f = "%s %-" + max_len + "s %s\n"; - /** - * Converts a string to title case (ala Python) - * - * @param string - * @param keep_upper If true, then any non-first character that is uppercase - * stays uppercase - * @return - */ - public static String title(String string, boolean keep_upper) { - StringBuilder sb = new StringBuilder(); - String add = ""; - for (String part : TITLE_SPLIT.split(string)) { - sb.append(add).append(part.substring(0, 1).toUpperCase()); - int len = part.length(); - if (len > 1) { - if (keep_upper) { - for (int i = 1; i < len; i++) { - String c = part.substring(i, i + 1); - String up = c.toUpperCase(); - sb.append(c.equals(up) ? c : c.toLowerCase()); - } - } else { - sb.append(part.substring(1).toLowerCase()); - } - } - add = " "; + StringBuilder sb = new StringBuilder(); + sb.append(top_line).append("\n"); + for (String line : lines) { + sb.append(String.format(f, mark, line, mark)); + } + sb.append(top_line); + + return (sb.toString()); + } + + /** + * Converts a string to title case (ala Python) + * + * @param string + * @return + */ + public static String title(String string) { + return (StringUtil.title(string, false)); + } + + /** + * Converts a string to title case (ala Python) + * + * @param string + * @param keep_upper If true, then any non-first character that is uppercase stays uppercase + * @return + */ + public static String title(String string, boolean keep_upper) { + StringBuilder sb = new StringBuilder(); + String add = ""; + for (String part : TITLE_SPLIT.split(string)) { + sb.append(add).append(part.substring(0, 1).toUpperCase()); + int len = part.length(); + if (len > 1) { + if (keep_upper) { + for (int i = 1; i < len; i++) { + String c = part.substring(i, i + 1); + String up = c.toUpperCase(); + sb.append(c.equals(up) ? c : c.toLowerCase()); + } + } else { + sb.append(part.substring(1).toLowerCase()); } - return (sb.toString()); + } + add = " "; } - - /** - * Python join() - * - * @param - * @param delimiter - * @param items - * @return - */ - @SuppressWarnings("unchecked") - public static String join(String delimiter, T... items) { - return (join(delimiter, Arrays.asList(items))); + return (sb.toString()); + } + + /** + * Python join() + * + * @param + * @param delimiter + * @param items + * @return + */ + @SuppressWarnings("unchecked") + public static String join(String delimiter, T... items) { + return (join(delimiter, Arrays.asList(items))); + } + + /** + * Wrap the given string with the control characters to make the text appear bold in the console + */ + public static String bold(String str) { + return (SET_BOLD_TEXT + str + SET_PLAIN_TEXT); + } + + /** + * Python join() + * + * @param delimiter + * @param items + * @return + */ + public static String join(String delimiter, Iterable items) { + return (join("", delimiter, items)); + } + + /** + * Python join() with optional prefix + * + * @param prefix + * @param delimiter + * @param items + * @return + */ + public static String join(String prefix, String delimiter, Iterable items) { + if (items == null) { + return (""); } - - /** - * Wrap the given string with the control characters - * to make the text appear bold in the console - */ - public static String bold(String str) { - return (SET_BOLD_TEXT + str + SET_PLAIN_TEXT); + if (prefix == null) { + prefix = ""; } - /** - * Python join() - * - * @param delimiter - * @param items - * @return - */ - public static String join(String delimiter, Iterable items) { - return (join("", delimiter, items)); + StringBuilder sb = new StringBuilder(); + int i = 0; + for (Object x : items) { + if (!prefix.isEmpty()) { + sb.append(prefix); + } + sb.append(x != null ? x.toString() : x).append(delimiter); + i++; } - - /** - * Python join() with optional prefix - * - * @param prefix - * @param delimiter - * @param items - * @return - */ - public static String join(String prefix, String delimiter, Iterable items) { - if (items == null) { - return (""); - } - if (prefix == null) { - prefix = ""; - } - - StringBuilder sb = new StringBuilder(); - int i = 0; - for (Object x : items) { - if (!prefix.isEmpty()) { - sb.append(prefix); - } - sb.append(x != null ? x.toString() : x).append(delimiter); - i++; - } - if (i == 0) { - return ""; - } - sb.delete(sb.length() - delimiter.length(), sb.length()); - - return sb.toString(); + if (i == 0) { + return ""; } - - public static List splitToList(Pattern delim, String str) { - String[] arr = delim.split(str); - List retList = new ArrayList<>(); - // remove empty strings. - for (String s : arr) { - if (s.length() == 0) { - continue; - } - // strip the spaces. - int left_idx = 0; - int right_idx = s.length(); - while (left_idx < right_idx && Pattern.matches(WHITESPACE.pattern(), - s.substring(left_idx, left_idx + 1))) { - left_idx++; - } - while (right_idx > left_idx && Pattern.matches(WHITESPACE.pattern(), - s.substring(right_idx - 1, right_idx))) { - right_idx--; - } - - if (right_idx <= left_idx) { - continue; - } - - retList.add(s.substring(left_idx, right_idx)); - } - return retList; + sb.delete(sb.length() - delimiter.length(), sb.length()); + + return sb.toString(); + } + + public static List splitToList(Pattern delim, String str) { + String[] arr = delim.split(str); + List retList = new ArrayList<>(); + // remove empty strings. + for (String s : arr) { + if (s.length() == 0) { + continue; + } + // strip the spaces. + int left_idx = 0; + int right_idx = s.length(); + while (left_idx < right_idx + && Pattern.matches(WHITESPACE.pattern(), s.substring(left_idx, left_idx + 1))) { + left_idx++; + } + while (right_idx > left_idx + && Pattern.matches(WHITESPACE.pattern(), s.substring(right_idx - 1, right_idx))) { + right_idx--; + } + + if (right_idx <= left_idx) { + continue; + } + + retList.add(s.substring(left_idx, right_idx)); } - + return retList; + } } diff --git a/src/main/java/com/oltpbenchmark/util/TableDataIterable.java b/src/main/java/com/oltpbenchmark/util/TableDataIterable.java index 80019099d..9288beade 100644 --- a/src/main/java/com/oltpbenchmark/util/TableDataIterable.java +++ b/src/main/java/com/oltpbenchmark/util/TableDataIterable.java @@ -15,147 +15,147 @@ * */ - package com.oltpbenchmark.util; import com.oltpbenchmark.catalog.Column; import com.oltpbenchmark.catalog.Table; import com.opencsv.CSVReader; - +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.IOException; import java.util.Iterator; /** * @author pavlo */ public class TableDataIterable implements Iterable, AutoCloseable { - private final String filePath; - private final CSVReader reader; - private final boolean auto_generate_first_column; - - private final int[] types; - private final boolean[] fkeys; - private final boolean[] nullable; - private int line_ctr = 0; - - private InputStream in = null; - - /** - * Constructor - * - * @param filePath - * @param has_header whether we expect the data file to include a header in the first row - * @param auto_generate_first_column TODO - * @throws Exception - */ - public TableDataIterable(Table catalog_tbl, String filePath, boolean has_header, boolean auto_generate_first_column) throws Exception { - this.filePath = filePath; - this.auto_generate_first_column = auto_generate_first_column; - - this.types = new int[catalog_tbl.getColumnCount()]; - this.fkeys = new boolean[catalog_tbl.getColumnCount()]; - this.nullable = new boolean[catalog_tbl.getColumnCount()]; - for (int i = 0; i < this.types.length; i++) { - Column catalog_col = catalog_tbl.getColumn(i); - this.types[i] = catalog_col.getType(); - this.fkeys[i] = (catalog_col.getForeignKey() != null); - this.nullable[i] = catalog_col.isNullable(); - } - - in = this.getClass().getResourceAsStream(filePath); - this.reader = new CSVReader(new InputStreamReader(in)); + private final String filePath; + private final CSVReader reader; + private final boolean auto_generate_first_column; + + private final int[] types; + private final boolean[] fkeys; + private final boolean[] nullable; + private int line_ctr = 0; + + private InputStream in = null; + + /** + * Constructor + * + * @param filePath + * @param has_header whether we expect the data file to include a header in the first row + * @param auto_generate_first_column TODO + * @throws Exception + */ + public TableDataIterable( + Table catalog_tbl, String filePath, boolean has_header, boolean auto_generate_first_column) + throws Exception { + this.filePath = filePath; + this.auto_generate_first_column = auto_generate_first_column; + + this.types = new int[catalog_tbl.getColumnCount()]; + this.fkeys = new boolean[catalog_tbl.getColumnCount()]; + this.nullable = new boolean[catalog_tbl.getColumnCount()]; + for (int i = 0; i < this.types.length; i++) { + Column catalog_col = catalog_tbl.getColumn(i); + this.types[i] = catalog_col.getType(); + this.fkeys[i] = (catalog_col.getForeignKey() != null); + this.nullable[i] = catalog_col.isNullable(); + } + in = this.getClass().getResourceAsStream(filePath); + this.reader = new CSVReader(new InputStreamReader(in)); - // Throw away the first row if there is a header - if (has_header) { - this.reader.readNext(); - this.line_ctr++; - } + // Throw away the first row if there is a header + if (has_header) { + this.reader.readNext(); + this.line_ctr++; } + } + public Iterator iterator() { + return (new TableIterator()); + } - public Iterator iterator() { - return (new TableIterator()); + @Override + public void close() throws IOException { + if (this.in != null) { + in.close(); } - @Override - public void close() throws IOException { - if (this.in != null) { - in.close(); - } - - if (this.reader != null) { - reader.close(); - } + if (this.reader != null) { + reader.close(); } + } - public class TableIterator implements Iterator { - String[] next = null; + public class TableIterator implements Iterator { + String[] next = null; - private void getNext() { - if (next == null) { - try { - next = reader.readNext(); - } catch (Exception ex) { - throw new RuntimeException("Unable to retrieve tuples from '" + filePath + "'", ex); - } - } + private void getNext() { + if (next == null) { + try { + next = reader.readNext(); + } catch (Exception ex) { + throw new RuntimeException("Unable to retrieve tuples from '" + filePath + "'", ex); } + } + } - @Override - public boolean hasNext() { - this.getNext(); - return (next != null); - } + @Override + public boolean hasNext() { + this.getNext(); + return (next != null); + } - @Override - public Object[] next() { - this.getNext(); - if (next == null) { - return (next); - } - String[] row; - synchronized (this) { - row = this.next; - this.next = null; - } - Object[] tuple = new Object[types.length]; - int row_idx = 0; - for (int col_idx = 0; col_idx < types.length; col_idx++) { - // Auto-generate first column - if (col_idx == 0 && auto_generate_first_column) { - tuple[col_idx] = (long) line_ctr; - } else if (row_idx >= row.length) { - // Null values. - tuple[col_idx] = null; - } else if (fkeys[col_idx]) { - // Foreign keys. - tuple[col_idx] = row[row_idx++]; - } - // Default: Cast the string into the proper type - else { - if (row[row_idx].isEmpty() && nullable[col_idx]) { - tuple[col_idx] = null; - } else { - try { - tuple[col_idx] = SQLUtil.castValue(types[col_idx], row[row_idx]); - } catch (Throwable ex) { - throw new RuntimeException(String.format("Line %d: Invalid data '%s' for column #%d", - TableDataIterable.this.line_ctr, row[row_idx], col_idx)); - } - } - row_idx++; - } + @Override + public Object[] next() { + this.getNext(); + if (next == null) { + return (next); + } + String[] row; + synchronized (this) { + row = this.next; + this.next = null; + } + Object[] tuple = new Object[types.length]; + int row_idx = 0; + for (int col_idx = 0; col_idx < types.length; col_idx++) { + // Auto-generate first column + if (col_idx == 0 && auto_generate_first_column) { + tuple[col_idx] = (long) line_ctr; + } else if (row_idx >= row.length) { + // Null values. + tuple[col_idx] = null; + } else if (fkeys[col_idx]) { + // Foreign keys. + tuple[col_idx] = row[row_idx++]; + } + // Default: Cast the string into the proper type + else { + if (row[row_idx].isEmpty() && nullable[col_idx]) { + tuple[col_idx] = null; + } else { + try { + tuple[col_idx] = SQLUtil.castValue(types[col_idx], row[row_idx]); + } catch (Throwable ex) { + throw new RuntimeException( + String.format( + "Line %d: Invalid data '%s' for column #%d", + TableDataIterable.this.line_ctr, row[row_idx], col_idx)); } - TableDataIterable.this.line_ctr++; - return (tuple); + } + row_idx++; } + } + TableDataIterable.this.line_ctr++; + return (tuple); + } - @Override - public void remove() { - throw new RuntimeException("Unimplemented operation"); - } + @Override + public void remove() { + throw new RuntimeException("Unimplemented operation"); } + } } diff --git a/src/main/java/com/oltpbenchmark/util/TextGenerator.java b/src/main/java/com/oltpbenchmark/util/TextGenerator.java index 3c62f01d2..1b9070644 100644 --- a/src/main/java/com/oltpbenchmark/util/TextGenerator.java +++ b/src/main/java/com/oltpbenchmark/util/TextGenerator.java @@ -27,140 +27,138 @@ */ public abstract class TextGenerator { - private static final int CHAR_START = 32; // [space] - private static final int CHAR_STOP = 126; // [~] - private static final char[] CHAR_SYMBOLS = new char[1 + CHAR_STOP - CHAR_START]; + private static final int CHAR_START = 32; // [space] + private static final int CHAR_STOP = 126; // [~] + private static final char[] CHAR_SYMBOLS = new char[1 + CHAR_STOP - CHAR_START]; - static { - for (int i = 0; i < CHAR_SYMBOLS.length; i++) { - CHAR_SYMBOLS[i] = (char) (CHAR_START + i); - } + static { + for (int i = 0; i < CHAR_SYMBOLS.length; i++) { + CHAR_SYMBOLS[i] = (char) (CHAR_START + i); } - - private static final int[] FAST_MASKS = { - 554189328, // 10000 - 277094664, // 01000 - 138547332, // 00100 - 69273666, // 00010 - 34636833, // 00001 - 346368330, // 01010 - 727373493, // 10101 - 588826161, // 10001 - 935194491, // 11011 - 658099827, // 10011 - }; - - - /** - * Generate a random block of text as a char array - * - * @param rng - * @param strLen - * @return - */ - public static char[] randomChars(Random rng, int strLen) { - char[] chars = new char[strLen]; - return randomFastChars(rng, chars); + } + + private static final int[] FAST_MASKS = { + 554189328, // 10000 + 277094664, // 01000 + 138547332, // 00100 + 69273666, // 00010 + 34636833, // 00001 + 346368330, // 01010 + 727373493, // 10101 + 588826161, // 10001 + 935194491, // 11011 + 658099827, // 10011 + }; + + /** + * Generate a random block of text as a char array + * + * @param rng + * @param strLen + * @return + */ + public static char[] randomChars(Random rng, int strLen) { + char[] chars = new char[strLen]; + return randomFastChars(rng, chars); + } + + public static char[] randomChars(Random rng, char[] chars) { + for (int i = 0; i < chars.length; i++) { + chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; + } // FOR + return (chars); + } + + /** + * Faster (pseudo) random number generator + * + * @param rng + * @param chars + * @return + */ + public static char[] randomFastChars(Random rng, char[] chars) { + // Ok so now the goal of this is to reduce the number of times that we have to + // invoke a random number. We'll do this by grabbing a single random int + // and then taking different bitmasks + + int num_rounds = chars.length / FAST_MASKS.length; + int i = 0; + for (int ctr = 0; ctr < num_rounds; ctr++) { + int rand = rng.nextInt(10000); // CHAR_SYMBOLS.length); + for (int mask : FAST_MASKS) { + chars[i++] = CHAR_SYMBOLS[(rand | mask) % CHAR_SYMBOLS.length]; + } } - - public static char[] randomChars(Random rng, char[] chars) { - for (int i = 0; i < chars.length; i++) { - chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; - } // FOR - return (chars); + // Use the old way for the remaining characters + // I am doing this because I am too lazy to think of something more clever + for (; i < chars.length; i++) { + chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; } - - /** - * Faster (pseudo) random number generator - * - * @param rng - * @param chars - * @return - */ - public static char[] randomFastChars(Random rng, char[] chars) { - // Ok so now the goal of this is to reduce the number of times that we have to - // invoke a random number. We'll do this by grabbing a single random int - // and then taking different bitmasks - - int num_rounds = chars.length / FAST_MASKS.length; - int i = 0; - for (int ctr = 0; ctr < num_rounds; ctr++) { - int rand = rng.nextInt(10000); // CHAR_SYMBOLS.length); - for (int mask : FAST_MASKS) { - chars[i++] = CHAR_SYMBOLS[(rand | mask) % CHAR_SYMBOLS.length]; - } - } - // Use the old way for the remaining characters - // I am doing this because I am too lazy to think of something more clever - for (; i < chars.length; i++) { - chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; - } - return (chars); + return (chars); + } + + /** + * Returns a new string filled with random text + * + * @param rng + * @param strLen + * @return + */ + public static String randomStr(Random rng, int strLen) { + return new String(randomChars(rng, strLen)); + } + + /** + * Resize the given block of text by the delta and add random characters to the new space in the + * array. Returns a new character array + * + * @param rng + * @param orig + * @param delta + * @return + */ + public static char[] resizeText(Random rng, char[] orig, int delta) { + char[] chars = Arrays.copyOf(orig, orig.length + delta); + for (int i = orig.length; i < chars.length; i++) { + chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; } - - /** - * Returns a new string filled with random text - * - * @param rng - * @param strLen - * @return - */ - public static String randomStr(Random rng, int strLen) { - return new String(randomChars(rng, strLen)); - } - - /** - * Resize the given block of text by the delta and add random characters - * to the new space in the array. Returns a new character array - * - * @param rng - * @param orig - * @param delta - * @return - */ - public static char[] resizeText(Random rng, char[] orig, int delta) { - char[] chars = Arrays.copyOf(orig, orig.length + delta); - for (int i = orig.length; i < chars.length; i++) { - chars[i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; - } - return (chars); + return (chars); + } + + /** + * Permute a random portion of the origin text Returns the same character array that was given as + * input + * + * @param rng + * @param chars + * @return + */ + public static char[] permuteText(Random rng, char[] chars) { + // We will try to be fast about this and permute the text by blocks + int idx = 0; + int blockSize = chars.length / 32; + + // We'll generate one random number and check whether its bit is set to zero + // Hopefully this is faster than having to generate a bunch of random + // integers + int rand = rng.nextInt(); + // If the number is zero, then flip one bit so that we make sure that + // we change at least one block + if (rand == 0) { + rand = 1; } - - /** - * Permute a random portion of the origin text - * Returns the same character array that was given as input - * - * @param rng - * @param chars - * @return - */ - public static char[] permuteText(Random rng, char[] chars) { - // We will try to be fast about this and permute the text by blocks - int idx = 0; - int blockSize = chars.length / 32; - - // We'll generate one random number and check whether its bit is set to zero - // Hopefully this is faster than having to generate a bunch of random - // integers - int rand = rng.nextInt(); - // If the number is zero, then flip one bit so that we make sure that - // we change at least one block - if (rand == 0) { - rand = 1; + for (int bit = 0; bit < 32; bit++) { + if ((rand >> bit & 1) == 1) { + for (int i = 0; i < blockSize; i++) { + chars[idx + i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; } - for (int bit = 0; bit < 32; bit++) { - if ((rand >> bit & 1) == 1) { - for (int i = 0; i < blockSize; i++) { - chars[idx + i] = CHAR_SYMBOLS[rng.nextInt(CHAR_SYMBOLS.length)]; - } - } - idx += blockSize; - if (idx >= chars.length) { - break; - } - } - - return (chars); + } + idx += blockSize; + if (idx >= chars.length) { + break; + } } + return (chars); + } } diff --git a/src/main/java/com/oltpbenchmark/util/ThreadUtil.java b/src/main/java/com/oltpbenchmark/util/ThreadUtil.java index 79a6b09a5..8c6065daf 100644 --- a/src/main/java/com/oltpbenchmark/util/ThreadUtil.java +++ b/src/main/java/com/oltpbenchmark/util/ThreadUtil.java @@ -45,111 +45,121 @@ package com.oltpbenchmark.util; import com.oltpbenchmark.api.LoaderThread; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.util.Collection; import java.util.List; import java.util.concurrent.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class ThreadUtil { - private static final Logger LOG = LoggerFactory.getLogger(ThreadUtil.class); - - public static int availableProcessors() { - return Math.max(1, Runtime.getRuntime().availableProcessors()); + private static final Logger LOG = LoggerFactory.getLogger(ThreadUtil.class); + + public static int availableProcessors() { + return Math.max(1, Runtime.getRuntime().availableProcessors()); + } + + /** + * For a given list of threads, execute them all (up to max_concurrent at a time) and return once + * they have completed. If max_concurrent is null, then all threads will be fired off at the same + * time + * + * @param loaderThreads + * @param maxConcurrent + * @throws Exception + */ + public static void runLoaderThreads( + final Collection loaderThreads, int maxConcurrent) throws InterruptedException { + + final int loaderThreadSize = loaderThreads.size(); + + int poolSize = Math.max(1, Math.min(maxConcurrent, loaderThreadSize)); + + int threadOverflow = (loaderThreadSize > poolSize ? loaderThreadSize - poolSize : 0); + + if (LOG.isInfoEnabled()) { + LOG.info( + "Creating a Thread Pool with a size of {} to run {} Loader Threads. {} threads will be queued.", + poolSize, + loaderThreadSize, + threadOverflow); } + ExecutorService service = Executors.newFixedThreadPool(poolSize, factory); - /** - * For a given list of threads, execute them all (up to max_concurrent at a - * time) and return once they have completed. If max_concurrent is null, - * then all threads will be fired off at the same time - * - * @param loaderThreads - * @param maxConcurrent - * @throws Exception - */ - public static void runLoaderThreads(final Collection loaderThreads, int maxConcurrent) throws InterruptedException { - - final int loaderThreadSize = loaderThreads.size(); - - int poolSize = Math.max(1, Math.min(maxConcurrent, loaderThreadSize)); - - int threadOverflow = (loaderThreadSize > poolSize ? loaderThreadSize - poolSize : 0); - - if (LOG.isInfoEnabled()) { - LOG.info("Creating a Thread Pool with a size of {} to run {} Loader Threads. {} threads will be queued.", poolSize, loaderThreadSize, threadOverflow); - } - - ExecutorService service = Executors.newFixedThreadPool(poolSize, factory); - - final long start = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); - final CountDownLatch latch = new CountDownLatch(loaderThreadSize); + final CountDownLatch latch = new CountDownLatch(loaderThreadSize); - try { - for (LoaderThread loaderThread : loaderThreads) { - service.execute(new LatchRunnable(loaderThread, latch)); - } + try { + for (LoaderThread loaderThread : loaderThreads) { + service.execute(new LatchRunnable(loaderThread, latch)); + } - LOG.trace("All Loader Threads executed; waiting on latches..."); - latch.await(); + LOG.trace("All Loader Threads executed; waiting on latches..."); + latch.await(); - } finally { + } finally { - LOG.trace("Attempting to shutdown the pool..."); + LOG.trace("Attempting to shutdown the pool..."); - service.shutdown(); + service.shutdown(); - boolean cleanTermination = service.awaitTermination(5, TimeUnit.MINUTES); + boolean cleanTermination = service.awaitTermination(5, TimeUnit.MINUTES); - if (cleanTermination) { - LOG.trace("Pool shut down cleanly!"); - } else { - LOG.warn("Pool shut down after termination timeout expired. Likely caused by an unhandled exception in a Loader Thread causing latch count down. Will force shutdown now."); + if (cleanTermination) { + LOG.trace("Pool shut down cleanly!"); + } else { + LOG.warn( + "Pool shut down after termination timeout expired. Likely caused by an unhandled exception in a Loader Thread causing latch count down. Will force shutdown now."); - List notStarted = service.shutdownNow(); + List notStarted = service.shutdownNow(); - LOG.warn("{} Loader Threads were terminated before starting.", notStarted.size()); - } - - if (LOG.isInfoEnabled()) { - final long stop = System.currentTimeMillis(); - LOG.info(String.format("Finished executing %d Loader Threads [time=%.02fs]", loaderThreadSize, (stop - start) / 1000d)); - } - } + LOG.warn("{} Loader Threads were terminated before starting.", notStarted.size()); + } + if (LOG.isInfoEnabled()) { + final long stop = System.currentTimeMillis(); + LOG.info( + String.format( + "Finished executing %d Loader Threads [time=%.02fs]", + loaderThreadSize, (stop - start) / 1000d)); + } } + } - private static final ThreadFactory factory = new ThreadFactory() { + private static final ThreadFactory factory = + new ThreadFactory() { @Override public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setDaemon(true); - return (t); + Thread t = new Thread(r); + t.setDaemon(true); + return (t); } - }; + }; - private static class LatchRunnable implements Runnable { - private final LoaderThread loaderThread; - private final CountDownLatch latch; + private static class LatchRunnable implements Runnable { + private final LoaderThread loaderThread; + private final CountDownLatch latch; - public LatchRunnable(LoaderThread loaderThread, CountDownLatch latch) { - this.loaderThread = loaderThread; - this.latch = latch; - } - - @Override - public void run() { - try { - this.loaderThread.run(); - } catch (Exception e) { - LOG.error(String.format("Exception in Loader Thread with message: [%s]; will count down latch with count %d and then exit :(", e.getMessage(), this.latch.getCount()), e); - System.exit(1); - } finally { - this.latch.countDown(); - } - } + public LatchRunnable(LoaderThread loaderThread, CountDownLatch latch) { + this.loaderThread = loaderThread; + this.latch = latch; } + @Override + public void run() { + try { + this.loaderThread.run(); + } catch (Exception e) { + LOG.error( + String.format( + "Exception in Loader Thread with message: [%s]; will count down latch with count %d and then exit :(", + e.getMessage(), this.latch.getCount()), + e); + System.exit(1); + } finally { + this.latch.countDown(); + } + } + } } diff --git a/src/main/java/com/oltpbenchmark/util/TimeUtil.java b/src/main/java/com/oltpbenchmark/util/TimeUtil.java index f91228ab1..82675c835 100644 --- a/src/main/java/com/oltpbenchmark/util/TimeUtil.java +++ b/src/main/java/com/oltpbenchmark/util/TimeUtil.java @@ -22,31 +22,29 @@ public abstract class TimeUtil { - public final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); - public final static SimpleDateFormat DATE_FORMAT_14 = new SimpleDateFormat("yyyyMMddHHmmss"); + public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); + public static final SimpleDateFormat DATE_FORMAT_14 = new SimpleDateFormat("yyyyMMddHHmmss"); - /** - * TODO(djellel) - * - * @return - */ - public static String getCurrentTimeString14() { - return TimeUtil.DATE_FORMAT_14.format(new java.util.Date()); - } + /** + * TODO(djellel) + * + * @return + */ + public static String getCurrentTimeString14() { + return TimeUtil.DATE_FORMAT_14.format(new java.util.Date()); + } - /** - * TODO(djellel) - * - * @return - */ - public static String getCurrentTimeString() { - return TimeUtil.DATE_FORMAT.format(new java.util.Date()); - } + /** + * TODO(djellel) + * + * @return + */ + public static String getCurrentTimeString() { + return TimeUtil.DATE_FORMAT.format(new java.util.Date()); + } - /** - * Get a timestamp of the current time - */ - public static Timestamp getCurrentTime() { - return new Timestamp(System.currentTimeMillis()); - } + /** Get a timestamp of the current time */ + public static Timestamp getCurrentTime() { + return new Timestamp(System.currentTimeMillis()); + } } diff --git a/src/test/java/com/oltpbenchmark/api/AbstractTestBenchmarkModule.java b/src/test/java/com/oltpbenchmark/api/AbstractTestBenchmarkModule.java index 9555ca45f..ff366e83b 100644 --- a/src/test/java/com/oltpbenchmark/api/AbstractTestBenchmarkModule.java +++ b/src/test/java/com/oltpbenchmark/api/AbstractTestBenchmarkModule.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.api; import static org.junit.Assert.assertEquals; @@ -26,7 +25,6 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.ClassUtil; - import java.io.File; import java.io.InputStream; import java.net.URL; @@ -36,170 +34,150 @@ import java.util.stream.Collectors; import org.junit.Test; -public abstract class AbstractTestBenchmarkModule extends AbstractTestCase { - - - public AbstractTestBenchmarkModule() { - super(false, false); +public abstract class AbstractTestBenchmarkModule + extends AbstractTestCase { + + public AbstractTestBenchmarkModule() { + super(false, false); + } + + @Override + public List ignorableTables() { + return null; + } + + /** testGetDatabaseDDLPath */ + @Test + public void testGetDatabaseDDLPath() throws Exception { + String ddlPath = this.benchmark.getDatabaseDDLPath(this.workConf.getDatabaseType()); + assertNotNull(ddlPath); + try (InputStream stream = this.getClass().getResourceAsStream(ddlPath)) { + assertNotNull(stream); } - - @Override - public List ignorableTables() { - return null; + } + + /** testCreateDatabase */ + @Test + public void testCreateDatabase() throws Exception { + this.benchmark.createDatabase(); + + // Make sure that we get back some tables + this.benchmark.refreshCatalog(); + AbstractCatalog catalog = this.benchmark.getCatalog(); + assertNotNull(catalog); + assertFalse(catalog.getTables().isEmpty()); + + // Just make sure that there are no empty tables + for (Table catalog_tbl : catalog.getTables()) { + assert (catalog_tbl.getColumnCount() > 0) : "Missing columns for " + catalog_tbl; } - - /** - * testGetDatabaseDDLPath - */ - @Test - public void testGetDatabaseDDLPath() throws Exception { - String ddlPath = this.benchmark.getDatabaseDDLPath(this.workConf.getDatabaseType()); - assertNotNull(ddlPath); - try (InputStream stream = this.getClass().getResourceAsStream(ddlPath)) { - assertNotNull(stream); - } + } + + /** testGetTransactionType */ + @Test + public void testGetTransactionType() { + int id = 1; + for (Class procClass : procedures()) { + assertNotNull(procClass); + String procName = procClass.getSimpleName(); + TransactionType txnType = this.benchmark.initTransactionType(procName, id++, 0, 0); + assertNotNull(txnType); + assertEquals(procClass, txnType.getProcedureClass()); } - - /** - * testCreateDatabase - */ - @Test - public void testCreateDatabase() throws Exception { - this.benchmark.createDatabase(); - - // Make sure that we get back some tables - this.benchmark.refreshCatalog(); - AbstractCatalog catalog = this.benchmark.getCatalog(); - assertNotNull(catalog); - assertFalse(catalog.getTables().isEmpty()); - - // Just make sure that there are no empty tables - for (Table catalog_tbl : catalog.getTables()) { - assert (catalog_tbl.getColumnCount() > 0) : "Missing columns for " + catalog_tbl; - } + } + + /** testGetSQLDialectPath */ + @Test + public void testGetSQLDialectPath() throws Exception { + for (DatabaseType dbType : DatabaseType.values()) { + String xmlFilePath = this.benchmark.getStatementDialects().getSQLDialectPath(dbType); + if (xmlFilePath != null) { + URL xmlUrl = this.getClass().getResource(xmlFilePath); + assertNotNull(xmlUrl); + File xmlFile = new File(xmlUrl.toURI()); + assertTrue(xmlFile.getAbsolutePath(), xmlFile.exists()); + } } - - /** - * testGetTransactionType - */ - @Test - public void testGetTransactionType() { - int id = 1; - for (Class procClass : procedures()) { - assertNotNull(procClass); - String procName = procClass.getSimpleName(); - TransactionType txnType = this.benchmark.initTransactionType(procName, id++, 0, 0); - assertNotNull(txnType); - assertEquals(procClass, txnType.getProcedureClass()); + } + + /** testLoadSQLDialect */ + @Test + public void testLoadSQLDialect() throws Exception { + for (DatabaseType dbType : DatabaseType.values()) { + this.workConf.setDatabaseType(dbType); + + // Just make sure that we can load it + StatementDialects dialects = new StatementDialects(this.workConf); + if (dialects.load()) { + + for (String procName : dialects.getProcedureNames()) { + for (String stmtName : dialects.getStatementNames(procName)) { + String sql = dialects.getSQL(procName, stmtName); + assertNotNull(sql); + assertFalse(sql.isEmpty()); + } } + } } - - - /** - * testGetSQLDialectPath - */ - @Test - public void testGetSQLDialectPath() throws Exception { - for (DatabaseType dbType : DatabaseType.values()) { - String xmlFilePath = this.benchmark.getStatementDialects().getSQLDialectPath(dbType); - if (xmlFilePath != null) { - URL xmlUrl = this.getClass().getResource(xmlFilePath); - assertNotNull(xmlUrl); - File xmlFile = new File(xmlUrl.toURI()); - assertTrue(xmlFile.getAbsolutePath(), xmlFile.exists()); + } + + /** testDumpSQLDialect */ + @Test + public void testDumpSQLDialect() throws Exception { + for (DatabaseType dbType : DatabaseType.values()) { + this.workConf.setDatabaseType(dbType); + + StatementDialects dialects = new StatementDialects(this.workConf); + if (dialects.load()) { + String dump = dialects.export(dbType, this.benchmark.getProcedures().values()); + assertNotNull(dump); + assertFalse(dump.isEmpty()); + Set benchmarkProcedureNames = + this.benchmark.getProcedures().values().stream() + .map(Procedure::getProcedureName) + .collect(Collectors.toSet()); + for (String procName : dialects.getProcedureNames()) { + if (benchmarkProcedureNames.contains(procName)) { + assertTrue(procName, dump.contains(procName)); + for (String stmtName : dialects.getStatementNames(procName)) { + assertTrue(procName + "." + stmtName, dump.contains(stmtName)); } + } } + } } - - /** - * testLoadSQLDialect - */ - @Test - public void testLoadSQLDialect() throws Exception { - for (DatabaseType dbType : DatabaseType.values()) { - this.workConf.setDatabaseType(dbType); - - // Just make sure that we can load it - StatementDialects dialects = new StatementDialects(this.workConf); - if (dialects.load()) { - - for (String procName : dialects.getProcedureNames()) { - for (String stmtName : dialects.getStatementNames(procName)) { - String sql = dialects.getSQL(procName, stmtName); - assertNotNull(sql); - assertFalse(sql.isEmpty()); - } - } - - } - } - } - - - /** - * testDumpSQLDialect - */ - @Test - public void testDumpSQLDialect() throws Exception { - for (DatabaseType dbType : DatabaseType.values()) { - this.workConf.setDatabaseType(dbType); - - StatementDialects dialects = new StatementDialects(this.workConf); - if (dialects.load()) { - String dump = dialects.export(dbType, this.benchmark.getProcedures().values()); - assertNotNull(dump); - assertFalse(dump.isEmpty()); - Set benchmarkProcedureNames = this.benchmark.getProcedures().values() - .stream() - .map(Procedure::getProcedureName) - .collect(Collectors.toSet()); - for (String procName : dialects.getProcedureNames()) { - if (benchmarkProcedureNames.contains(procName)) { - assertTrue(procName, dump.contains(procName)); - for (String stmtName : dialects.getStatementNames(procName)) { - assertTrue(procName + "." + stmtName, dump.contains(stmtName)); - } - } - } + } + + /** testSetSQLDialect */ + @Test + public void testSetSQLDialect() throws Exception { + for (DatabaseType dbType : DatabaseType.values()) { + this.workConf.setDatabaseType(dbType); + + StatementDialects dialects = new StatementDialects(this.workConf); + if (dialects.load()) { + + for (Procedure proc : this.benchmark.getProcedures().values()) { + if (dialects.getProcedureNames().contains(proc.getProcedureName())) { + // Need a new proc because the dialect gets loaded in BenchmarkModule::getProcedureName + Procedure testProc = + ClassUtil.newInstance(proc.getClass().getName(), new Object[0], new Class[0]); + assertNotNull(testProc); + testProc.initialize(dbType); + testProc.loadSQLDialect(dialects); + + Collection dialectStatementNames = + dialects.getStatementNames(testProc.getProcedureName()); + + for (String statementName : dialectStatementNames) { + SQLStmt stmt = testProc.getStatements().get(statementName); + assertNotNull(stmt); + String dialectSQL = dialects.getSQL(testProc.getProcedureName(), statementName); + assertEquals(dialectSQL, stmt.getOriginalSQL()); } + } } + } } - - - /** - * testSetSQLDialect - */ - @Test - public void testSetSQLDialect() throws Exception { - for (DatabaseType dbType : DatabaseType.values()) { - this.workConf.setDatabaseType(dbType); - - StatementDialects dialects = new StatementDialects(this.workConf); - if (dialects.load()) { - - for (Procedure proc : this.benchmark.getProcedures().values()) { - if (dialects.getProcedureNames().contains(proc.getProcedureName())) { - // Need a new proc because the dialect gets loaded in BenchmarkModule::getProcedureName - Procedure testProc = ClassUtil.newInstance(proc.getClass().getName(), - new Object[0], new Class[0]); - assertNotNull(testProc); - testProc.initialize(dbType); - testProc.loadSQLDialect(dialects); - - Collection dialectStatementNames = dialects.getStatementNames( - testProc.getProcedureName()); - - for (String statementName : dialectStatementNames) { - SQLStmt stmt = testProc.getStatements().get(statementName); - assertNotNull(stmt); - String dialectSQL = dialects.getSQL(testProc.getProcedureName(), - statementName); - assertEquals(dialectSQL, stmt.getOriginalSQL()); - } - } - } - } - } - } - + } } diff --git a/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java b/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java index 5f7f2fcd8..8edfa40d6 100644 --- a/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java +++ b/src/test/java/com/oltpbenchmark/api/AbstractTestCase.java @@ -24,6 +24,13 @@ import com.oltpbenchmark.catalog.AbstractCatalog; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.ClassUtil; +import java.io.IOException; +import java.net.BindException; +import java.net.ServerSocket; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; import org.hsqldb.Database; import org.hsqldb.persist.HsqlProperties; import org.hsqldb.server.Server; @@ -35,230 +42,218 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.sql.Connection; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; -import java.net.ServerSocket; -import java.net.BindException; - public abstract class AbstractTestCase { - protected final Logger LOG = LoggerFactory.getLogger(getClass()); + protected final Logger LOG = LoggerFactory.getLogger(getClass()); - // ----------------------------------------------------------------- + // ----------------------------------------------------------------- - /** - * This is the database type that we will use in our unit tests. - * This should always be one of the embedded java databases - */ - private static final DatabaseType DB_TYPE = DatabaseType.HSQLDB; + /** + * This is the database type that we will use in our unit tests. This should always be one of the + * embedded java databases + */ + private static final DatabaseType DB_TYPE = DatabaseType.HSQLDB; + // ----------------------------------------------------------------- - // ----------------------------------------------------------------- + protected static final double DB_SCALE_FACTOR = 0.01; - protected static final double DB_SCALE_FACTOR = 0.01; + private Server server = null; - private Server server = null; + protected WorkloadConfiguration workConf; + protected T benchmark; + protected AbstractCatalog catalog; + protected Connection conn; - protected WorkloadConfiguration workConf; - protected T benchmark; - protected AbstractCatalog catalog; - protected Connection conn; + protected final boolean createDatabase; + protected final boolean loadDatabase; + protected final String ddlOverridePath; - protected final boolean createDatabase; - protected final boolean loadDatabase; - protected final String ddlOverridePath; + private static final AtomicInteger portCounter = new AtomicInteger(9001); + private static final int MAX_PORT_NUMBER = 65535; - private static final AtomicInteger portCounter = new AtomicInteger(9001); - private static final int MAX_PORT_NUMBER = 65535; + public AbstractTestCase(boolean createDatabase, boolean loadDatabase) { + this.benchmark = null; + this.createDatabase = createDatabase; + this.loadDatabase = loadDatabase; + this.ddlOverridePath = null; + } + public AbstractTestCase(boolean createDatabase, boolean loadDatabase, String ddlOverridePath) { + this.benchmark = null; + this.createDatabase = createDatabase; + this.loadDatabase = loadDatabase; + this.ddlOverridePath = ddlOverridePath; + } - public AbstractTestCase(boolean createDatabase, boolean loadDatabase) { - this.benchmark = null; - this.createDatabase = createDatabase; - this.loadDatabase = loadDatabase; - this.ddlOverridePath = null; - } + public abstract List> procedures(); - public AbstractTestCase(boolean createDatabase, boolean loadDatabase, String ddlOverridePath) { - this.benchmark = null; - this.createDatabase = createDatabase; - this.loadDatabase = loadDatabase; - this.ddlOverridePath = ddlOverridePath; - } + public abstract Class benchmarkClass(); - public abstract List> procedures(); + public abstract List ignorableTables(); - public abstract Class benchmarkClass(); + @Rule public TestName name = new TestName(); - public abstract List ignorableTables(); + @Before + public final void setUp() throws Exception { + HsqlProperties props = new HsqlProperties(); + // props.setProperty("server.remote_open", true); - @Rule - public TestName name = new TestName(); + int port = findAvailablePort(); - @Before - public final void setUp() throws Exception { - HsqlProperties props = new HsqlProperties(); - //props.setProperty("server.remote_open", true); + LOG.info("starting HSQLDB server for test [{}] on port [{}]", name.getMethodName(), port); - int port = findAvailablePort(); + server = new Server(); + server.setProperties(props); + server.setDatabasePath(0, "mem:benchbase;sql.syntax_mys=true"); + server.setDatabaseName(0, "benchbase"); + server.setAddress("localhost"); + server.setPort(port); + server.setSilent(true); + server.setLogWriter(null); + server.start(); - LOG.info("starting HSQLDB server for test [{}] on port [{}]", name.getMethodName(), port); + this.workConf = new WorkloadConfiguration(); - server = new Server(); - server.setProperties(props); - server.setDatabasePath(0, "mem:benchbase;sql.syntax_mys=true"); - server.setDatabaseName(0, "benchbase"); - server.setAddress("localhost"); - server.setPort(port); - server.setSilent(true); - server.setLogWriter(null); - server.start(); + String DB_CONNECTION = + String.format("jdbc:hsqldb:hsql://localhost:%d/benchbase", server.getPort()); - this.workConf = new WorkloadConfiguration(); + this.workConf.setTransTypes(proceduresToTransactionTypes(procedures())); + this.workConf.setDatabaseType(DB_TYPE); + this.workConf.setUrl(DB_CONNECTION); + this.workConf.setScaleFactor(DB_SCALE_FACTOR); + this.workConf.setTerminals(1); + this.workConf.setBatchSize(128); + this.workConf.setBenchmarkName( + BenchmarkModule.convertBenchmarkClassToBenchmarkName(benchmarkClass())); + this.workConf.setDDLPath(this.ddlOverridePath); - String DB_CONNECTION = String.format("jdbc:hsqldb:hsql://localhost:%d/benchbase", server.getPort()); - - this.workConf.setTransTypes(proceduresToTransactionTypes(procedures())); - this.workConf.setDatabaseType(DB_TYPE); - this.workConf.setUrl(DB_CONNECTION); - this.workConf.setScaleFactor(DB_SCALE_FACTOR); - this.workConf.setTerminals(1); - this.workConf.setBatchSize(128); - this.workConf.setBenchmarkName(BenchmarkModule.convertBenchmarkClassToBenchmarkName(benchmarkClass())); - this.workConf.setDDLPath(this.ddlOverridePath); - - customWorkloadConfiguration(this.workConf); - - this.benchmark = ClassUtil.newInstance(benchmarkClass(), - new Object[]{this.workConf}, - new Class[]{WorkloadConfiguration.class}); - assertNotNull(this.benchmark); - - // HACK: calling this a second time is a cheap no-op for most benchmark - // tests, but actually ensures that the procedures list is populated - // for the TestTemplatedWorker test which doesn't know its procedures - // until after the benchmark is initialized and the config is loaded. - var proceedures = this.procedures(); - assertNotNull(proceedures); - if (!(this instanceof TestDDLOverride)) { - assertFalse(proceedures.isEmpty()); - } + customWorkloadConfiguration(this.workConf); - this.conn = this.benchmark.makeConnection(); - assertNotNull(this.conn); + this.benchmark = + ClassUtil.newInstance( + benchmarkClass(), + new Object[] {this.workConf}, + new Class[] {WorkloadConfiguration.class}); + assertNotNull(this.benchmark); - this.benchmark.refreshCatalog(); - this.catalog = this.benchmark.getCatalog(); - assertNotNull(this.catalog); - - if (createDatabase) { - this.createDatabase(); - } - - if (loadDatabase) { - this.loadDatabase(); - } - - try { - postCreateDatabaseSetup(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - cleanupServer(); - fail("postCreateDatabaseSetup() failed"); - } + // HACK: calling this a second time is a cheap no-op for most benchmark + // tests, but actually ensures that the procedures list is populated + // for the TestTemplatedWorker test which doesn't know its procedures + // until after the benchmark is initialized and the config is loaded. + var proceedures = this.procedures(); + assertNotNull(proceedures); + if (!(this instanceof TestDDLOverride)) { + assertFalse(proceedures.isEmpty()); } - private int findAvailablePort() throws IOException { - while (true) { - int port = portCounter.incrementAndGet(); - - if (port > MAX_PORT_NUMBER) { - throw new IOException("No available port found up to " + MAX_PORT_NUMBER); - } - - try (ServerSocket testSocket = new ServerSocket(port)) { - assert testSocket != null; - return port; - } catch (BindException e) { - // This port is already in use. Continue to next port. - LOG.warn("Port {} is already in use. Trying next port.", port); - } - } - } + this.conn = this.benchmark.makeConnection(); + assertNotNull(this.conn); - protected TransactionTypes proceduresToTransactionTypes(List> procedures) { - TransactionTypes txnTypes = new TransactionTypes(new ArrayList<>()); - - int id = 0; - for (Class procedureClass : procedures) { - TransactionType tt = new TransactionType(procedureClass, id++, false, 0, 0); - txnTypes.add(tt); - } + this.benchmark.refreshCatalog(); + this.catalog = this.benchmark.getCatalog(); + assertNotNull(this.catalog); - return txnTypes; + if (createDatabase) { + this.createDatabase(); } - protected void createDatabase() { - try { - this.benchmark.createDatabase(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - cleanupServer(); - fail("createDatabase() failed"); - } + if (loadDatabase) { + this.loadDatabase(); } - protected void loadDatabase() { - try { - this.benchmark.loadDatabase(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - cleanupServer(); - fail("loadDatabase() failed"); - } + try { + postCreateDatabaseSetup(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + cleanupServer(); + fail("postCreateDatabaseSetup() failed"); + } + } + + private int findAvailablePort() throws IOException { + while (true) { + int port = portCounter.incrementAndGet(); + + if (port > MAX_PORT_NUMBER) { + throw new IOException("No available port found up to " + MAX_PORT_NUMBER); + } + + try (ServerSocket testSocket = new ServerSocket(port)) { + assert testSocket != null; + return port; + } catch (BindException e) { + // This port is already in use. Continue to next port. + LOG.warn("Port {} is already in use. Trying next port.", port); + } } + } - protected void customWorkloadConfiguration(WorkloadConfiguration workConf) { + protected TransactionTypes proceduresToTransactionTypes( + List> procedures) { + TransactionTypes txnTypes = new TransactionTypes(new ArrayList<>()); + int id = 0; + for (Class procedureClass : procedures) { + TransactionType tt = new TransactionType(procedureClass, id++, false, 0, 0); + txnTypes.add(tt); } - protected void postCreateDatabaseSetup() throws IOException { + return txnTypes; + } + protected void createDatabase() { + try { + this.benchmark.createDatabase(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + cleanupServer(); + fail("createDatabase() failed"); } + } + + protected void loadDatabase() { + try { + this.benchmark.loadDatabase(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + cleanupServer(); + fail("loadDatabase() failed"); + } + } + protected void customWorkloadConfiguration(WorkloadConfiguration workConf) {} - @After - public final void tearDown() throws Exception { + protected void postCreateDatabaseSetup() throws IOException {} - if (this.conn != null) { - this.conn.close(); - } + @After + public final void tearDown() throws Exception { - cleanupServer(); + if (this.conn != null) { + this.conn.close(); } - protected void cleanupServer() { - if (server != null) { - - LOG.trace("shutting down catalogs..."); - server.shutdownCatalogs(Database.CLOSEMODE_NORMAL); + cleanupServer(); + } - LOG.trace("stopping server..."); - server.stop(); + protected void cleanupServer() { + if (server != null) { - while (server.getState() != ServerConstants.SERVER_STATE_SHUTDOWN) { - try { - Thread.sleep(100); - } catch (InterruptedException ignore) { - } - } + LOG.trace("shutting down catalogs..."); + server.shutdownCatalogs(Database.CLOSEMODE_NORMAL); - LOG.trace("shutting down server..."); - server.shutdown(); + LOG.trace("stopping server..."); + server.stop(); + while (server.getState() != ServerConstants.SERVER_STATE_SHUTDOWN) { + try { + Thread.sleep(100); + } catch (InterruptedException ignore) { } + } + + LOG.trace("shutting down server..."); + server.shutdown(); } + } } diff --git a/src/test/java/com/oltpbenchmark/api/AbstractTestLoader.java b/src/test/java/com/oltpbenchmark/api/AbstractTestLoader.java index cbfc7bc75..eff474615 100644 --- a/src/test/java/com/oltpbenchmark/api/AbstractTestLoader.java +++ b/src/test/java/com/oltpbenchmark/api/AbstractTestLoader.java @@ -14,117 +14,116 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.api; +import static org.junit.Assert.*; +import static org.junit.Assert.fail; + import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.Histogram; import com.oltpbenchmark.util.SQLUtil; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; - -import static org.junit.Assert.*; -import static org.junit.Assert.fail; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public abstract class AbstractTestLoader extends AbstractTestCase { - private static final Logger LOG = LoggerFactory.getLogger(AbstractTestLoader.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractTestLoader.class); - public AbstractTestLoader() { - super(true, false); - } + public AbstractTestLoader() { + super(true, false); + } - @Override - public List ignorableTables() { - return null; - } + @Override + public List ignorableTables() { + return null; + } - /** - * testLoad - */ - @Test - public void testLoad() throws Exception { + /** testLoad */ + @Test + public void testLoad() throws Exception { - this.benchmark.loadDatabase(); + this.benchmark.loadDatabase(); - validateLoad(); + validateLoad(); + } - } + /** testLoad with after load script */ + @Test + public void testLoadWithAfterLoad() throws Exception { + this.benchmark.setAfterLoadScriptPath("/after-load.sql"); + + this.benchmark.loadDatabase(); - /** - * testLoad with after load script - */ - @Test - public void testLoadWithAfterLoad() throws Exception { - this.benchmark.setAfterLoadScriptPath("/after-load.sql"); - - this.benchmark.loadDatabase(); - - // A table called extra is added with after-load, with one entry zero - try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM extra"); ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - assertEquals("Table 'extra' from after-load.sql has value different than 0", rs.getInt(1), 0); - } - } catch (Exception e) { - fail("Table 'extra' from after-load.sql was not created"); - } - - validateLoad(); + // A table called extra is added with after-load, with one entry zero + try (PreparedStatement stmt = conn.prepareStatement("SELECT * FROM extra"); + ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + assertEquals( + "Table 'extra' from after-load.sql has value different than 0", rs.getInt(1), 0); + } + } catch (Exception e) { + fail("Table 'extra' from after-load.sql was not created"); } - private void validateLoad() throws SQLException { - assertFalse("Failed to get table names for " + benchmark.getBenchmarkName().toUpperCase(), this.catalog.getTables().isEmpty()); + validateLoad(); + } + private void validateLoad() throws SQLException { + assertFalse( + "Failed to get table names for " + benchmark.getBenchmarkName().toUpperCase(), + this.catalog.getTables().isEmpty()); - LOG.debug("Computing the size of the tables"); - Histogram tableSizes = new Histogram(true); + LOG.debug("Computing the size of the tables"); + Histogram tableSizes = new Histogram(true); - for (Table table : this.catalog.getTables()) { - String tableName = table.getName(); - Table catalog_tbl = this.catalog.getTable(tableName); + for (Table table : this.catalog.getTables()) { + String tableName = table.getName(); + Table catalog_tbl = this.catalog.getTable(tableName); - String sql = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), catalog_tbl); + String sql = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), catalog_tbl); - try (Statement stmt = conn.createStatement(); - ResultSet result = stmt.executeQuery(sql);) { + try (Statement stmt = conn.createStatement(); + ResultSet result = stmt.executeQuery(sql); ) { - assertNotNull(result); + assertNotNull(result); - boolean adv = result.next(); - assertTrue(sql, adv); + boolean adv = result.next(); + assertTrue(sql, adv); - int count = result.getInt(1); - LOG.debug(sql + " => " + count); - tableSizes.put(tableName, count); - } - } + int count = result.getInt(1); + LOG.debug(sql + " => " + count); + tableSizes.put(tableName, count); + } + } - LOG.debug("=== TABLE SIZES ===\n" + tableSizes); - assertFalse("Unable to compute the tables size for " + benchmark.getBenchmarkName().toUpperCase(), tableSizes.isEmpty()); + LOG.debug("=== TABLE SIZES ===\n" + tableSizes); + assertFalse( + "Unable to compute the tables size for " + benchmark.getBenchmarkName().toUpperCase(), + tableSizes.isEmpty()); - for (String tableName : tableSizes.values()) { - long count = tableSizes.get(tableName); + for (String tableName : tableSizes.values()) { + long count = tableSizes.get(tableName); - if (ignorableTables() != null && ignorableTables().stream().anyMatch(tableName::equalsIgnoreCase)) { - continue; - } + if (ignorableTables() != null + && ignorableTables().stream().anyMatch(tableName::equalsIgnoreCase)) { + continue; + } - assert (count > 0) : "No tuples were inserted for table " + tableName; - } + assert (count > 0) : "No tuples were inserted for table " + tableName; } + } - public Loader testLoadWithReturn() throws Exception { - Loader loader = this.benchmark.loadDatabase(); + public Loader testLoadWithReturn() throws Exception { + Loader loader = this.benchmark.loadDatabase(); - validateLoad(); + validateLoad(); - return loader; - } + return loader; + } } diff --git a/src/test/java/com/oltpbenchmark/api/AbstractTestWorker.java b/src/test/java/com/oltpbenchmark/api/AbstractTestWorker.java index c9a59b751..cbb487194 100644 --- a/src/test/java/com/oltpbenchmark/api/AbstractTestWorker.java +++ b/src/test/java/com/oltpbenchmark/api/AbstractTestWorker.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.api; import static org.junit.Assert.assertEquals; @@ -22,87 +21,84 @@ import static org.junit.Assert.assertNotNull; import com.oltpbenchmark.api.Procedure.UserAbortException; -import org.apache.commons.lang3.time.StopWatch; - import java.io.IOException; import java.util.List; import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.time.StopWatch; import org.junit.Test; public abstract class AbstractTestWorker extends AbstractTestCase { - protected static final int NUM_TERMINALS = 1; - - protected List> workers; - - public AbstractTestWorker() { - super(true, true); - } - - public AbstractTestWorker(String ddlOverridePath) { - super(true, true, ddlOverridePath); + protected static final int NUM_TERMINALS = 1; + + protected List> workers; + + public AbstractTestWorker() { + super(true, true); + } + + public AbstractTestWorker(String ddlOverridePath) { + super(true, true, ddlOverridePath); + } + + @Override + public List ignorableTables() { + return null; + } + + @Override + protected void postCreateDatabaseSetup() throws IOException { + this.workers = this.benchmark.makeWorkers(); + assertNotNull(this.workers); + assertEquals(NUM_TERMINALS, this.workers.size()); + } + + /** testGetProcedure */ + @Test + public void testGetProcedure() { + // Make sure that we can get a Procedure handle for each TransactionType + Worker w = workers.get(0); + assertNotNull(w); + for (Class procClass : this.procedures()) { + assertNotNull(procClass); + Procedure proc = w.getProcedure(procClass); + assertNotNull("Failed to get procedure " + procClass.getSimpleName(), proc); + assertEquals(procClass, proc.getClass()); } - - @Override - public List ignorableTables() { - return null; - } - - @Override - protected void postCreateDatabaseSetup() throws IOException { - this.workers = this.benchmark.makeWorkers(); - assertNotNull(this.workers); - assertEquals(NUM_TERMINALS, this.workers.size()); - } - - /** - * testGetProcedure - */ - @Test - public void testGetProcedure() { - // Make sure that we can get a Procedure handle for each TransactionType - Worker w = workers.get(0); - assertNotNull(w); - for (Class procClass : this.procedures()) { - assertNotNull(procClass); - Procedure proc = w.getProcedure(procClass); - assertNotNull("Failed to get procedure " + procClass.getSimpleName(), proc); - assertEquals(procClass, proc.getClass()); - } - } - - /** - * testExecuteWork - */ - @Test - public void testExecuteWork() throws Exception { - - Worker w = workers.get(0); - assertNotNull(w); - w.initialize(); - assertFalse(this.conn.isReadOnly()); - for (TransactionType txnType : this.workConf.getTransTypes()) { - if (txnType.isSupplemental()) { - continue; - } - - StopWatch sw = new StopWatch(txnType.toString()); - - try { - LOG.info("starting execution of [{}]", txnType); - sw.start(); - w.executeWork(this.conn, txnType); - sw.stop(); - - - } catch (UserAbortException ex) { - // These are expected, so they can be ignored - // Anything else is a serious error - } catch (Throwable ex) { - throw new RuntimeException("Failed to execute " + txnType, ex); - } finally { - LOG.info("completed execution of [{}] in {} ms", txnType.toString(), sw.getTime(TimeUnit.MILLISECONDS)); - } - } + } + + /** testExecuteWork */ + @Test + public void testExecuteWork() throws Exception { + + Worker w = workers.get(0); + assertNotNull(w); + w.initialize(); + assertFalse(this.conn.isReadOnly()); + for (TransactionType txnType : this.workConf.getTransTypes()) { + if (txnType.isSupplemental()) { + continue; + } + + StopWatch sw = new StopWatch(txnType.toString()); + + try { + LOG.info("starting execution of [{}]", txnType); + sw.start(); + w.executeWork(this.conn, txnType); + sw.stop(); + + } catch (UserAbortException ex) { + // These are expected, so they can be ignored + // Anything else is a serious error + } catch (Throwable ex) { + throw new RuntimeException("Failed to execute " + txnType, ex); + } finally { + LOG.info( + "completed execution of [{}] in {} ms", + txnType.toString(), + sw.getTime(TimeUnit.MILLISECONDS)); + } } + } } diff --git a/src/test/java/com/oltpbenchmark/api/MockBenchmark.java b/src/test/java/com/oltpbenchmark/api/MockBenchmark.java index 5db859b6f..a2777cc5e 100644 --- a/src/test/java/com/oltpbenchmark/api/MockBenchmark.java +++ b/src/test/java/com/oltpbenchmark/api/MockBenchmark.java @@ -17,32 +17,31 @@ package com.oltpbenchmark.api; import com.oltpbenchmark.WorkloadConfiguration; - import java.io.IOException; import java.util.List; public final class MockBenchmark extends BenchmarkModule { - public MockBenchmark() { - super(new WorkloadConfiguration()); - this.workConf.setBenchmarkName("mockbenchmark"); - } - - public MockBenchmark(WorkloadConfiguration workConf) { - super(workConf); - } - - @Override - protected Package getProcedurePackageImpl() { - return null; - } - - @Override - protected Loader makeLoaderImpl() { - return null; - } - - @Override - protected List> makeWorkersImpl() throws IOException { - return null; - } -} \ No newline at end of file + public MockBenchmark() { + super(new WorkloadConfiguration()); + this.workConf.setBenchmarkName("mockbenchmark"); + } + + public MockBenchmark(WorkloadConfiguration workConf) { + super(workConf); + } + + @Override + protected Package getProcedurePackageImpl() { + return null; + } + + @Override + protected Loader makeLoaderImpl() { + return null; + } + + @Override + protected List> makeWorkersImpl() throws IOException { + return null; + } +} diff --git a/src/test/java/com/oltpbenchmark/api/TestDDLOverride.java b/src/test/java/com/oltpbenchmark/api/TestDDLOverride.java index 04f78eb40..593f41d23 100644 --- a/src/test/java/com/oltpbenchmark/api/TestDDLOverride.java +++ b/src/test/java/com/oltpbenchmark/api/TestDDLOverride.java @@ -7,7 +7,6 @@ import com.oltpbenchmark.catalog.Table; import com.oltpbenchmark.util.SQLUtil; - import java.nio.file.Paths; import java.sql.ResultSet; import java.sql.Statement; @@ -17,47 +16,54 @@ public class TestDDLOverride extends AbstractTestCase { - public TestDDLOverride() { - super(false, false, Paths.get("src", "test", "resources", "benchmarks", "mockbenchmark", "ddl-hsqldb.sql").toAbsolutePath().toString()); - } + public TestDDLOverride() { + super( + false, + false, + Paths.get("src", "test", "resources", "benchmarks", "mockbenchmark", "ddl-hsqldb.sql") + .toAbsolutePath() + .toString()); + } - @Override - public List> procedures() { - return new ArrayList<>(); - } + @Override + public List> procedures() { + return new ArrayList<>(); + } - @Override - public Class benchmarkClass() { - return MockBenchmark.class; - } + @Override + public Class benchmarkClass() { + return MockBenchmark.class; + } - @Override - public List ignorableTables() { - return null; - } + @Override + public List ignorableTables() { + return null; + } - @Test - public void testCreateWithDdlOverride() throws Exception { - this.benchmark.createDatabase(); + @Test + public void testCreateWithDdlOverride() throws Exception { + this.benchmark.createDatabase(); - assertFalse("Failed to get table names for " + benchmark.getBenchmarkName().toUpperCase(), this.catalog.getTables().isEmpty()); - for (Table table : this.catalog.getTables()) { - String tableName = table.getName(); - Table catalog_tbl = this.catalog.getTable(tableName); + assertFalse( + "Failed to get table names for " + benchmark.getBenchmarkName().toUpperCase(), + this.catalog.getTables().isEmpty()); + for (Table table : this.catalog.getTables()) { + String tableName = table.getName(); + Table catalog_tbl = this.catalog.getTable(tableName); - String sql = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), catalog_tbl); + String sql = SQLUtil.getCountSQL(this.workConf.getDatabaseType(), catalog_tbl); - try (Statement stmt = conn.createStatement(); - ResultSet result = stmt.executeQuery(sql);) { + try (Statement stmt = conn.createStatement(); + ResultSet result = stmt.executeQuery(sql); ) { - assertNotNull(result); + assertNotNull(result); - boolean adv = result.next(); - assertTrue(sql, adv); + boolean adv = result.next(); + assertTrue(sql, adv); - int count = result.getInt(1); - assertEquals(0, count); - } - } + int count = result.getInt(1); + assertEquals(0, count); + } } + } } diff --git a/src/test/java/com/oltpbenchmark/api/TestProcedure.java b/src/test/java/com/oltpbenchmark/api/TestProcedure.java index beeb4ec9f..ea3ec5875 100644 --- a/src/test/java/com/oltpbenchmark/api/TestProcedure.java +++ b/src/test/java/com/oltpbenchmark/api/TestProcedure.java @@ -21,60 +21,48 @@ import com.oltpbenchmark.benchmarks.tatp.procedures.DeleteCallForwarding; import com.oltpbenchmark.types.DatabaseType; - import java.util.Map; import org.junit.Before; import org.junit.Test; public class TestProcedure { - @Before - public void setUp() throws Exception { - - } - - /** - * testGetProcedureName - */ - @Test - public void testGetProcedureName() throws Exception { - DeleteCallForwarding proc = new DeleteCallForwarding(); - assertEquals(DeleteCallForwarding.class.getSimpleName(), proc.getProcedureName()); - } - - /** - * testGetStatements - */ - @Test - public void testGetStatements() throws Exception { - Map stmts = Procedure.getStatements(new DeleteCallForwarding()); - assertNotNull(stmts); - assertEquals(2, stmts.size()); -// System.err.println(stmts); - } - - /** - * testGetStatementsConstructor - */ - @Test - public void testGetStatementsConstructor() throws Exception { - Procedure proc = new DeleteCallForwarding(); - proc.initialize(DatabaseType.POSTGRES); - - // Make sure that procedure handle has the same - // SQLStmts as what we get back from the static method - Map expected = Procedure.getStatements(proc); - assertNotNull(expected); -// System.err.println("EXPECTED:" + expected); - - Map actual = proc.getStatements(); - assertNotNull(actual); -// System.err.println("ACTUAL:" + actual); - - assertEquals(expected.size(), actual.size()); - assertEquals(expected, actual); - - - } - + @Before + public void setUp() throws Exception {} + + /** testGetProcedureName */ + @Test + public void testGetProcedureName() throws Exception { + DeleteCallForwarding proc = new DeleteCallForwarding(); + assertEquals(DeleteCallForwarding.class.getSimpleName(), proc.getProcedureName()); + } + + /** testGetStatements */ + @Test + public void testGetStatements() throws Exception { + Map stmts = Procedure.getStatements(new DeleteCallForwarding()); + assertNotNull(stmts); + assertEquals(2, stmts.size()); + // System.err.println(stmts); + } + + /** testGetStatementsConstructor */ + @Test + public void testGetStatementsConstructor() throws Exception { + Procedure proc = new DeleteCallForwarding(); + proc.initialize(DatabaseType.POSTGRES); + + // Make sure that procedure handle has the same + // SQLStmts as what we get back from the static method + Map expected = Procedure.getStatements(proc); + assertNotNull(expected); + // System.err.println("EXPECTED:" + expected); + + Map actual = proc.getStatements(); + assertNotNull(actual); + // System.err.println("ACTUAL:" + actual); + + assertEquals(expected.size(), actual.size()); + assertEquals(expected, actual); + } } diff --git a/src/test/java/com/oltpbenchmark/api/TestSQLStmt.java b/src/test/java/com/oltpbenchmark/api/TestSQLStmt.java index 85b01a8f7..eaac3d089 100644 --- a/src/test/java/com/oltpbenchmark/api/TestSQLStmt.java +++ b/src/test/java/com/oltpbenchmark/api/TestSQLStmt.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.api; import static org.junit.Assert.assertEquals; @@ -24,40 +23,33 @@ public class TestSQLStmt { - /** - * testSubstitution - */ - @Test - public void testSubstitution() throws Exception { - int ctr = 25; - SQLStmt stmt = new SQLStmt( - "SELECT * FROM tweets WHERE uid IN (??)", ctr - ); - - String sql = stmt.getSQL(); - assertFalse(sql.isEmpty()); - assertFalse(sql.contains("\\?\\?")); - } - - /** - * testSetSQL - */ - @Test - public void testSetSQL() throws Exception { - int expected = 99; - SQLStmt stmt = new SQLStmt("SELECT * FROM tweets", expected); - stmt.setSQL("SELECT * FROM tweets WHERE uid IN (??)"); - - String sql = stmt.getSQL(); - assertFalse(sql.isEmpty()); - assertFalse(sql.contains("\\?\\?")); - - // Count the number of times '?' appears - int actual = 0; - for (int i = 0; i < sql.length(); i++) { - if (sql.charAt(i) == '?') actual++; - } // FOR - assertEquals(expected, actual); - } - + /** testSubstitution */ + @Test + public void testSubstitution() throws Exception { + int ctr = 25; + SQLStmt stmt = new SQLStmt("SELECT * FROM tweets WHERE uid IN (??)", ctr); + + String sql = stmt.getSQL(); + assertFalse(sql.isEmpty()); + assertFalse(sql.contains("\\?\\?")); + } + + /** testSetSQL */ + @Test + public void testSetSQL() throws Exception { + int expected = 99; + SQLStmt stmt = new SQLStmt("SELECT * FROM tweets", expected); + stmt.setSQL("SELECT * FROM tweets WHERE uid IN (??)"); + + String sql = stmt.getSQL(); + assertFalse(sql.isEmpty()); + assertFalse(sql.contains("\\?\\?")); + + // Count the number of times '?' appears + int actual = 0; + for (int i = 0; i < sql.length(); i++) { + if (sql.charAt(i) == '?') actual++; + } // FOR + assertEquals(expected, actual); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkBenchmark.java index da2c9b8e3..c9ff53221 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkBenchmark.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.auctionmark; import static org.junit.Assert.assertNotNull; @@ -25,7 +24,6 @@ import com.oltpbenchmark.api.TransactionType; import com.oltpbenchmark.benchmarks.auctionmark.procedures.*; import com.oltpbenchmark.benchmarks.auctionmark.util.CategoryParser; - import java.io.IOException; import java.util.List; import java.util.Map; @@ -33,49 +31,47 @@ public class TestAuctionMarkBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of(GetItem.class, - GetUserInfo.class, - NewBid.class, - NewComment.class, - NewCommentResponse.class, - NewFeedback.class, - NewItem.class, - NewPurchase.class, - UpdateItem.class); + public static final List> PROCEDURE_CLASSES = + List.of( + GetItem.class, + GetUserInfo.class, + NewBid.class, + NewComment.class, + NewCommentResponse.class, + NewFeedback.class, + NewItem.class, + NewPurchase.class, + UpdateItem.class); - @Override - public List> procedures() { - return PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return AuctionMarkBenchmark.class; - } + @Override + public Class benchmarkClass() { + return AuctionMarkBenchmark.class; + } - @Override - protected void postCreateDatabaseSetup() throws IOException { - super.postCreateDatabaseSetup(); - AuctionMarkProfile.clearCachedProfile(); - } + @Override + protected void postCreateDatabaseSetup() throws IOException { + super.postCreateDatabaseSetup(); + AuctionMarkProfile.clearCachedProfile(); + } - /** - * testCategoryParser - */ - @Test - public void testCategoryParser() throws Exception { - CategoryParser categoryParser = new CategoryParser(); - assertNotNull(categoryParser.getCategoryMap()); - assertTrue(categoryParser.getCategoryMap().size() > 0); - } + /** testCategoryParser */ + @Test + public void testCategoryParser() throws Exception { + CategoryParser categoryParser = new CategoryParser(); + assertNotNull(categoryParser.getCategoryMap()); + assertTrue(categoryParser.getCategoryMap().size() > 0); + } - /** - * testSupplementalClasses - */ - @Test - public void testSupplementalClasses() throws Exception { - // Check to make sure that we have something... - Map procs = this.benchmark.getProcedures(); - assertNotNull(procs); - } + /** testSupplementalClasses */ + @Test + public void testSupplementalClasses() throws Exception { + // Check to make sure that we have something... + Map procs = this.benchmark.getProcedures(); + assertNotNull(procs); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkLoader.java index 465b6e52e..aceddc52b 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkLoader.java @@ -27,7 +27,6 @@ import com.oltpbenchmark.benchmarks.auctionmark.util.ItemInfo; import com.oltpbenchmark.util.Histogram; import com.oltpbenchmark.util.RandomGenerator; - import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -36,78 +35,73 @@ public class TestAuctionMarkLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestAuctionMarkBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return AuctionMarkBenchmark.class; - } - - /** - * testSaveLoadProfile - */ - @Test - public void testSaveLoadProfile() throws Exception { - AuctionMarkProfile.clearCachedProfile(); - AuctionMarkLoader loader = (AuctionMarkLoader) super.testLoadWithReturn(); - - AuctionMarkProfile orig = loader.profile; - assertNotNull(orig); - assertFalse(orig.users_per_itemCount.isEmpty()); - - AuctionMarkProfile copy = new AuctionMarkProfile(this.benchmark, new RandomGenerator(0)); - assertTrue(copy.users_per_itemCount.isEmpty()); - - List> workers = this.benchmark.makeWorkers(); - AuctionMarkWorker worker = (AuctionMarkWorker) workers.get(0); - copy.loadProfile(worker); - - assertEquals(orig.scale_factor, copy.scale_factor, 0.001f); - assertEquals(orig.getLoaderStartTime().toString(), copy.getLoaderStartTime().toString()); - assertEquals(orig.getLoaderStopTime().toString(), copy.getLoaderStopTime().toString()); - assertEquals(orig.users_per_itemCount, copy.users_per_itemCount); - } - - /** - * testLoadProfilePerClient - */ - @Test - public void testLoadProfilePerClient() throws Exception { - // We don't have to reload our cached profile here - // We just want to make sure that each client's profile contains a unique - // set of ItemInfo records that are not found in any other profile's lists - int num_clients = 9; - this.workConf.setTerminals(num_clients); - AuctionMarkLoader loader = (AuctionMarkLoader) super.testLoadWithReturn(); - assertNotNull(loader); - - Set allItemInfos = new HashSet<>(); - Set clientItemInfos = new HashSet<>(); - Histogram clientItemCtr = new Histogram<>(); - List> workers = this.benchmark.makeWorkers(); - assertEquals(num_clients, workers.size()); - for (int i = 0; i < num_clients; i++) { - AuctionMarkWorker worker = (AuctionMarkWorker) workers.get(i); - assertNotNull(worker); - worker.initialize(); // Initializes the profile we need - - clientItemInfos.clear(); - for (LinkedList items : worker.profile.allItemSets) { - assertNotNull(items); - for (ItemInfo itemInfo : items) { - // Make sure we haven't seen it another list for this client - assertFalse(itemInfo.toString(), clientItemInfos.contains(itemInfo)); - // Nor that we have seen it in any other client - assertFalse(itemInfo.toString(), allItemInfos.contains(itemInfo)); - } // FOR - clientItemInfos.addAll(items); - } // FOR - clientItemCtr.put(i, clientItemInfos.size()); - allItemInfos.addAll(clientItemInfos); + @Override + public List> procedures() { + return TestAuctionMarkBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return AuctionMarkBenchmark.class; + } + + /** testSaveLoadProfile */ + @Test + public void testSaveLoadProfile() throws Exception { + AuctionMarkProfile.clearCachedProfile(); + AuctionMarkLoader loader = (AuctionMarkLoader) super.testLoadWithReturn(); + + AuctionMarkProfile orig = loader.profile; + assertNotNull(orig); + assertFalse(orig.users_per_itemCount.isEmpty()); + + AuctionMarkProfile copy = new AuctionMarkProfile(this.benchmark, new RandomGenerator(0)); + assertTrue(copy.users_per_itemCount.isEmpty()); + + List> workers = this.benchmark.makeWorkers(); + AuctionMarkWorker worker = (AuctionMarkWorker) workers.get(0); + copy.loadProfile(worker); + + assertEquals(orig.scale_factor, copy.scale_factor, 0.001f); + assertEquals(orig.getLoaderStartTime().toString(), copy.getLoaderStartTime().toString()); + assertEquals(orig.getLoaderStopTime().toString(), copy.getLoaderStopTime().toString()); + assertEquals(orig.users_per_itemCount, copy.users_per_itemCount); + } + + /** testLoadProfilePerClient */ + @Test + public void testLoadProfilePerClient() throws Exception { + // We don't have to reload our cached profile here + // We just want to make sure that each client's profile contains a unique + // set of ItemInfo records that are not found in any other profile's lists + int num_clients = 9; + this.workConf.setTerminals(num_clients); + AuctionMarkLoader loader = (AuctionMarkLoader) super.testLoadWithReturn(); + assertNotNull(loader); + + Set allItemInfos = new HashSet<>(); + Set clientItemInfos = new HashSet<>(); + Histogram clientItemCtr = new Histogram<>(); + List> workers = this.benchmark.makeWorkers(); + assertEquals(num_clients, workers.size()); + for (int i = 0; i < num_clients; i++) { + AuctionMarkWorker worker = (AuctionMarkWorker) workers.get(i); + assertNotNull(worker); + worker.initialize(); // Initializes the profile we need + + clientItemInfos.clear(); + for (LinkedList items : worker.profile.allItemSets) { + assertNotNull(items); + for (ItemInfo itemInfo : items) { + // Make sure we haven't seen it another list for this client + assertFalse(itemInfo.toString(), clientItemInfos.contains(itemInfo)); + // Nor that we have seen it in any other client + assertFalse(itemInfo.toString(), allItemInfos.contains(itemInfo)); } // FOR - } - + clientItemInfos.addAll(items); + } // FOR + clientItemCtr.put(i, clientItemInfos.size()); + allItemInfos.addAll(clientItemInfos); + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java index 1973d03ac..4ef2c7bfe 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/TestAuctionMarkWorker.java @@ -24,7 +24,6 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.auctionmark.util.UserId; - import java.io.IOException; import java.util.HashSet; import java.util.List; @@ -34,63 +33,60 @@ public class TestAuctionMarkWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestAuctionMarkBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return AuctionMarkBenchmark.class; - } + @Override + public List> procedures() { + return TestAuctionMarkBenchmark.PROCEDURE_CLASSES; + } - @Override - protected void postCreateDatabaseSetup() throws IOException { - super.postCreateDatabaseSetup(); - AuctionMarkProfile.clearCachedProfile(); - AuctionMarkConstants.CLOSE_AUCTIONS_ENABLE = false; - } + @Override + public Class benchmarkClass() { + return AuctionMarkBenchmark.class; + } - /** - * testUniqueSellers - */ - @Test - public void testUniqueSellers() throws Exception { + @Override + protected void postCreateDatabaseSetup() throws IOException { + super.postCreateDatabaseSetup(); + AuctionMarkProfile.clearCachedProfile(); + AuctionMarkConstants.CLOSE_AUCTIONS_ENABLE = false; + } - Set all_users = new HashSet(); - Set worker_users = new TreeSet(); - Integer last_num_users = null; - for (var w : this.workers) { - AuctionMarkWorker worker = (AuctionMarkWorker) w; - assertNotNull(w); + /** testUniqueSellers */ + @Test + public void testUniqueSellers() throws Exception { - // Get the uninitialized profile - AuctionMarkProfile profile = worker.getProfile(); - assertNotNull(profile); - assertTrue(profile.users_per_itemCount.isEmpty()); + Set all_users = new HashSet(); + Set worker_users = new TreeSet(); + Integer last_num_users = null; + for (var w : this.workers) { + AuctionMarkWorker worker = (AuctionMarkWorker) w; + assertNotNull(w); - // Then try to initialize it - profile.loadProfile(worker); - assertFalse(profile.users_per_itemCount.isEmpty()); - int num_users = profile.users_per_itemCount.getSampleCount(); - if (last_num_users != null) - assertEquals(last_num_users.intValue(), num_users); - else { - System.err.println("Number of Users: " + num_users); - } + // Get the uninitialized profile + AuctionMarkProfile profile = worker.getProfile(); + assertNotNull(profile); + assertTrue(profile.users_per_itemCount.isEmpty()); - worker_users.clear(); - for (int i = 0; i < num_users; i++) { - UserId user_id = profile.getRandomSellerId(worker.getId()); - assertNotNull(user_id); - assertFalse(worker.getId() + " -> " + user_id.toString() + " / " + user_id.encode(), - all_users.contains(user_id)); - worker_users.add(user_id); - } // FOR - assertFalse(worker_users.isEmpty()); - all_users.addAll(worker_users); - last_num_users = num_users; - } // FOR - } + // Then try to initialize it + profile.loadProfile(worker); + assertFalse(profile.users_per_itemCount.isEmpty()); + int num_users = profile.users_per_itemCount.getSampleCount(); + if (last_num_users != null) assertEquals(last_num_users.intValue(), num_users); + else { + System.err.println("Number of Users: " + num_users); + } + worker_users.clear(); + for (int i = 0; i < num_users; i++) { + UserId user_id = profile.getRandomSellerId(worker.getId()); + assertNotNull(user_id); + assertFalse( + worker.getId() + " -> " + user_id.toString() + " / " + user_id.encode(), + all_users.contains(user_id)); + worker_users.add(user_id); + } // FOR + assertFalse(worker_users.isEmpty()); + all_users.addAll(worker_users); + last_num_users = num_users; + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestItemId.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestItemId.java index 187f4b75b..6d760955b 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestItemId.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestItemId.java @@ -14,55 +14,48 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.auctionmark.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import org.junit.Test; - import java.util.Random; +import org.junit.Test; public class TestItemId { - private static final Random rand = new Random(1); - - - private final int num_items = 10; - private final int num_users = 3; - - /** - * testItemId - */ - @Test - public void testItemId() { - for (int i = 0; i < num_users; i++) { - UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); - for (int item_ctr = 0; item_ctr < num_items; item_ctr++) { - ItemId customer_id = new ItemId(user_id, item_ctr); - assertNotNull(customer_id); - assertEquals(user_id, customer_id.getSellerId()); - assertEquals(item_ctr, customer_id.getItemCtr()); - } // FOR - } // FOR - } - - /** - * testItemIdEncode - */ - @Test - public void testItemIdEncode() { - for (int i = 0; i < num_users; i++) { - UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); - for (int item_ctr = 0; item_ctr < num_items; item_ctr++) { - String encoded = new ItemId(user_id, item_ctr).encode(); - - ItemId customer_id = new ItemId(encoded); - assertNotNull(customer_id); - assertEquals(user_id, customer_id.getSellerId()); - assertEquals(item_ctr, customer_id.getItemCtr()); - } // FOR - } // FOR - } -} \ No newline at end of file + private static final Random rand = new Random(1); + + private final int num_items = 10; + private final int num_users = 3; + + /** testItemId */ + @Test + public void testItemId() { + for (int i = 0; i < num_users; i++) { + UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); + for (int item_ctr = 0; item_ctr < num_items; item_ctr++) { + ItemId customer_id = new ItemId(user_id, item_ctr); + assertNotNull(customer_id); + assertEquals(user_id, customer_id.getSellerId()); + assertEquals(item_ctr, customer_id.getItemCtr()); + } // FOR + } // FOR + } + + /** testItemIdEncode */ + @Test + public void testItemIdEncode() { + for (int i = 0; i < num_users; i++) { + UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); + for (int item_ctr = 0; item_ctr < num_items; item_ctr++) { + String encoded = new ItemId(user_id, item_ctr).encode(); + + ItemId customer_id = new ItemId(encoded); + assertNotNull(customer_id); + assertEquals(user_id, customer_id.getSellerId()); + assertEquals(item_ctr, customer_id.getItemCtr()); + } // FOR + } // FOR + } +} diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java index 8fb16662c..a801ed53e 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserId.java @@ -14,165 +14,152 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.auctionmark.util; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.oltpbenchmark.util.Histogram; -import org.junit.Test; - import java.util.*; +import org.junit.Test; public class TestUserId { - private static final Random rand = new Random(1); - - /** - * testUserId - */ - @Test - public void testUserId() { - for (int i = 0; i < 100; i++) { - int size = rand.nextInt(10000); - for (int offset = 0; offset < 10; offset++) { - UserId user_id = new UserId(size, offset); - assertNotNull(user_id); - assertEquals(size, user_id.getItemCount()); - assertEquals(offset, user_id.getOffset()); - } // FOR - } // FOR + private static final Random rand = new Random(1); + + /** testUserId */ + @Test + public void testUserId() { + for (int i = 0; i < 100; i++) { + int size = rand.nextInt(10000); + for (int offset = 0; offset < 10; offset++) { + UserId user_id = new UserId(size, offset); + assertNotNull(user_id); + assertEquals(size, user_id.getItemCount()); + assertEquals(offset, user_id.getOffset()); + } // FOR + } // FOR + } + + /** testEquals */ + // @Test + // public void testEquals() { + // UserId user_id = new UserId(rand.nextLong()); + // assert (user_id.getItemCount() > 0); + // assert (user_id.getOffset() > 0); + // + // UserId clone = new UserId(user_id.getItemCount(), user_id.getOffset()); + // assertEquals(user_id, clone); + // assertEquals(user_id.hashCode(), clone.hashCode()); + // assertEquals(0, user_id.compareTo(clone)); + // } + + /** testCompareTo */ + @Test + public void testCompareTo() throws Throwable { + Histogram h = new Histogram(); + List orig = new ArrayList(); + + Set seen_encode = new HashSet<>(); + Set seen_hash = new HashSet(); + Set seen_array = new HashSet<>(); + SortedMap seen_map = new TreeMap(); + + int num_ids = 100; + for (int i = 0; i < num_ids; i++) { + UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); + assert (user_id.getItemCount() > 0); + assert (user_id.getOffset() > 0); + if (orig.contains(user_id)) { + i--; + continue; + } + + // System.err.println(String.format("[%02d] %-50s => %d / %d %s%s%s%s", + // h.getValueCount(), user_id, user_id.hashCode(), user_id.encode(), + // (seen_hash.contains(user_id.hashCode()) ? "!!! HASH" : ""), + // (seen_encode.contains(user_id.encode()) ? "!!! ENCODE" : ""), + // (seen_array.contains(user_id.toArray()) ? "!!! ARRAY" : ""), + // (seen_map.containsKey(user_id) ? "!!! MAP" : "") + // )); + + h.put(user_id, i + 1); + assertTrue(user_id.toString(), h.contains(user_id)); + assertNotNull(user_id.toString(), h.get(user_id)); + assertEquals(user_id.toString(), i + 1, h.get(user_id).intValue()); + assertEquals(i + 1, h.getValueCount()); + + orig.add(user_id); + seen_hash.add(user_id.hashCode()); + seen_encode.add(user_id.encode()); + seen_array.add(user_id.toArray()); + seen_map.put(user_id, true); + } // FOR + assertEquals(num_ids, orig.size()); + assertEquals(num_ids, h.values().size()); + assertEquals(num_ids, h.getValueCount()); + assertEquals(num_ids, seen_hash.size()); + assertEquals(num_ids, seen_encode.size()); + + for (int i = 0; i < num_ids; i++) { + UserId user_id = orig.get(i); + assertTrue(user_id.toString(), seen_encode.contains(user_id.encode())); + assertTrue(user_id.toString(), seen_hash.contains(user_id.hashCode())); + assertTrue(user_id.toString(), seen_map.containsKey(user_id)); + assertNotNull(user_id.toString(), h.get(user_id)); + assertEquals(user_id.toString(), i + 1, h.get(user_id).intValue()); } - /** - * testEquals - */ -// @Test -// public void testEquals() { -// UserId user_id = new UserId(rand.nextLong()); -// assert (user_id.getItemCount() > 0); -// assert (user_id.getOffset() > 0); -// -// UserId clone = new UserId(user_id.getItemCount(), user_id.getOffset()); -// assertEquals(user_id, clone); -// assertEquals(user_id.hashCode(), clone.hashCode()); -// assertEquals(0, user_id.compareTo(clone)); -// } - - /** - * testCompareTo - */ - @Test - public void testCompareTo() throws Throwable { - Histogram h = new Histogram(); - List orig = new ArrayList(); - - Set seen_encode = new HashSet<>(); - Set seen_hash = new HashSet(); - Set seen_array = new HashSet<>(); - SortedMap seen_map = new TreeMap(); - - int num_ids = 100; - for (int i = 0; i < num_ids; i++) { - UserId user_id = new UserId(rand.nextInt(Integer.MAX_VALUE), rand.nextInt(Integer.MAX_VALUE)); - assert (user_id.getItemCount() > 0); - assert (user_id.getOffset() > 0); - if (orig.contains(user_id)) { - i--; - continue; - } - -// System.err.println(String.format("[%02d] %-50s => %d / %d %s%s%s%s", -// h.getValueCount(), user_id, user_id.hashCode(), user_id.encode(), -// (seen_hash.contains(user_id.hashCode()) ? "!!! HASH" : ""), -// (seen_encode.contains(user_id.encode()) ? "!!! ENCODE" : ""), -// (seen_array.contains(user_id.toArray()) ? "!!! ARRAY" : ""), -// (seen_map.containsKey(user_id) ? "!!! MAP" : "") -// )); - - h.put(user_id, i + 1); - assertTrue(user_id.toString(), h.contains(user_id)); - assertNotNull(user_id.toString(), h.get(user_id)); - assertEquals(user_id.toString(), i + 1, h.get(user_id).intValue()); - assertEquals(i + 1, h.getValueCount()); - - orig.add(user_id); - seen_hash.add(user_id.hashCode()); - seen_encode.add(user_id.encode()); - seen_array.add(user_id.toArray()); - seen_map.put(user_id, true); - } // FOR - assertEquals(num_ids, orig.size()); - assertEquals(num_ids, h.values().size()); - assertEquals(num_ids, h.getValueCount()); - assertEquals(num_ids, seen_hash.size()); - assertEquals(num_ids, seen_encode.size()); - - for (int i = 0; i < num_ids; i++) { - UserId user_id = orig.get(i); - assertTrue(user_id.toString(), seen_encode.contains(user_id.encode())); - assertTrue(user_id.toString(), seen_hash.contains(user_id.hashCode())); - assertTrue(user_id.toString(), seen_map.containsKey(user_id)); - assertNotNull(user_id.toString(), h.get(user_id)); - assertEquals(user_id.toString(), i + 1, h.get(user_id).intValue()); - } - - // Randomly delete a bunch and make sure that they're not in our histogram anymore - Set deleted = new HashSet(); - for (int i = 0; i < num_ids; i++) { - if (rand.nextBoolean()) { - UserId user_id = orig.get(i); - assertNotNull(user_id); - h.removeAll(user_id); - deleted.add(user_id); - } - } // FOR - assertFalse(deleted.isEmpty()); - assertEquals(orig.size() - deleted.size(), h.getValueCount()); - for (UserId user_id : orig) { - assertEquals(user_id.toString(), !deleted.contains(user_id), h.contains(user_id)); + // Randomly delete a bunch and make sure that they're not in our histogram anymore + Set deleted = new HashSet(); + for (int i = 0; i < num_ids; i++) { + if (rand.nextBoolean()) { + UserId user_id = orig.get(i); + assertNotNull(user_id); + h.removeAll(user_id); + deleted.add(user_id); + } + } // FOR + assertFalse(deleted.isEmpty()); + assertEquals(orig.size() - deleted.size(), h.getValueCount()); + for (UserId user_id : orig) { + assertEquals(user_id.toString(), !deleted.contains(user_id), h.contains(user_id)); + } // FOR + } + + /** testUserIdEncode */ + @Test + public void testUserIdEncode() { + for (int i = 0; i < 100; i++) { + int size = rand.nextInt(10000); + for (int offset = 0; offset < 10; offset++) { + String encoded = new UserId(size, offset).encode(); + + UserId user_id = new UserId(encoded); + assertNotNull(user_id); + assertEquals(size, user_id.getItemCount()); + assertEquals(offset, user_id.getOffset()); + } // FOR + } // FOR + } + + /** testUserIdDecode */ + @Test + public void testUserIdDecode() { + for (int i = 0; i < 100; i++) { + int size = rand.nextInt(10000); + for (int offset = 0; offset < 10; offset++) { + String[] values = {Integer.toString(size), Integer.toString(offset)}; + String encoded = new UserId(size, offset).encode(); + + String[] new_values = new UserId(encoded).toArray(); + assertEquals(values.length, new_values.length); + for (int j = 0; j < new_values.length; j++) { + assertEquals(values[j], new_values[j]); } // FOR - - } - - /** - * testUserIdEncode - */ - @Test - public void testUserIdEncode() { - for (int i = 0; i < 100; i++) { - int size = rand.nextInt(10000); - for (int offset = 0; offset < 10; offset++) { - String encoded = new UserId(size, offset).encode(); - - UserId user_id = new UserId(encoded); - assertNotNull(user_id); - assertEquals(size, user_id.getItemCount()); - assertEquals(offset, user_id.getOffset()); - } // FOR - } // FOR - } - - /** - * testUserIdDecode - */ - @Test - public void testUserIdDecode() { - for (int i = 0; i < 100; i++) { - int size = rand.nextInt(10000); - for (int offset = 0; offset < 10; offset++) { - String[] values = {Integer.toString(size), Integer.toString(offset)}; - String encoded = new UserId(size, offset).encode(); - - String[] new_values = new UserId(encoded).toArray(); - assertEquals(values.length, new_values.length); - for (int j = 0; j < new_values.length; j++) { - assertEquals(values[j], new_values[j]); - } // FOR - } // FOR - } // FOR - } -} \ No newline at end of file + } // FOR + } // FOR + } +} diff --git a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserIdGenerator.java b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserIdGenerator.java index 100543341..00fd49dc3 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserIdGenerator.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/auctionmark/util/TestUserIdGenerator.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.auctionmark.util; import static org.junit.Assert.assertEquals; @@ -23,6 +22,11 @@ import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; +import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; +import com.oltpbenchmark.util.CollectionUtil; +import com.oltpbenchmark.util.Histogram; +import com.oltpbenchmark.util.RandomDistribution.Zipf; +import com.oltpbenchmark.util.RandomGenerator; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -30,258 +34,239 @@ import java.util.Random; import java.util.Set; import java.util.TreeMap; - import org.junit.Before; import org.junit.Test; -import com.oltpbenchmark.benchmarks.auctionmark.AuctionMarkConstants; -import com.oltpbenchmark.util.CollectionUtil; -import com.oltpbenchmark.util.Histogram; -import com.oltpbenchmark.util.RandomDistribution.Zipf; -import com.oltpbenchmark.util.RandomGenerator; - /** * @author pavlo */ public class TestUserIdGenerator { - private static final int NUM_CLIENTS = 10; - private static final int NUM_USERS = 1000; - private static final RandomGenerator rand = new RandomGenerator(0); // (int)System.currentTimeMillis()); - - private static final Zipf randomNumItems = new Zipf(rand, - AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MIN, - AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MAX, - 1.0001); - - private final Histogram users_per_item_count = new Histogram(); - - - @Before - public void setUp() throws Exception { - for (long i = 0; i < NUM_USERS; i++) { - this.users_per_item_count.put((long) randomNumItems.nextInt()); - } // FOR - assertEquals(NUM_USERS, this.users_per_item_count.getSampleCount()); - } - - /** - * testCheckClient - */ - @Test - public void testCheckClient() throws Exception { - int num_clients = 10; - UserIdGenerator generator; - - // Create a mapping from each Client Id -> UserIds - Map> clientIds = new HashMap<>(); - Map clientGenerators = new HashMap<>(); - for (int client = 0; client < num_clients; client++) { - generator = new UserIdGenerator(users_per_item_count, num_clients, client); - Collection users = CollectionUtil.addAll(new HashSet<>(), CollectionUtil.iterable(generator).iterator()); - assertFalse(users.isEmpty()); - clientIds.put(client, users); - clientGenerators.put(client, generator); - } // FOR - - // Then loop back through all of the User Ids and make sure that each UserId - // is mappable to the expected client - generator = new UserIdGenerator(users_per_item_count, num_clients); - int ctr = 0; - for (UserId user_id : CollectionUtil.iterable(generator)) { - assertNotNull(user_id); - boolean found = false; - for (int client = 0; client < num_clients; client++) { - boolean expected = clientIds.get(client).contains(user_id); - if (expected) assertFalse(found); - boolean actual = clientGenerators.get(client).checkClient(user_id); - assertEquals(String.format("[%03d] %d / %s", ctr, client, user_id), expected, actual); - found = (found || expected); - ctr++; - } // FOR - assertTrue(user_id.toString(), found); - } // FOR - } - - /** - * testSeekToPosition - */ - @Test - public void testSeekToPosition() throws Exception { - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, 1); - final int num_users = (int) (generator.getTotalUsers() - 1); - - int itemCount = rand.nextInt(users_per_item_count.getMaxValue().intValue() - 1); - generator.setCurrentItemCount(itemCount); -// System.err.println("itemCount = " + itemCount); - - int cur_position = generator.getCurrentPosition(); - int new_position = rand.number(cur_position, num_users); -// System.err.println(users_per_item_count); -// System.err.println("cur_position = " + cur_position); -// System.err.println("new_position = " + new_position); - generator.setCurrentItemCount(0); - UserId expected = null; - for (int i = 0; i <= new_position; i++) { - assertTrue(generator.hasNext()); - expected = generator.next(); - assertNotNull(expected); - } // FOR - - generator.setCurrentItemCount(0); - UserId user_id = generator.seekToPosition(new_position); - assertNotNull(user_id); -// System.err.println(user_id); - assertEquals(expected, user_id); - } - - /** - * testSeekToPositionSameUserId - */ - @Test - public void testSeekToPositionClientId() throws Exception { - int num_clients = 10; - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, num_clients); - final int num_users = (int) (generator.getTotalUsers() - 1); - - Map expectedIds = new TreeMap(); - while (generator.hasNext()) { - int position = generator.getCurrentPosition(); - UserId user_id = generator.next(); - assertNotNull(user_id); - expectedIds.put(position, user_id); - } // WHILE -// System.err.println(StringUtil.formatMaps(expectedIds)); - - for (int client = 0; client < num_clients; client++) { - generator = new UserIdGenerator(users_per_item_count, num_clients, client); - - // Randomly jump around and make sure that we get the same UserId per position - for (int i = 0; i < NUM_USERS; i++) { - // This could be null because there were no more UserIds for this - // client beyond the given position - int position = rand.nextInt(num_users); - UserId user_id = generator.seekToPosition(position); - if (user_id == null) continue; - - // We have to go back and get our position since we used a client id, - // which means that the generator could skip ahead even more - position = generator.getCurrentPosition(); - UserId expected = expectedIds.get(position); - assertNotNull(expected); - - assertEquals("Position: " + position, expected, user_id); - } // FOR - } // FOR - - } - - /** - * testAllUsers - */ - @Test - public void testAllUsers() throws Exception { - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS); - Set seen = new HashSet(); - assert (generator.hasNext()); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (seen.contains(u_id) == false) : "Duplicate " + u_id; - seen.add(u_id); -// System.err.println(u_id); - } // FOR - assertEquals(NUM_USERS, seen.size()); - } - - /** - * testPerClient - */ - @Test - public void testPerClient() throws Exception { - Histogram clients_h = new Histogram(); - Set all_seen = new HashSet(); - for (int client = 0; client < NUM_CLIENTS; client++) { - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS, client); - Set seen = new HashSet(); - assert (generator.hasNext()); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (seen.contains(u_id) == false) : "Duplicate " + u_id; - assert (all_seen.contains(u_id) == false) : "Duplicate " + u_id; - seen.add(u_id); - all_seen.add(u_id); - } // FOR - assertNotSame(Integer.toString(client), NUM_USERS, seen.size()); - assertFalse(Integer.toString(client), seen.isEmpty()); - clients_h.put(client, seen.size()); - } // FOR - assertEquals(NUM_USERS, all_seen.size()); - - // Make sure that they all have the same number of UserIds - Integer last_cnt = null; - for (Integer client : clients_h.values()) { - if (last_cnt != null) { - assertEquals(client.toString(), last_cnt, clients_h.get(client)); - } - last_cnt = clients_h.get(client); - } // FOR -// System.err.println(clients_h); - } - - /** - * testSingleClient - */ - @Test - public void testSingleClient() throws Exception { - // First create a UserIdGenerator for all clients and get - // the set of all the UserIds that we expect - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, 1); - Set expected = new HashSet(); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (expected.contains(u_id) == false) : "Duplicate " + u_id; - expected.add(u_id); - } // FOR - - // Now create a new generator that only has one client. That means that we should - // get back all the same UserIds - Set actual = new HashSet(); - generator = new UserIdGenerator(users_per_item_count, 1, 0); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (actual.contains(u_id) == false) : "Duplicate " + u_id; - assert (expected.contains(u_id)) : "Unexpected " + u_id; - actual.add(u_id); - } // FOR - assertEquals(expected.size(), actual.size()); - } - - /** - * testSetCurrentSize - */ - @Test - public void testSetCurrentSize() throws Exception { - // First create a UserIdGenerator for a random ClientId and populate - // the set of all the UserIds that we expect for this client - Random rand = new Random(); - int client = rand.nextInt(NUM_CLIENTS); - UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS, client); - Set seen = new HashSet(); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (seen.contains(u_id) == false) : "Duplicate " + u_id; - seen.add(u_id); - } // FOR - - // Now make sure that we always get back the same UserIds regardless of where - // we jump around with using setCurrentSize() - for (int i = 0; i < 10; i++) { - int size = rand.nextInt((int) (users_per_item_count.getMaxValue() + 1)); - generator.setCurrentItemCount(size); - for (UserId u_id : CollectionUtil.iterable(generator)) { - assertNotNull(u_id); - assert (seen.contains(u_id)) : "Unexpected " + u_id; - } // FOR - } // FOR - } + private static final int NUM_CLIENTS = 10; + private static final int NUM_USERS = 1000; + private static final RandomGenerator rand = + new RandomGenerator(0); // (int)System.currentTimeMillis()); + + private static final Zipf randomNumItems = + new Zipf( + rand, + AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MIN, + AuctionMarkConstants.ITEM_ITEMS_PER_SELLER_MAX, + 1.0001); + + private final Histogram users_per_item_count = new Histogram(); + + @Before + public void setUp() throws Exception { + for (long i = 0; i < NUM_USERS; i++) { + this.users_per_item_count.put((long) randomNumItems.nextInt()); + } // FOR + assertEquals(NUM_USERS, this.users_per_item_count.getSampleCount()); + } + + /** testCheckClient */ + @Test + public void testCheckClient() throws Exception { + int num_clients = 10; + UserIdGenerator generator; + + // Create a mapping from each Client Id -> UserIds + Map> clientIds = new HashMap<>(); + Map clientGenerators = new HashMap<>(); + for (int client = 0; client < num_clients; client++) { + generator = new UserIdGenerator(users_per_item_count, num_clients, client); + Collection users = + CollectionUtil.addAll(new HashSet<>(), CollectionUtil.iterable(generator).iterator()); + assertFalse(users.isEmpty()); + clientIds.put(client, users); + clientGenerators.put(client, generator); + } // FOR + + // Then loop back through all of the User Ids and make sure that each UserId + // is mappable to the expected client + generator = new UserIdGenerator(users_per_item_count, num_clients); + int ctr = 0; + for (UserId user_id : CollectionUtil.iterable(generator)) { + assertNotNull(user_id); + boolean found = false; + for (int client = 0; client < num_clients; client++) { + boolean expected = clientIds.get(client).contains(user_id); + if (expected) assertFalse(found); + boolean actual = clientGenerators.get(client).checkClient(user_id); + assertEquals(String.format("[%03d] %d / %s", ctr, client, user_id), expected, actual); + found = (found || expected); + ctr++; + } // FOR + assertTrue(user_id.toString(), found); + } // FOR + } + + /** testSeekToPosition */ + @Test + public void testSeekToPosition() throws Exception { + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, 1); + final int num_users = (int) (generator.getTotalUsers() - 1); + + int itemCount = rand.nextInt(users_per_item_count.getMaxValue().intValue() - 1); + generator.setCurrentItemCount(itemCount); + // System.err.println("itemCount = " + itemCount); + + int cur_position = generator.getCurrentPosition(); + int new_position = rand.number(cur_position, num_users); + // System.err.println(users_per_item_count); + // System.err.println("cur_position = " + cur_position); + // System.err.println("new_position = " + new_position); + generator.setCurrentItemCount(0); + UserId expected = null; + for (int i = 0; i <= new_position; i++) { + assertTrue(generator.hasNext()); + expected = generator.next(); + assertNotNull(expected); + } // FOR + + generator.setCurrentItemCount(0); + UserId user_id = generator.seekToPosition(new_position); + assertNotNull(user_id); + // System.err.println(user_id); + assertEquals(expected, user_id); + } + + /** testSeekToPositionSameUserId */ + @Test + public void testSeekToPositionClientId() throws Exception { + int num_clients = 10; + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, num_clients); + final int num_users = (int) (generator.getTotalUsers() - 1); + + Map expectedIds = new TreeMap(); + while (generator.hasNext()) { + int position = generator.getCurrentPosition(); + UserId user_id = generator.next(); + assertNotNull(user_id); + expectedIds.put(position, user_id); + } // WHILE + // System.err.println(StringUtil.formatMaps(expectedIds)); + + for (int client = 0; client < num_clients; client++) { + generator = new UserIdGenerator(users_per_item_count, num_clients, client); + + // Randomly jump around and make sure that we get the same UserId per position + for (int i = 0; i < NUM_USERS; i++) { + // This could be null because there were no more UserIds for this + // client beyond the given position + int position = rand.nextInt(num_users); + UserId user_id = generator.seekToPosition(position); + if (user_id == null) continue; + + // We have to go back and get our position since we used a client id, + // which means that the generator could skip ahead even more + position = generator.getCurrentPosition(); + UserId expected = expectedIds.get(position); + assertNotNull(expected); + + assertEquals("Position: " + position, expected, user_id); + } // FOR + } // FOR + } + + /** testAllUsers */ + @Test + public void testAllUsers() throws Exception { + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS); + Set seen = new HashSet(); + assert (generator.hasNext()); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (seen.contains(u_id) == false) : "Duplicate " + u_id; + seen.add(u_id); + // System.err.println(u_id); + } // FOR + assertEquals(NUM_USERS, seen.size()); + } + + /** testPerClient */ + @Test + public void testPerClient() throws Exception { + Histogram clients_h = new Histogram(); + Set all_seen = new HashSet(); + for (int client = 0; client < NUM_CLIENTS; client++) { + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS, client); + Set seen = new HashSet(); + assert (generator.hasNext()); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (seen.contains(u_id) == false) : "Duplicate " + u_id; + assert (all_seen.contains(u_id) == false) : "Duplicate " + u_id; + seen.add(u_id); + all_seen.add(u_id); + } // FOR + assertNotSame(Integer.toString(client), NUM_USERS, seen.size()); + assertFalse(Integer.toString(client), seen.isEmpty()); + clients_h.put(client, seen.size()); + } // FOR + assertEquals(NUM_USERS, all_seen.size()); + + // Make sure that they all have the same number of UserIds + Integer last_cnt = null; + for (Integer client : clients_h.values()) { + if (last_cnt != null) { + assertEquals(client.toString(), last_cnt, clients_h.get(client)); + } + last_cnt = clients_h.get(client); + } // FOR + // System.err.println(clients_h); + } + + /** testSingleClient */ + @Test + public void testSingleClient() throws Exception { + // First create a UserIdGenerator for all clients and get + // the set of all the UserIds that we expect + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, 1); + Set expected = new HashSet(); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (expected.contains(u_id) == false) : "Duplicate " + u_id; + expected.add(u_id); + } // FOR + + // Now create a new generator that only has one client. That means that we should + // get back all the same UserIds + Set actual = new HashSet(); + generator = new UserIdGenerator(users_per_item_count, 1, 0); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (actual.contains(u_id) == false) : "Duplicate " + u_id; + assert (expected.contains(u_id)) : "Unexpected " + u_id; + actual.add(u_id); + } // FOR + assertEquals(expected.size(), actual.size()); + } + + /** testSetCurrentSize */ + @Test + public void testSetCurrentSize() throws Exception { + // First create a UserIdGenerator for a random ClientId and populate + // the set of all the UserIds that we expect for this client + Random rand = new Random(); + int client = rand.nextInt(NUM_CLIENTS); + UserIdGenerator generator = new UserIdGenerator(users_per_item_count, NUM_CLIENTS, client); + Set seen = new HashSet(); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (seen.contains(u_id) == false) : "Duplicate " + u_id; + seen.add(u_id); + } // FOR + + // Now make sure that we always get back the same UserIds regardless of where + // we jump around with using setCurrentSize() + for (int i = 0; i < 10; i++) { + int size = rand.nextInt((int) (users_per_item_count.getMaxValue() + 1)); + generator.setCurrentItemCount(size); + for (UserId u_id : CollectionUtil.iterable(generator)) { + assertNotNull(u_id); + assert (seen.contains(u_id)) : "Unexpected " + u_id; + } // FOR + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmark.java b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmark.java index 07f95a71f..c22bd77c8 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmark.java @@ -19,45 +19,25 @@ import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.chbenchmark.queries.*; -import org.junit.Ignore; - import java.util.List; +import org.junit.Ignore; @Ignore("the testcase is under development") public class TestCHBenCHmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - Q1.class, - Q2.class, - Q3.class, - Q4.class, - Q5.class, - Q6.class, - Q7.class, - Q8.class, - Q9.class, - Q10.class, - Q11.class, - Q12.class, - Q13.class, - Q14.class, - Q15.class, - Q16.class, - Q17.class, - Q18.class, - Q19.class, - Q20.class, - Q21.class, - Q22.class); - - @Override - public List> procedures() { - return TestCHBenCHmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return CHBenCHmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + Q1.class, Q2.class, Q3.class, Q4.class, Q5.class, Q6.class, Q7.class, Q8.class, Q9.class, + Q10.class, Q11.class, Q12.class, Q13.class, Q14.class, Q15.class, Q16.class, Q17.class, + Q18.class, Q19.class, Q20.class, Q21.class, Q22.class); + + @Override + public List> procedures() { + return TestCHBenCHmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return CHBenCHmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkLoader.java index 0f8b4292d..feda80217 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkLoader.java @@ -18,21 +18,19 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; -import org.junit.Ignore; - import java.util.List; +import org.junit.Ignore; @Ignore("the testcase is under development") public class TestCHBenCHmarkLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestCHBenCHmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return CHBenCHmark.class; - } + @Override + public List> procedures() { + return TestCHBenCHmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return CHBenCHmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkWorker.java index 5f31db53b..dad9fdc6e 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/chbenchmark/TestCHBenCHmarkWorker.java @@ -18,21 +18,19 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; -import org.junit.Ignore; - import java.util.List; +import org.junit.Ignore; @Ignore("the testcase is under development") public class TestCHBenCHmarkWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestCHBenCHmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return CHBenCHmark.class; - } + @Override + public List> procedures() { + return TestCHBenCHmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return CHBenCHmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsBenchmark.java index 97c9a15c7..5f14462e9 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsBenchmark.java @@ -14,36 +14,33 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.epinions; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.epinions.procedures.*; - import java.util.List; public class TestEpinionsBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - GetAverageRatingByTrustedUser.class, - GetItemAverageRating.class, - GetItemReviewsByTrustedUser.class, - GetReviewItemById.class, - GetReviewsByUser.class, - UpdateItemTitle.class, - UpdateTrustRating.class, - UpdateUserName.class - ); - - @Override - public List> procedures() { - return TestEpinionsBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return EpinionsBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + GetAverageRatingByTrustedUser.class, + GetItemAverageRating.class, + GetItemReviewsByTrustedUser.class, + GetReviewItemById.class, + GetReviewsByUser.class, + UpdateItemTitle.class, + UpdateTrustRating.class, + UpdateUserName.class); + + @Override + public List> procedures() { + return TestEpinionsBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return EpinionsBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsLoader.java index bad459e6d..5e591daa0 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsLoader.java @@ -14,28 +14,26 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.epinions; import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestEpinionsLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestEpinionsBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestEpinionsBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return EpinionsBenchmark.class; - } + @Override + public Class benchmarkClass() { + return EpinionsBenchmark.class; + } - @Override - public List ignorableTables() { - return List.of("review_rating"); - } + @Override + public List ignorableTables() { + return List.of("review_rating"); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsWorker.java index 874fa72a3..d414addf3 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/epinions/TestEpinionsWorker.java @@ -14,24 +14,21 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.epinions; import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestEpinionsWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestEpinionsBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return EpinionsBenchmark.class; - } + @Override + public List> procedures() { + return TestEpinionsBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return EpinionsBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpBenchmark.java index e29d5a01b..f0b49b8f9 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpBenchmark.java @@ -19,23 +19,19 @@ import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.noop.procedures.NoOp; - import java.util.List; public class TestNoOpBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - NoOp.class - ); - - @Override - public List> procedures() { - return TestNoOpBenchmark.PROCEDURE_CLASSES; - } + public static final List> PROCEDURE_CLASSES = List.of(NoOp.class); - @Override - public Class benchmarkClass() { - return NoOpBenchmark.class; - } + @Override + public List> procedures() { + return TestNoOpBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return NoOpBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpLoader.java index dbb7d7792..cd2d07cbb 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpLoader.java @@ -18,23 +18,22 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestNoOpLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestNoOpBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestNoOpBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return NoOpBenchmark.class; - } + @Override + public Class benchmarkClass() { + return NoOpBenchmark.class; + } - @Override - public List ignorableTables() { - return List.of("FAKE"); - } + @Override + public List ignorableTables() { + return List.of("FAKE"); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpWorker.java index a575b3315..234cb887e 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/noop/TestNoOpWorker.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestNoOpWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestNoOpBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return NoOpBenchmark.class; - } + @Override + public List> procedures() { + return TestNoOpBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return NoOpBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsBenchmark.java index ecd770483..a8d41a093 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsBenchmark.java @@ -20,23 +20,20 @@ import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.otmetrics.procedures.GetSessionRange; - import java.util.List; public class TestOTMetricsBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - GetSessionRange.class - ); - - @Override - public List> procedures() { - return TestOTMetricsBenchmark.PROCEDURE_CLASSES; - } + public static final List> PROCEDURE_CLASSES = + List.of(GetSessionRange.class); - @Override - public Class benchmarkClass() { - return OTMetricsBenchmark.class; - } + @Override + public List> procedures() { + return TestOTMetricsBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return OTMetricsBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsLoader.java index dacfcd883..8abc42c2e 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsLoader.java @@ -18,27 +18,24 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestOTMetricsLoader extends AbstractTestLoader { - private static final String[] IGNORE = { - - }; + private static final String[] IGNORE = {}; - @Override - public List> procedures() { - return TestOTMetricsBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestOTMetricsBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return OTMetricsBenchmark.class; - } + @Override + public Class benchmarkClass() { + return OTMetricsBenchmark.class; + } - @Override - public List ignorableTables() { - return List.of(IGNORE); - } + @Override + public List ignorableTables() { + return List.of(IGNORE); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsWorker.java index de3f4d48f..8547e60f9 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/otmetrics/TestOTMetricsWorker.java @@ -2,18 +2,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestOTMetricsWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestOTMetricsBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestOTMetricsBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return OTMetricsBenchmark.class; - } + @Override + public Class benchmarkClass() { + return OTMetricsBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserBenchmark.java index 35569f88a..3a5c061fc 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserBenchmark.java @@ -14,34 +14,26 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.resourcestresser; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.resourcestresser.procedures.*; - import java.util.List; -public class TestResourceStresserBenchmark extends AbstractTestBenchmarkModule { - - public static final List> PROCEDURE_CLASSES = List.of( - Contention1.class, - Contention2.class, - CPU1.class, - CPU2.class, - IO1.class, - IO2.class - ); +public class TestResourceStresserBenchmark + extends AbstractTestBenchmarkModule { - @Override - public List> procedures() { - return TestResourceStresserBenchmark.PROCEDURE_CLASSES; - } + public static final List> PROCEDURE_CLASSES = + List.of(Contention1.class, Contention2.class, CPU1.class, CPU2.class, IO1.class, IO2.class); - @Override - public Class benchmarkClass() { - return ResourceStresserBenchmark.class; - } + @Override + public List> procedures() { + return TestResourceStresserBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return ResourceStresserBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserLoader.java index 1c23bebf3..1cd7029dd 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserLoader.java @@ -2,18 +2,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestResourceStresserLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestResourceStresserBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestResourceStresserBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return ResourceStresserBenchmark.class; - } + @Override + public Class benchmarkClass() { + return ResourceStresserBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserWorker.java index fda5526e9..791a01f83 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/resourcestresser/TestResourceStresserWorker.java @@ -2,18 +2,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestResourceStresserWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestResourceStresserBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestResourceStresserBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return ResourceStresserBenchmark.class; - } + @Override + public Class benchmarkClass() { + return ResourceStresserBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSBenchmark.java index 68b3f9a19..d91d8a041 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSBenchmark.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.seats; import static org.junit.Assert.assertNotNull; @@ -23,44 +22,40 @@ import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.seats.procedures.*; import com.oltpbenchmark.catalog.Table; - import java.io.InputStream; import java.util.List; import org.junit.Test; public class TestSEATSBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - DeleteReservation.class, - FindFlights.class, - FindOpenSeats.class, - NewReservation.class, - UpdateCustomer.class, - UpdateReservation.class - ); - - @Override - public List> procedures() { - return TestSEATSBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return SEATSBenchmark.class; - } - - - /** - * testGetDataDir - */ - @Test - public void testGetDataDir() throws Exception { - // Test by reading the country table. - Table countryTable = this.benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_COUNTRY); - String countryFilePath = SEATSBenchmark.getTableDataFilePath(this.benchmark.getDataDir(), countryTable); - assertNotNull(countryFilePath); - InputStream countryFile = this.getClass().getResourceAsStream(countryFilePath); - assertNotNull(countryFile); - } - + public static final List> PROCEDURE_CLASSES = + List.of( + DeleteReservation.class, + FindFlights.class, + FindOpenSeats.class, + NewReservation.class, + UpdateCustomer.class, + UpdateReservation.class); + + @Override + public List> procedures() { + return TestSEATSBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return SEATSBenchmark.class; + } + + /** testGetDataDir */ + @Test + public void testGetDataDir() throws Exception { + // Test by reading the country table. + Table countryTable = this.benchmark.getCatalog().getTable(SEATSConstants.TABLENAME_COUNTRY); + String countryFilePath = + SEATSBenchmark.getTableDataFilePath(this.benchmark.getDataDir(), countryTable); + assertNotNull(countryFilePath); + InputStream countryFile = this.getClass().getResourceAsStream(countryFilePath); + assertNotNull(countryFile); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSLoader.java index 57c8688ba..69957893d 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSLoader.java @@ -23,65 +23,62 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.api.Worker; - import java.io.IOException; import java.util.List; import org.junit.Test; public class TestSEATSLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestSEATSBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return SEATSBenchmark.class; - } + @Override + public List> procedures() { + return TestSEATSBenchmark.PROCEDURE_CLASSES; + } - @Override - protected void postCreateDatabaseSetup() throws IOException { - super.postCreateDatabaseSetup(); - SEATSProfile.clearCachedProfile(); - } + @Override + public Class benchmarkClass() { + return SEATSBenchmark.class; + } - /** - * testSaveLoadProfile - */ - @Test - public void testSaveLoadProfile() throws Exception { - this.benchmark.createDatabase(); - SEATSLoader loader = (SEATSLoader) this.benchmark.loadDatabase(); - assertNotNull(loader); + @Override + protected void postCreateDatabaseSetup() throws IOException { + super.postCreateDatabaseSetup(); + SEATSProfile.clearCachedProfile(); + } - SEATSProfile orig = loader.profile; - assertNotNull(orig); + /** testSaveLoadProfile */ + @Test + public void testSaveLoadProfile() throws Exception { + this.benchmark.createDatabase(); + SEATSLoader loader = (SEATSLoader) this.benchmark.loadDatabase(); + assertNotNull(loader); - // Make sure there is something in our profile after loading the database - assertFalse("Empty Profile: airport_max_customer_id", orig.airport_max_customer_id.isEmpty()); + SEATSProfile orig = loader.profile; + assertNotNull(orig); - SEATSProfile copy = new SEATSProfile(this.benchmark, benchmark.getRandomGenerator()); - assert (copy.airport_histograms.isEmpty()); + // Make sure there is something in our profile after loading the database + assertFalse("Empty Profile: airport_max_customer_id", orig.airport_max_customer_id.isEmpty()); - List> workers = this.benchmark.makeWorkers(); - SEATSWorker worker = (SEATSWorker) workers.get(0); - copy.loadProfile(worker); + SEATSProfile copy = new SEATSProfile(this.benchmark, benchmark.getRandomGenerator()); + assert (copy.airport_histograms.isEmpty()); - assertEquals(orig.scale_factor, copy.scale_factor, 0.001f); - assertEquals(orig.airport_max_customer_id, copy.airport_max_customer_id); - assertEquals(orig.flight_start_date.toString(), copy.flight_start_date.toString()); - assertEquals(orig.flight_upcoming_date.toString(), copy.flight_upcoming_date.toString()); - assertEquals(orig.flight_past_days, copy.flight_past_days); - assertEquals(orig.flight_future_days, copy.flight_future_days); - assertEquals(orig.flight_upcoming_offset, copy.flight_upcoming_offset); - assertEquals(orig.reservation_upcoming_offset, copy.reservation_upcoming_offset); - assertEquals(orig.num_reservations, copy.num_reservations); - assertEquals(orig.histograms, copy.histograms); - assertEquals(orig.airport_histograms, copy.airport_histograms); - // TODO(WAN): This was commented out before and so it is still commented out now, but we should probably dig - // into why it is not the same. - // assertEquals(orig.code_id_xref, copy.code_id_xref); - } + List> workers = this.benchmark.makeWorkers(); + SEATSWorker worker = (SEATSWorker) workers.get(0); + copy.loadProfile(worker); + assertEquals(orig.scale_factor, copy.scale_factor, 0.001f); + assertEquals(orig.airport_max_customer_id, copy.airport_max_customer_id); + assertEquals(orig.flight_start_date.toString(), copy.flight_start_date.toString()); + assertEquals(orig.flight_upcoming_date.toString(), copy.flight_upcoming_date.toString()); + assertEquals(orig.flight_past_days, copy.flight_past_days); + assertEquals(orig.flight_future_days, copy.flight_future_days); + assertEquals(orig.flight_upcoming_offset, copy.flight_upcoming_offset); + assertEquals(orig.reservation_upcoming_offset, copy.reservation_upcoming_offset); + assertEquals(orig.num_reservations, copy.num_reservations); + assertEquals(orig.histograms, copy.histograms); + assertEquals(orig.airport_histograms, copy.airport_histograms); + // TODO(WAN): This was commented out before and so it is still commented out now, but we should + // probably dig + // into why it is not the same. + // assertEquals(orig.code_id_xref, copy.code_id_xref); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSWorker.java index ce68f3efa..38923ae6b 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/TestSEATSWorker.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestSEATSWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestSEATSBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return SEATSBenchmark.class; - } + @Override + public List> procedures() { + return TestSEATSBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return SEATSBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerId.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerId.java index 23f6db619..4c5de02e3 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerId.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerId.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.seats.util; import static org.junit.Assert.assertEquals; @@ -24,61 +23,55 @@ public class TestCustomerId { - private final long[] base_ids = {66666, 77777, 88888}; - private final long[] airport_ids = {123, 1234, 12345}; + private final long[] base_ids = {66666, 77777, 88888}; + private final long[] airport_ids = {123, 1234, 12345}; - /** - * testCustomerId - */ - @Test - public void testCustomerId() { - for (long base_id : this.base_ids) { - for (long airport_id : this.airport_ids) { - CustomerId customer_id = new CustomerId((int) base_id, airport_id); - assertNotNull(customer_id); - assertEquals(base_id, customer_id.getId()); - assertEquals(airport_id, customer_id.getDepartAirportId()); - } // FOR - } // FOR - } + /** testCustomerId */ + @Test + public void testCustomerId() { + for (long base_id : this.base_ids) { + for (long airport_id : this.airport_ids) { + CustomerId customer_id = new CustomerId((int) base_id, airport_id); + assertNotNull(customer_id); + assertEquals(base_id, customer_id.getId()); + assertEquals(airport_id, customer_id.getDepartAirportId()); + } // FOR + } // FOR + } - /** - * testCustomerIdEncode - */ - @Test - public void testCustomerIdEncode() { - for (long base_id : this.base_ids) { - for (long airport_id : this.airport_ids) { - String encoded = new CustomerId((int) base_id, airport_id).encode(); -// System.err.println("base_id=" + base_id); -// System.err.println("airport_id=" + airport_id); -// System.err.println("encodd=" + encoded); -// System.exit(1); + /** testCustomerIdEncode */ + @Test + public void testCustomerIdEncode() { + for (long base_id : this.base_ids) { + for (long airport_id : this.airport_ids) { + String encoded = new CustomerId((int) base_id, airport_id).encode(); + // System.err.println("base_id=" + base_id); + // System.err.println("airport_id=" + airport_id); + // System.err.println("encodd=" + encoded); + // System.exit(1); - CustomerId customer_id = new CustomerId(encoded); - assertNotNull(customer_id); - assertEquals(base_id, customer_id.getId()); - assertEquals(airport_id, customer_id.getDepartAirportId()); - } // FOR - } // FOR - } + CustomerId customer_id = new CustomerId(encoded); + assertNotNull(customer_id); + assertEquals(base_id, customer_id.getId()); + assertEquals(airport_id, customer_id.getDepartAirportId()); + } // FOR + } // FOR + } - /** - * testCustomerIdDecode - */ - @Test - public void testCustomerIdDecode() { - for (long base_id : this.base_ids) { - for (long airport_id : this.airport_ids) { - String[] values = {String.valueOf(base_id), String.valueOf(airport_id)}; - String encoded = new CustomerId((int) base_id, airport_id).encode(); + /** testCustomerIdDecode */ + @Test + public void testCustomerIdDecode() { + for (long base_id : this.base_ids) { + for (long airport_id : this.airport_ids) { + String[] values = {String.valueOf(base_id), String.valueOf(airport_id)}; + String encoded = new CustomerId((int) base_id, airport_id).encode(); - String[] new_values = new CustomerId(encoded).toArray(); - assertEquals(values.length, new_values.length); - for (int i = 0; i < new_values.length; i++) { - assertEquals(values[i], new_values[i]); - } // FOR - } // FOR + String[] new_values = new CustomerId(encoded).toArray(); + assertEquals(values.length, new_values.length); + for (int i = 0; i < new_values.length; i++) { + assertEquals(values[i], new_values[i]); } // FOR - } -} \ No newline at end of file + } // FOR + } // FOR + } +} diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerIdIterable.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerIdIterable.java index 0fa3987fa..586dcc01c 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerIdIterable.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestCustomerIdIterable.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertNotNull; import com.oltpbenchmark.util.Histogram; - import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -30,36 +29,31 @@ public class TestCustomerIdIterable { - final Random rand = new Random(); - final Histogram airport_max_customer_id = new Histogram(); - CustomerIdIterable customer_id_iterable; - - @Before - public void setUp() throws Exception { - for (long airport = 0; airport <= 285; airport++) { - this.airport_max_customer_id.put(airport, rand.nextInt(100)); - } // FOR - this.customer_id_iterable = new CustomerIdIterable(this.airport_max_customer_id); - } - - - /** - * testIterator - */ - @Test - public void testIterator() throws Exception { - Set seen_ids = new HashSet<>(); - Histogram airport_ids = new Histogram<>(); - for (CustomerId c_id : this.customer_id_iterable) { - assertNotNull(c_id); - String encoded = c_id.encode(); - assertFalse(seen_ids.contains(encoded)); - seen_ids.add(encoded); - airport_ids.put(c_id.getDepartAirportId()); - } // FOR - assertEquals(this.airport_max_customer_id.getSampleCount(), seen_ids.size()); - assertEquals(this.airport_max_customer_id, airport_ids); - } - - + final Random rand = new Random(); + final Histogram airport_max_customer_id = new Histogram(); + CustomerIdIterable customer_id_iterable; + + @Before + public void setUp() throws Exception { + for (long airport = 0; airport <= 285; airport++) { + this.airport_max_customer_id.put(airport, rand.nextInt(100)); + } // FOR + this.customer_id_iterable = new CustomerIdIterable(this.airport_max_customer_id); + } + + /** testIterator */ + @Test + public void testIterator() throws Exception { + Set seen_ids = new HashSet<>(); + Histogram airport_ids = new Histogram<>(); + for (CustomerId c_id : this.customer_id_iterable) { + assertNotNull(c_id); + String encoded = c_id.encode(); + assertFalse(seen_ids.contains(encoded)); + seen_ids.add(encoded); + airport_ids.put(c_id.getDepartAirportId()); + } // FOR + assertEquals(this.airport_max_customer_id.getSampleCount(), seen_ids.size()); + assertEquals(this.airport_max_customer_id, airport_ids); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestDistanceUtil.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestDistanceUtil.java index 3f28b9b49..e9ed05842 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestDistanceUtil.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestDistanceUtil.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.seats.util; import static org.junit.Assert.assertEquals; @@ -23,37 +22,34 @@ public class TestDistanceUtil { - /** - * testDistance - */ - @Test - public void testDistance() throws Exception { - // { latitude, longitude } - double[][] locations = { - {39.175278, -76.668333}, // Baltimore-Washington, USA (BWI) - {-22.808889, -43.243611}, // Rio de Janeiro, Brazil (GIG) - {40.633333, -73.783333}, // New York, USA (JFK) - {-33.946111, 151.177222}, // Syndey, Austrailia (SYD) - }; - // expected distance in miles - double[] expected = { - 4796, // BWI->GIG - 183, // BWI->JFK - 9787, // BWI->SYD - 4802, // GIG->JFK - 8402, // GIG->SYD - 9950, // JFK->SYD - }; - - int e = 0; - for (int i = 0; i < locations.length - 1; i++) { - double[] loc0 = locations[i]; - for (int j = i + 1; j < locations.length; j++) { - double[] loc1 = locations[j]; - double distance = Math.round(DistanceUtil.distance(loc0[0], loc0[1], loc1[0], loc1[1])); - assertEquals(expected[e++], distance, 0.0001f); - } // FOR - } // FOR - } - + /** testDistance */ + @Test + public void testDistance() throws Exception { + // { latitude, longitude } + double[][] locations = { + {39.175278, -76.668333}, // Baltimore-Washington, USA (BWI) + {-22.808889, -43.243611}, // Rio de Janeiro, Brazil (GIG) + {40.633333, -73.783333}, // New York, USA (JFK) + {-33.946111, 151.177222}, // Syndey, Austrailia (SYD) + }; + // expected distance in miles + double[] expected = { + 4796, // BWI->GIG + 183, // BWI->JFK + 9787, // BWI->SYD + 4802, // GIG->JFK + 8402, // GIG->SYD + 9950, // JFK->SYD + }; + + int e = 0; + for (int i = 0; i < locations.length - 1; i++) { + double[] loc0 = locations[i]; + for (int j = i + 1; j < locations.length; j++) { + double[] loc1 = locations[j]; + double distance = Math.round(DistanceUtil.distance(loc0[0], loc0[1], loc1[0], loc1[1])); + assertEquals(expected[e++], distance, 0.0001f); + } // FOR + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestFlightId.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestFlightId.java index 4bb7478ce..89379cd5b 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestFlightId.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestFlightId.java @@ -14,14 +14,12 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.seats.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import com.oltpbenchmark.benchmarks.seats.SEATSConstants; - import java.sql.Timestamp; import java.util.Calendar; import org.junit.Before; @@ -29,86 +27,94 @@ public class TestFlightId { - private final long[] base_ids = {111, 222, 333}; - private final long[] depart_airport_ids = {444, 555, 666}; - private final long[] arrive_airport_ids = {777, 888, 999}; - private final int[] flight_offset_days = {1, 2, 4, 8}; - private final Timestamp[] flight_dates = new Timestamp[this.flight_offset_days.length]; - private Timestamp start_date; + private final long[] base_ids = {111, 222, 333}; + private final long[] depart_airport_ids = {444, 555, 666}; + private final long[] arrive_airport_ids = {777, 888, 999}; + private final int[] flight_offset_days = {1, 2, 4, 8}; + private final Timestamp[] flight_dates = new Timestamp[this.flight_offset_days.length]; + private Timestamp start_date; - @Before - public void setUp() throws Exception { - this.start_date = new Timestamp(Calendar.getInstance().getTime().getTime()); - for (int i = 0; i < this.flight_dates.length; i++) { - int day = this.flight_offset_days[i]; - this.flight_dates[i] = new Timestamp(this.start_date.getTime() + (day * SEATSConstants.MILLISECONDS_PER_DAY)); - } // FOR - } + @Before + public void setUp() throws Exception { + this.start_date = new Timestamp(Calendar.getInstance().getTime().getTime()); + for (int i = 0; i < this.flight_dates.length; i++) { + int day = this.flight_offset_days[i]; + this.flight_dates[i] = + new Timestamp(this.start_date.getTime() + (day * SEATSConstants.MILLISECONDS_PER_DAY)); + } // FOR + } - /** - * testFlightId - */ - @Test - public void testFlightId() { - for (long base_id : this.base_ids) { - for (long depart_airport_id : this.depart_airport_ids) { - for (long arrive_airport_id : this.arrive_airport_ids) { - for (Timestamp flight_date : this.flight_dates) { - FlightId flight_id = new FlightId(base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date); - assertNotNull(flight_id); - assertEquals(base_id, flight_id.getAirlineId()); - assertEquals(depart_airport_id, flight_id.getDepartAirportId()); - assertEquals(arrive_airport_id, flight_id.getArriveAirportId()); - assertEquals(flight_date, flight_id.getDepartDateAsTimestamp(this.start_date)); - } // FOR (time_code) - } // FOR (arrive_airport_id) - } // FOR (depart_airport_id) - } // FOR (base_ids) - } + /** testFlightId */ + @Test + public void testFlightId() { + for (long base_id : this.base_ids) { + for (long depart_airport_id : this.depart_airport_ids) { + for (long arrive_airport_id : this.arrive_airport_ids) { + for (Timestamp flight_date : this.flight_dates) { + FlightId flight_id = + new FlightId( + base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date); + assertNotNull(flight_id); + assertEquals(base_id, flight_id.getAirlineId()); + assertEquals(depart_airport_id, flight_id.getDepartAirportId()); + assertEquals(arrive_airport_id, flight_id.getArriveAirportId()); + assertEquals(flight_date, flight_id.getDepartDateAsTimestamp(this.start_date)); + } // FOR (time_code) + } // FOR (arrive_airport_id) + } // FOR (depart_airport_id) + } // FOR (base_ids) + } - /** - * testFlightIdEncode - */ - @Test - public void testFlightIdEncode() { - for (long base_id : this.base_ids) { - for (long depart_airport_id : this.depart_airport_ids) { - for (long arrive_airport_id : this.arrive_airport_ids) { - for (Timestamp flight_date : this.flight_dates) { - String encoded = new FlightId(base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date).encode(); + /** testFlightIdEncode */ + @Test + public void testFlightIdEncode() { + for (long base_id : this.base_ids) { + for (long depart_airport_id : this.depart_airport_ids) { + for (long arrive_airport_id : this.arrive_airport_ids) { + for (Timestamp flight_date : this.flight_dates) { + String encoded = + new FlightId( + base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date) + .encode(); - FlightId flight_id = new FlightId(encoded); - assertNotNull(flight_id); - assertEquals(base_id, flight_id.getAirlineId()); - assertEquals(depart_airport_id, flight_id.getDepartAirportId()); - assertEquals(arrive_airport_id, flight_id.getArriveAirportId()); - assertEquals(flight_date, flight_id.getDepartDateAsTimestamp(this.start_date)); - } // FOR (time_code) - } // FOR (arrive_airport_id) - } // FOR (depart_airport_id) - } // FOR (base_ids) - } + FlightId flight_id = new FlightId(encoded); + assertNotNull(flight_id); + assertEquals(base_id, flight_id.getAirlineId()); + assertEquals(depart_airport_id, flight_id.getDepartAirportId()); + assertEquals(arrive_airport_id, flight_id.getArriveAirportId()); + assertEquals(flight_date, flight_id.getDepartDateAsTimestamp(this.start_date)); + } // FOR (time_code) + } // FOR (arrive_airport_id) + } // FOR (depart_airport_id) + } // FOR (base_ids) + } - /** - * testFlightIdDecode - */ - @Test - public void testFlightIdDecode() { - for (long base_id : this.base_ids) { - for (long depart_airport_id : this.depart_airport_ids) { - for (long arrive_airport_id : this.arrive_airport_ids) { - for (Timestamp flight_date : this.flight_dates) { - String[] values = {String.valueOf(base_id), String.valueOf(depart_airport_id), String.valueOf(arrive_airport_id), String.valueOf(FlightId.calculateFlightDate(this.start_date, flight_date))}; - String encoded = new FlightId(base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date).encode(); + /** testFlightIdDecode */ + @Test + public void testFlightIdDecode() { + for (long base_id : this.base_ids) { + for (long depart_airport_id : this.depart_airport_ids) { + for (long arrive_airport_id : this.arrive_airport_ids) { + for (Timestamp flight_date : this.flight_dates) { + String[] values = { + String.valueOf(base_id), + String.valueOf(depart_airport_id), + String.valueOf(arrive_airport_id), + String.valueOf(FlightId.calculateFlightDate(this.start_date, flight_date)) + }; + String encoded = + new FlightId( + base_id, depart_airport_id, arrive_airport_id, this.start_date, flight_date) + .encode(); - String[] new_values = new FlightId(encoded).toArray(); - assertEquals(values.length, new_values.length); - for (int i = 0; i < new_values.length; i++) { - assertEquals(values[i], new_values[i]); - } // FOR - } // FOR (time_code) - } // FOR (arrive_airport_id) - } // FOR (depart_airport_id) - } // FOR (base_ids) - } -} \ No newline at end of file + String[] new_values = new FlightId(encoded).toArray(); + assertEquals(values.length, new_values.length); + for (int i = 0; i < new_values.length; i++) { + assertEquals(values[i], new_values[i]); + } // FOR + } // FOR (time_code) + } // FOR (arrive_airport_id) + } // FOR (depart_airport_id) + } // FOR (base_ids) + } +} diff --git a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestReturnFlight.java b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestReturnFlight.java index 3c14de980..4f1d293f3 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestReturnFlight.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/seats/util/TestReturnFlight.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.seats.util; import static org.junit.Assert.assertEquals; @@ -27,44 +26,41 @@ public class TestReturnFlight { - private final int customer_base_id = 1000; - private final long depart_airport_id = 9999; - private final int[] return_days = {1, 5, 14}; + private final int customer_base_id = 1000; + private final long depart_airport_id = 9999; + private final int[] return_days = {1, 5, 14}; - private Timestamp flight_date; - private CustomerId customer_id; + private Timestamp flight_date; + private CustomerId customer_id; - @Before - public void setUp() throws Exception { - this.customer_id = new CustomerId(this.customer_base_id, this.depart_airport_id); - assertNotNull(this.customer_id); - this.flight_date = new Timestamp(System.currentTimeMillis()); - assertNotNull(this.flight_date); - } + @Before + public void setUp() throws Exception { + this.customer_id = new CustomerId(this.customer_base_id, this.depart_airport_id); + assertNotNull(this.customer_id); + this.flight_date = new Timestamp(System.currentTimeMillis()); + assertNotNull(this.flight_date); + } - /** - * testReturnFlight - */ - @Test - public void testReturnFlight() { - for (int return_day : this.return_days) { - ReturnFlight return_flight = new ReturnFlight(this.customer_id, this.depart_airport_id, this.flight_date, return_day); - assertNotNull(return_flight); - assertEquals(this.customer_id, return_flight.getCustomerId()); - assertEquals(this.depart_airport_id, return_flight.getReturnAirportId()); - assertTrue(this.flight_date.getTime() < return_flight.getReturnDate().getTime()); - } // FOR - } + /** testReturnFlight */ + @Test + public void testReturnFlight() { + for (int return_day : this.return_days) { + ReturnFlight return_flight = + new ReturnFlight(this.customer_id, this.depart_airport_id, this.flight_date, return_day); + assertNotNull(return_flight); + assertEquals(this.customer_id, return_flight.getCustomerId()); + assertEquals(this.depart_airport_id, return_flight.getReturnAirportId()); + assertTrue(this.flight_date.getTime() < return_flight.getReturnDate().getTime()); + } // FOR + } - /** - * testCalculateReturnDate - */ - @Test - public void testCalculateReturnDate() { - for (int return_day : this.return_days) { - Timestamp return_flight_date = ReturnFlight.calculateReturnDate(this.flight_date, return_day); - assertNotNull(return_flight_date); - assertTrue(this.flight_date.getTime() < return_flight_date.getTime()); - } // FOR - } + /** testCalculateReturnDate */ + @Test + public void testCalculateReturnDate() { + for (int return_day : this.return_days) { + Timestamp return_flight_date = ReturnFlight.calculateReturnDate(this.flight_date, return_day); + assertNotNull(return_flight_date); + assertTrue(this.flight_date.getTime() < return_flight_date.getTime()); + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankBenchmark.java index 77f975954..360754d5f 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankBenchmark.java @@ -14,34 +14,31 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.smallbank; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.smallbank.procedures.*; - import java.util.List; public class TestSmallBankBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - Amalgamate.class, - Balance.class, - DepositChecking.class, - SendPayment.class, - TransactSavings.class, - WriteCheck.class - ); - - @Override - public List> procedures() { - return TestSmallBankBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return SmallBankBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + Amalgamate.class, + Balance.class, + DepositChecking.class, + SendPayment.class, + TransactSavings.class, + WriteCheck.class); + + @Override + public List> procedures() { + return TestSmallBankBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return SmallBankBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankLoader.java index ce39ead57..db2339b7c 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankLoader.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestSmallBankLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestSmallBankBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return SmallBankBenchmark.class; - } + @Override + public List> procedures() { + return TestSmallBankBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return SmallBankBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankWorker.java index f7cc14afb..0f157b4d4 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/smallbank/TestSmallBankWorker.java @@ -18,18 +18,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestSmallBankWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestSmallBankBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestSmallBankBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return SmallBankBenchmark.class; - } + @Override + public Class benchmarkClass() { + return SmallBankBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPBenchmark.java index 5f2560f00..8d1b718e2 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPBenchmark.java @@ -14,35 +14,32 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.tatp; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.tatp.procedures.*; - import java.util.List; public class TestTATPBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - DeleteCallForwarding.class, - GetAccessData.class, - GetNewDestination.class, - GetSubscriberData.class, - InsertCallForwarding.class, - UpdateLocation.class, - UpdateSubscriberData.class - ); - - @Override - public List> procedures() { - return TestTATPBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TATPBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + DeleteCallForwarding.class, + GetAccessData.class, + GetNewDestination.class, + GetSubscriberData.class, + InsertCallForwarding.class, + UpdateLocation.class, + UpdateSubscriberData.class); + + @Override + public List> procedures() { + return TestTATPBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return TATPBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPLoader.java index befc6f6e0..8c4e14f23 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPLoader.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTATPLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestTATPBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TATPBenchmark.class; - } + @Override + public List> procedures() { + return TestTATPBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return TATPBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPWorker.java index 4a072e8b5..00235f2de 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tatp/TestTATPWorker.java @@ -18,18 +18,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTATPWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestTATPBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestTATPBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return TATPBenchmark.class; - } + @Override + public Class benchmarkClass() { + return TATPBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/templated/TestTemplatedWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/templated/TestTemplatedWorker.java index 19cf7cf99..026f8c061 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/templated/TestTemplatedWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/templated/TestTemplatedWorker.java @@ -1,123 +1,123 @@ package com.oltpbenchmark.benchmarks.templated; -import com.oltpbenchmark.api.AbstractTestWorker; -import com.oltpbenchmark.api.Procedure; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import com.oltpbenchmark.DBWorkload; import com.oltpbenchmark.WorkloadConfiguration; - +import com.oltpbenchmark.api.AbstractTestWorker; +import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.tpcc.TPCCBenchmark; - import java.nio.file.Paths; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; - import org.apache.commons.configuration2.XMLConfiguration; import org.apache.commons.configuration2.ex.ConfigurationException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.junit.Assert.fail; -import static org.junit.Assert.assertNotNull; - - public class TestTemplatedWorker extends AbstractTestWorker { - private static final Logger LOG = LoggerFactory.getLogger(TestTemplatedWorker.class); - - public static final String DDL_OVERRIDE_PATH = Paths.get("src", "main", "resources", "benchmarks", "tpcc", "ddl-generic.sql").toAbsolutePath().toString(); - public static final String SAMPLE_TEMPLATED_LOADING_CONFIG = Paths.get("config", "sqlite", "sample_tpcc_config.xml").toAbsolutePath().toString(); - public static final String SAMPLE_TEMPLATED_CONFIG = Paths.get("config", "sqlite", "sample_templated_config.xml").toAbsolutePath().toString(); - public static final String TEMPLATES_CONFIG = Paths.get("data", "templated", "example.xml").toAbsolutePath().toString(); - - TPCCBenchmark tpccBenchmark = null; - - public TestTemplatedWorker() { - // Technically we aren't creating this schema with the - // TemplatedBenchmark, but specifying the DDL that we are using (see - // below) allows some other checks to pass. - super(DDL_OVERRIDE_PATH); + private static final Logger LOG = LoggerFactory.getLogger(TestTemplatedWorker.class); + + public static final String DDL_OVERRIDE_PATH = + Paths.get("src", "main", "resources", "benchmarks", "tpcc", "ddl-generic.sql") + .toAbsolutePath() + .toString(); + public static final String SAMPLE_TEMPLATED_LOADING_CONFIG = + Paths.get("config", "sqlite", "sample_tpcc_config.xml").toAbsolutePath().toString(); + public static final String SAMPLE_TEMPLATED_CONFIG = + Paths.get("config", "sqlite", "sample_templated_config.xml").toAbsolutePath().toString(); + public static final String TEMPLATES_CONFIG = + Paths.get("data", "templated", "example.xml").toAbsolutePath().toString(); + + TPCCBenchmark tpccBenchmark = null; + + public TestTemplatedWorker() { + // Technically we aren't creating this schema with the + // TemplatedBenchmark, but specifying the DDL that we are using (see + // below) allows some other checks to pass. + super(DDL_OVERRIDE_PATH); + } + + public static void setWorkloadConfigXml(WorkloadConfiguration workConf) { + // Load the configuration file so we can parse the query_template_file value. + try { + XMLConfiguration xmlConf = DBWorkload.buildConfiguration(SAMPLE_TEMPLATED_CONFIG); + workConf.setXmlConfig(xmlConf); + } catch (ConfigurationException ex) { + LOG.error("Error loading configuration: " + SAMPLE_TEMPLATED_CONFIG, ex); } - - public static void setWorkloadConfigXml(WorkloadConfiguration workConf) { - // Load the configuration file so we can parse the query_template_file value. - try { - XMLConfiguration xmlConf = DBWorkload.buildConfiguration(SAMPLE_TEMPLATED_CONFIG); - workConf.setXmlConfig(xmlConf); - } - catch (ConfigurationException ex) { - LOG.error("Error loading configuration: " + SAMPLE_TEMPLATED_CONFIG, ex); - } + } + + @Override + protected void customWorkloadConfiguration(WorkloadConfiguration workConf) { + setWorkloadConfigXml(workConf); + } + + @Override + public List> procedures() { + // Note: the first time this is called is before the benchmark is + // initialized, so it should return nothing. + // It's only populated after the config is loaded for the benchmark. + List> procedures = new ArrayList<>(); + if (this.benchmark != null) { + procedures = this.benchmark.getProcedureClasses(); + if (!procedures.isEmpty() && this.workConf.getTransTypes().isEmpty()) { + workConf.setTransTypes(proceduresToTransactionTypes(procedures)); + } } + return procedures; + } - @Override - protected void customWorkloadConfiguration(WorkloadConfiguration workConf) { - setWorkloadConfigXml(workConf); - } + @Override + public Class benchmarkClass() { + return TemplatedBenchmark.class; + } - @Override - public List> procedures() { - // Note: the first time this is called is before the benchmark is - // initialized, so it should return nothing. - // It's only populated after the config is loaded for the benchmark. - List> procedures = new ArrayList<>(); - if (this.benchmark != null) { - procedures = this.benchmark.getProcedureClasses(); - if (!procedures.isEmpty() && this.workConf.getTransTypes().isEmpty()) { - workConf.setTransTypes(proceduresToTransactionTypes(procedures)); - } - } - return procedures; + private void setupTpccBenchmarkHelper() throws SQLException { + if (this.tpccBenchmark != null) { + return; } - @Override - public Class benchmarkClass() { - return TemplatedBenchmark.class; + // Create a second benchmark to re/ab/use for loading the database (tpcc in this case). + WorkloadConfiguration tpccWorkConf = new WorkloadConfiguration(); + tpccWorkConf.setDatabaseType(this.workConf.getDatabaseType()); + tpccWorkConf.setUrl(this.workConf.getUrl()); + tpccWorkConf.setScaleFactor(this.workConf.getScaleFactor()); + tpccWorkConf.setTerminals(this.workConf.getTerminals()); + tpccWorkConf.setBatchSize(this.workConf.getBatchSize()); + // tpccWorkConf.setBenchmarkName(BenchmarkModule.convertBenchmarkClassToBenchmarkName(TPCCBenchmark.class)); + tpccWorkConf.setBenchmarkName( + TPCCBenchmark.class.getSimpleName().toLowerCase().replace("benchmark", "")); + + this.tpccBenchmark = new TPCCBenchmark(this.workConf); + conn = this.tpccBenchmark.makeConnection(); + assertNotNull(conn); + this.tpccBenchmark.refreshCatalog(); + catalog = this.tpccBenchmark.getCatalog(); + assertNotNull(catalog); + } + + protected void createDatabase() { + try { + this.setupTpccBenchmarkHelper(); + this.tpccBenchmark.createDatabase(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + cleanupServer(); + fail("createDatabase() failed"); } - - private void setupTpccBenchmarkHelper() throws SQLException { - if (this.tpccBenchmark != null) { - return; - } - - // Create a second benchmark to re/ab/use for loading the database (tpcc in this case). - WorkloadConfiguration tpccWorkConf = new WorkloadConfiguration(); - tpccWorkConf.setDatabaseType(this.workConf.getDatabaseType()); - tpccWorkConf.setUrl(this.workConf.getUrl()); - tpccWorkConf.setScaleFactor(this.workConf.getScaleFactor()); - tpccWorkConf.setTerminals(this.workConf.getTerminals()); - tpccWorkConf.setBatchSize(this.workConf.getBatchSize()); - // tpccWorkConf.setBenchmarkName(BenchmarkModule.convertBenchmarkClassToBenchmarkName(TPCCBenchmark.class)); - tpccWorkConf.setBenchmarkName(TPCCBenchmark.class.getSimpleName().toLowerCase().replace("benchmark", "")); - - this.tpccBenchmark = new TPCCBenchmark(this.workConf); - conn = this.tpccBenchmark.makeConnection(); - assertNotNull(conn); - this.tpccBenchmark.refreshCatalog(); - catalog = this.tpccBenchmark.getCatalog(); - assertNotNull(catalog); - } - - protected void createDatabase() { - try { - this.setupTpccBenchmarkHelper(); - this.tpccBenchmark.createDatabase(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - cleanupServer(); - fail("createDatabase() failed"); - } - } - - protected void loadDatabase() { - try { - this.setupTpccBenchmarkHelper(); - this.tpccBenchmark.loadDatabase(); - } catch (Exception e) { - LOG.error(e.getMessage(), e); - cleanupServer(); - fail("loadDatabase() failed"); - } + } + + protected void loadDatabase() { + try { + this.setupTpccBenchmarkHelper(); + this.tpccBenchmark.loadDatabase(); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + cleanupServer(); + fail("loadDatabase() failed"); } + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCBenchmark.java index dd6330d89..0d83c7c95 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCBenchmark.java @@ -14,33 +14,25 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.tpcc; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.tpcc.procedures.*; - import java.util.List; public class TestTPCCBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - Delivery.class, - NewOrder.class, - OrderStatus.class, - Payment.class, - StockLevel.class - ); - - @Override - public List> procedures() { - return TestTPCCBenchmark.PROCEDURE_CLASSES; - } + public static final List> PROCEDURE_CLASSES = + List.of(Delivery.class, NewOrder.class, OrderStatus.class, Payment.class, StockLevel.class); - @Override - public Class benchmarkClass() { - return TPCCBenchmark.class; - } + @Override + public List> procedures() { + return TestTPCCBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return TPCCBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCLoader.java index e63ea89ab..33285f25f 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCLoader.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTPCCLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestTPCCBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TPCCBenchmark.class; - } + @Override + public List> procedures() { + return TestTPCCBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return TPCCBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCWorker.java index 6fa9aa246..73cb39708 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpcc/TestTPCCWorker.java @@ -2,19 +2,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTPCCWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestTPCCBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TPCCBenchmark.class; - } + @Override + public List> procedures() { + return TestTPCCBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return TPCCBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHBenchmark.java index bf87248e2..0c47b0d88 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHBenchmark.java @@ -14,49 +14,28 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.tpch; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.tpch.procedures.*; - import java.util.List; public class TestTPCHBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - Q1.class, - Q2.class, - Q3.class, - Q4.class, - Q5.class, - Q6.class, - Q7.class, - Q8.class, - Q9.class, - Q10.class, - Q11.class, - Q12.class, - Q13.class, - Q14.class, - Q15.class, - Q16.class, - Q17.class, - Q18.class, - Q19.class, - Q20.class, - Q21.class, - Q22.class); - - @Override - public List> procedures() { - return TestTPCHBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TPCHBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + Q1.class, Q2.class, Q3.class, Q4.class, Q5.class, Q6.class, Q7.class, Q8.class, Q9.class, + Q10.class, Q11.class, Q12.class, Q13.class, Q14.class, Q15.class, Q16.class, Q17.class, + Q18.class, Q19.class, Q20.class, Q21.class, Q22.class); + + @Override + public List> procedures() { + return TestTPCHBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return TPCHBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHLoader.java index d0db44b82..5477ce0e7 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHLoader.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTPCHLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestTPCHBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return TPCHBenchmark.class; - } + @Override + public List> procedures() { + return TestTPCHBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return TPCHBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHWorker.java index f589b0b90..021e88d76 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/tpch/TestTPCHWorker.java @@ -3,26 +3,25 @@ import com.oltpbenchmark.WorkloadConfiguration; import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestTPCHWorker extends AbstractTestWorker { - private static final double SCALE_FACTOR = .001; + private static final double SCALE_FACTOR = .001; - @Override - public List> procedures() { - return TestTPCHBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestTPCHBenchmark.PROCEDURE_CLASSES; + } - @Override - protected void customWorkloadConfiguration(WorkloadConfiguration workConf) { - // let's set the SF even lower than .01 for actual worker tests - this.workConf.setScaleFactor(SCALE_FACTOR); - } + @Override + protected void customWorkloadConfiguration(WorkloadConfiguration workConf) { + // let's set the SF even lower than .01 for actual worker tests + this.workConf.setScaleFactor(SCALE_FACTOR); + } - @Override - public Class benchmarkClass() { - return TPCHBenchmark.class; - } -} \ No newline at end of file + @Override + public Class benchmarkClass() { + return TPCHBenchmark.class; + } +} diff --git a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterBenchmark.java index b6a657f8f..bdb1eb545 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterBenchmark.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.twitter; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; @@ -23,25 +22,20 @@ import com.oltpbenchmark.benchmarks.twitter.procedures.GetTweet; import com.oltpbenchmark.benchmarks.twitter.procedures.GetTweetsFromFollowing; import com.oltpbenchmark.benchmarks.twitter.procedures.InsertTweet; - import java.util.List; public class TestTwitterBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - GetFollowers.class, - GetTweet.class, - GetTweetsFromFollowing.class, - InsertTweet.class - ); + public static final List> PROCEDURE_CLASSES = + List.of(GetFollowers.class, GetTweet.class, GetTweetsFromFollowing.class, InsertTweet.class); - @Override - public List> procedures() { - return TestTwitterBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestTwitterBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return TwitterBenchmark.class; - } + @Override + public Class benchmarkClass() { + return TwitterBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterLoader.java index e4fec261b..fe022f3cc 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterLoader.java @@ -18,30 +18,26 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; -import org.junit.Ignore; - import java.util.List; +import org.junit.Ignore; @Ignore("the testcase is under development") public class TestTwitterLoader extends AbstractTestLoader { - private final String[] IGNORED_TABLES = { - TwitterConstants.TABLENAME_ADDED_TWEETS - }; - - @Override - public List> procedures() { - return TestTwitterBenchmark.PROCEDURE_CLASSES; - } + private final String[] IGNORED_TABLES = {TwitterConstants.TABLENAME_ADDED_TWEETS}; - @Override - public Class benchmarkClass() { - return TwitterBenchmark.class; - } + @Override + public List> procedures() { + return TestTwitterBenchmark.PROCEDURE_CLASSES; + } - @Override - public List ignorableTables() { - return List.of(IGNORED_TABLES); - } + @Override + public Class benchmarkClass() { + return TwitterBenchmark.class; + } + @Override + public List ignorableTables() { + return List.of(IGNORED_TABLES); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterWorker.java index c72ba470d..ec36422e2 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/twitter/TestTwitterWorker.java @@ -2,20 +2,19 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; -import org.junit.Ignore; - import java.util.List; +import org.junit.Ignore; @Ignore("the testcase is under development") public class TestTwitterWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestTwitterBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestTwitterBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return TwitterBenchmark.class; - } + @Override + public Class benchmarkClass() { + return TwitterBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterBenchmark.java index db6d214c3..7655576ea 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterBenchmark.java @@ -19,23 +19,19 @@ import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.voter.procedures.Vote; - import java.util.List; public class TestVoterBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - Vote.class - ); - - @Override - public List> procedures() { - return TestVoterBenchmark.PROCEDURE_CLASSES; - } + public static final List> PROCEDURE_CLASSES = List.of(Vote.class); - @Override - public Class benchmarkClass() { - return VoterBenchmark.class; - } + @Override + public List> procedures() { + return TestVoterBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return VoterBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterLoader.java index 47017d76e..f57cb3afd 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterLoader.java @@ -18,28 +18,24 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestVoterLoader extends AbstractTestLoader { - private static final String[] IGNORE = { - VoterConstants.TABLENAME_VOTES - }; - - @Override - public List> procedures() { - return TestVoterBenchmark.PROCEDURE_CLASSES; - } + private static final String[] IGNORE = {VoterConstants.TABLENAME_VOTES}; - @Override - public Class benchmarkClass() { - return VoterBenchmark.class; - } + @Override + public List> procedures() { + return TestVoterBenchmark.PROCEDURE_CLASSES; + } - @Override - public List ignorableTables() { - return List.of(IGNORE); - } + @Override + public Class benchmarkClass() { + return VoterBenchmark.class; + } + @Override + public List ignorableTables() { + return List.of(IGNORE); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterWorker.java index 64e2cc984..2fb356a48 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/voter/TestVoterWorker.java @@ -18,18 +18,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestVoterWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestVoterBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestVoterBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return VoterBenchmark.class; - } + @Override + public Class benchmarkClass() { + return VoterBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaBenchmark.java index 51bc8dbf4..7044bdef8 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaBenchmark.java @@ -14,33 +14,30 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.wikipedia; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.wikipedia.procedures.*; - import java.util.List; public class TestWikipediaBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - AddWatchList.class, - GetPageAnonymous.class, - GetPageAuthenticated.class, - RemoveWatchList.class, - UpdatePage.class - ); - - @Override - public List> procedures() { - return TestWikipediaBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return WikipediaBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + AddWatchList.class, + GetPageAnonymous.class, + GetPageAuthenticated.class, + RemoveWatchList.class, + UpdatePage.class); + + @Override + public List> procedures() { + return TestWikipediaBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return WikipediaBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaLoader.java index a00f034f4..bb84545a6 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaLoader.java @@ -18,35 +18,34 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestWikipediaLoader extends AbstractTestLoader { - private static final String[] IGNORE = { - WikipediaConstants.TABLENAME_IPBLOCKS, - WikipediaConstants.TABLENAME_LOGGING, - WikipediaConstants.TABLENAME_PAGE_BACKUP, - WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS, - WikipediaConstants.TABLENAME_RECENTCHANGES, - WikipediaConstants.TABLENAME_REVISION, - WikipediaConstants.TABLENAME_TEXT, - WikipediaConstants.TABLENAME_USER_GROUPS, - WikipediaConstants.TABLENAME_VALUE_BACKUP, - }; - - @Override - public List> procedures() { - return TestWikipediaBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return WikipediaBenchmark.class; - } - - @Override - public List ignorableTables() { - return List.of(IGNORE); - } + private static final String[] IGNORE = { + WikipediaConstants.TABLENAME_IPBLOCKS, + WikipediaConstants.TABLENAME_LOGGING, + WikipediaConstants.TABLENAME_PAGE_BACKUP, + WikipediaConstants.TABLENAME_PAGE_RESTRICTIONS, + WikipediaConstants.TABLENAME_RECENTCHANGES, + WikipediaConstants.TABLENAME_REVISION, + WikipediaConstants.TABLENAME_TEXT, + WikipediaConstants.TABLENAME_USER_GROUPS, + WikipediaConstants.TABLENAME_VALUE_BACKUP, + }; + + @Override + public List> procedures() { + return TestWikipediaBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return WikipediaBenchmark.class; + } + + @Override + public List ignorableTables() { + return List.of(IGNORE); + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaWorker.java index 311e88dd3..123ffb1c1 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/wikipedia/TestWikipediaWorker.java @@ -2,18 +2,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestWikipediaWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestWikipediaBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestWikipediaBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return WikipediaBenchmark.class; - } + @Override + public Class benchmarkClass() { + return WikipediaBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBBenchmark.java b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBBenchmark.java index aff513491..4fec614ea 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBBenchmark.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBBenchmark.java @@ -14,34 +14,31 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.benchmarks.ycsb; import com.oltpbenchmark.api.AbstractTestBenchmarkModule; import com.oltpbenchmark.api.Procedure; import com.oltpbenchmark.benchmarks.ycsb.procedures.*; - import java.util.List; public class TestYCSBBenchmark extends AbstractTestBenchmarkModule { - public static final List> PROCEDURE_CLASSES = List.of( - DeleteRecord.class, - InsertRecord.class, - ReadModifyWriteRecord.class, - ReadRecord.class, - ScanRecord.class, - UpdateRecord.class - ); - - @Override - public List> procedures() { - return TestYCSBBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return YCSBBenchmark.class; - } - + public static final List> PROCEDURE_CLASSES = + List.of( + DeleteRecord.class, + InsertRecord.class, + ReadModifyWriteRecord.class, + ReadRecord.class, + ScanRecord.class, + UpdateRecord.class); + + @Override + public List> procedures() { + return TestYCSBBenchmark.PROCEDURE_CLASSES; + } + + @Override + public Class benchmarkClass() { + return YCSBBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBLoader.java b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBLoader.java index 64f72469e..21ea348a5 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBLoader.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBLoader.java @@ -18,19 +18,17 @@ import com.oltpbenchmark.api.AbstractTestLoader; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestYCSBLoader extends AbstractTestLoader { - @Override - public List> procedures() { - return TestYCSBBenchmark.PROCEDURE_CLASSES; - } - - @Override - public Class benchmarkClass() { - return YCSBBenchmark.class; - } + @Override + public List> procedures() { + return TestYCSBBenchmark.PROCEDURE_CLASSES; + } + @Override + public Class benchmarkClass() { + return YCSBBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBWorker.java b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBWorker.java index e8b948350..a6d426b1b 100644 --- a/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBWorker.java +++ b/src/test/java/com/oltpbenchmark/benchmarks/ycsb/TestYCSBWorker.java @@ -2,18 +2,17 @@ import com.oltpbenchmark.api.AbstractTestWorker; import com.oltpbenchmark.api.Procedure; - import java.util.List; public class TestYCSBWorker extends AbstractTestWorker { - @Override - public List> procedures() { - return TestYCSBBenchmark.PROCEDURE_CLASSES; - } + @Override + public List> procedures() { + return TestYCSBBenchmark.PROCEDURE_CLASSES; + } - @Override - public Class benchmarkClass() { - return YCSBBenchmark.class; - } + @Override + public Class benchmarkClass() { + return YCSBBenchmark.class; + } } diff --git a/src/test/java/com/oltpbenchmark/catalog/TestHSQLDBCatalog.java b/src/test/java/com/oltpbenchmark/catalog/TestHSQLDBCatalog.java index 05e577e39..1e3cc9aa4 100644 --- a/src/test/java/com/oltpbenchmark/catalog/TestHSQLDBCatalog.java +++ b/src/test/java/com/oltpbenchmark/catalog/TestHSQLDBCatalog.java @@ -16,141 +16,131 @@ package com.oltpbenchmark.catalog; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import com.oltpbenchmark.api.MockBenchmark; import com.oltpbenchmark.types.DatabaseType; import com.oltpbenchmark.util.SQLUtil; - import java.io.InputStream; import java.util.Map; import java.util.Map.Entry; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - public class TestHSQLDBCatalog { - private MockBenchmark benchmark; - private HSQLDBCatalog catalog; - - @Before - public void setUp() throws Exception { - this.benchmark = new MockBenchmark(); - this.catalog = new HSQLDBCatalog(benchmark); - assertNotNull(this.catalog); - } - - /** - * testGetOriginalTableNames - */ - @Test - public void testGetOriginalTableNames() { - // Make sure that the key and values in this map are not - // equal unless we ignore their case - Map origTableNames = this.catalog.getOriginalTableNames(); - assertNotNull(origTableNames); - assertFalse(origTableNames.isEmpty()); - - for (Entry e : origTableNames.entrySet()) { - assertFalse(e.toString(), e.getKey().equals(e.getValue())); - assertTrue(e.toString(), e.getKey().equalsIgnoreCase(e.getValue())); - } - } - - /** - * testInit - */ - @Test - public void testInit() throws Exception { - // Count the number of CREATE TABLEs in our test file - String ddlPath = this.benchmark.getDatabaseDDLPath(DatabaseType.HSQLDB); - try (InputStream stream = this.getClass().getResourceAsStream(ddlPath)) { - assertNotNull(stream); - String contents = new String(stream.readAllBytes()); - assertFalse(contents.isEmpty()); - int offset = 0; - int num_tables = 0; - while (offset < contents.length()) { - offset = contents.indexOf("CREATE TABLE", offset); - if (offset == -1) break; - num_tables++; - offset++; - } - assertEquals(num_tables, 3); - - // Make sure that CatalogUtil returns the same number of tables - assertEquals(num_tables, this.catalog.getTables().size()); - - // Make sure that Map names match the Table names - for (String table_name : this.catalog.getTables().stream().map(AbstractCatalogObject::getName).toList()) { - Table catalog_tbl = this.catalog.getTable(table_name); - assertNotNull(catalog_tbl); - assertEquals(table_name, catalog_tbl.getName()); - } - } + private MockBenchmark benchmark; + private HSQLDBCatalog catalog; + + @Before + public void setUp() throws Exception { + this.benchmark = new MockBenchmark(); + this.catalog = new HSQLDBCatalog(benchmark); + assertNotNull(this.catalog); + } + + /** testGetOriginalTableNames */ + @Test + public void testGetOriginalTableNames() { + // Make sure that the key and values in this map are not + // equal unless we ignore their case + Map origTableNames = this.catalog.getOriginalTableNames(); + assertNotNull(origTableNames); + assertFalse(origTableNames.isEmpty()); + + for (Entry e : origTableNames.entrySet()) { + assertFalse(e.toString(), e.getKey().equals(e.getValue())); + assertTrue(e.toString(), e.getKey().equalsIgnoreCase(e.getValue())); } - - /** - * testForeignKeys - */ - @Test - public void testForeignKeys() { - // The C table should have two foreign keys - Table catalog_tbl = this.catalog.getTable("C"); - int found = 0; + } + + /** testInit */ + @Test + public void testInit() throws Exception { + // Count the number of CREATE TABLEs in our test file + String ddlPath = this.benchmark.getDatabaseDDLPath(DatabaseType.HSQLDB); + try (InputStream stream = this.getClass().getResourceAsStream(ddlPath)) { + assertNotNull(stream); + String contents = new String(stream.readAllBytes()); + assertFalse(contents.isEmpty()); + int offset = 0; + int num_tables = 0; + while (offset < contents.length()) { + offset = contents.indexOf("CREATE TABLE", offset); + if (offset == -1) break; + num_tables++; + offset++; + } + assertEquals(num_tables, 3); + + // Make sure that CatalogUtil returns the same number of tables + assertEquals(num_tables, this.catalog.getTables().size()); + + // Make sure that Map names match the Table names + for (String table_name : + this.catalog.getTables().stream().map(AbstractCatalogObject::getName).toList()) { + Table catalog_tbl = this.catalog.getTable(table_name); assertNotNull(catalog_tbl); - for (Column catalog_col : catalog_tbl.getColumns()) { - assertNotNull(catalog_col); - Column fkey_col = catalog_col.getForeignKey(); - if (fkey_col != null) { - assertNotEquals(fkey_col.getTable(), catalog_tbl); - found++; - } - } - assertEquals(2, found); + assertEquals(table_name, catalog_tbl.getName()); + } } - - /** - * testIndexes - */ - @Test - public void testIndexes() { - for (Table catalog_tbl : this.catalog.getTables()) { - assertNotNull(catalog_tbl); - - for (Index catalog_idx : catalog_tbl.getIndexes()) { - assertNotNull(catalog_idx); - assertEquals(catalog_tbl, catalog_idx.getTable()); - assertTrue(catalog_idx.getColumns().size() > 0); - - for (int i = 0; i < catalog_idx.getColumns().size(); i++) { - assertNotNull(catalog_idx.getColumns().get(i).getName()); - assertNotNull(catalog_idx.getColumns().get(i).getDir()); - } - } + } + + /** testForeignKeys */ + @Test + public void testForeignKeys() { + // The C table should have two foreign keys + Table catalog_tbl = this.catalog.getTable("C"); + int found = 0; + assertNotNull(catalog_tbl); + for (Column catalog_col : catalog_tbl.getColumns()) { + assertNotNull(catalog_col); + Column fkey_col = catalog_col.getForeignKey(); + if (fkey_col != null) { + assertNotEquals(fkey_col.getTable(), catalog_tbl); + found++; + } + } + assertEquals(2, found); + } + + /** testIndexes */ + @Test + public void testIndexes() { + for (Table catalog_tbl : this.catalog.getTables()) { + assertNotNull(catalog_tbl); + + for (Index catalog_idx : catalog_tbl.getIndexes()) { + assertNotNull(catalog_idx); + assertEquals(catalog_tbl, catalog_idx.getTable()); + assertTrue(catalog_idx.getColumns().size() > 0); + + for (int i = 0; i < catalog_idx.getColumns().size(); i++) { + assertNotNull(catalog_idx.getColumns().get(i).getName()); + assertNotNull(catalog_idx.getColumns().get(i).getDir()); } + } } - - /** - * testIntegerColumns - */ - @Test - public void testIntegerColumns() { - // Any column that has a name with 'IATTR' in it is an integer - // So we need to check to make sure that our little checker works - for (Table catalog_tbl : this.catalog.getTables()) { - assertNotNull(catalog_tbl); - for (Column catalog_col : catalog_tbl.getColumns()) { - assertNotNull(catalog_col); - if (catalog_col.getName().contains("_IATTR")) { - boolean actual = SQLUtil.isIntegerType(catalog_col.getType()); - assertTrue(catalog_col.getName() + " -> " + catalog_col.getType(), actual); - } - } + } + + /** testIntegerColumns */ + @Test + public void testIntegerColumns() { + // Any column that has a name with 'IATTR' in it is an integer + // So we need to check to make sure that our little checker works + for (Table catalog_tbl : this.catalog.getTables()) { + assertNotNull(catalog_tbl); + for (Column catalog_col : catalog_tbl.getColumns()) { + assertNotNull(catalog_col); + if (catalog_col.getName().contains("_IATTR")) { + boolean actual = SQLUtil.isIntegerType(catalog_col.getType()); + assertTrue(catalog_col.getName() + " -> " + catalog_col.getType(), actual); } + } } + } } diff --git a/src/test/java/com/oltpbenchmark/util/TestClassUtil.java b/src/test/java/com/oltpbenchmark/util/TestClassUtil.java index 3f1741d17..47d317dd7 100644 --- a/src/test/java/com/oltpbenchmark/util/TestClassUtil.java +++ b/src/test/java/com/oltpbenchmark/util/TestClassUtil.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.util; import static org.junit.Assert.assertEquals; @@ -30,109 +29,87 @@ */ public class TestClassUtil { - private final Class target_class = ArrayList.class; - - public static class MockObject1 { - public MockObject1(MockObject1 x) { - - } - } - - public static class MockObject2 { - public MockObject2(MockObject2 x) { - - } - } + private final Class target_class = ArrayList.class; - public static class MockObject3 extends MockObject2 { - public MockObject3(MockObject2 x) { - super(x); - } - } + public static class MockObject1 { + public MockObject1(MockObject1 x) {} + } - /** - * testGetConstructor - */ - @Test - public void testGetConstructor() throws Exception { - Class[] targets = { - MockObject1.class, - MockObject2.class, - }; - Class[] params = { - MockObject1.class - }; - - for (Class targetClass : targets) { - Constructor c = ClassUtil.getConstructor(targetClass, params); - assertNotNull(c); - } // FOR - } - - - /** - * testGetSuperClasses - */ - @Test - public void testGetSuperClasses() { - Class[] expected = { - target_class, - AbstractList.class, - AbstractCollection.class, - Object.class, - }; - List> results = ClassUtil.getSuperClasses(target_class); - // System.err.println(target_class + " => " + results); - assert (!results.isEmpty()); - assertEquals(expected.length, results.size()); - - for (Class e : expected) { - assert (results.contains(e)); - } // FOR - } - - - /** - * testGetSuperClassesCatalogType - */ - @Test - public void testGetSuperClassesCatalogType() { - Class[] expected = { - MockObject3.class, - MockObject2.class, - Object.class, - }; - List> results = ClassUtil.getSuperClasses(MockObject3.class); - assert (!results.isEmpty()); - assertEquals(expected.length, results.size()); - - for (Class e : expected) { - assert (results.contains(e)); - } // FOR - } + public static class MockObject2 { + public MockObject2(MockObject2 x) {} + } - /** - * GetInterfaces - */ - @Test - public void testGetInterfaces() { - Class[] expected = { - Serializable.class, - Cloneable.class, - Iterable.class, - Collection.class, - List.class, - RandomAccess.class, - // New in Java 21: - SequencedCollection.class, - }; - Collection> results = ClassUtil.getInterfaces(target_class); - // System.err.println(target_class + " => " + results); - assert (!results.isEmpty()); - assertEquals(expected.length, results.size()); - - for (Class e : expected) { - assert (results.contains(e)); - } // FOR + public static class MockObject3 extends MockObject2 { + public MockObject3(MockObject2 x) { + super(x); } + } + + /** testGetConstructor */ + @Test + public void testGetConstructor() throws Exception { + Class[] targets = { + MockObject1.class, MockObject2.class, + }; + Class[] params = {MockObject1.class}; + + for (Class targetClass : targets) { + Constructor c = ClassUtil.getConstructor(targetClass, params); + assertNotNull(c); + } // FOR + } + + /** testGetSuperClasses */ + @Test + public void testGetSuperClasses() { + Class[] expected = { + target_class, AbstractList.class, AbstractCollection.class, Object.class, + }; + List> results = ClassUtil.getSuperClasses(target_class); + // System.err.println(target_class + " => " + results); + assert (!results.isEmpty()); + assertEquals(expected.length, results.size()); + + for (Class e : expected) { + assert (results.contains(e)); + } // FOR + } + + /** testGetSuperClassesCatalogType */ + @Test + public void testGetSuperClassesCatalogType() { + Class[] expected = { + MockObject3.class, MockObject2.class, Object.class, + }; + List> results = ClassUtil.getSuperClasses(MockObject3.class); + assert (!results.isEmpty()); + assertEquals(expected.length, results.size()); + + for (Class e : expected) { + assert (results.contains(e)); + } // FOR + } + + /** GetInterfaces */ + @Test + public void testGetInterfaces() { + Class[] expected = { + Serializable.class, + Cloneable.class, + Iterable.class, + Collection.class, + List.class, + RandomAccess.class, + // New in Java 21: + SequencedCollection.class, + }; + Collection> results = ClassUtil.getInterfaces(target_class); + // System.err.println(target_class + " => " + results); + assert (!results.isEmpty()); + assertEquals(expected.length, results.size()); + + for (Class e : expected) { + assert (results.contains(e)); + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java index 7785f3829..08345477b 100644 --- a/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java +++ b/src/test/java/com/oltpbenchmark/util/TestCollectionUtil.java @@ -14,16 +14,14 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.util; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import org.apache.commons.collections4.set.ListOrderedSet; - import java.util.*; +import org.apache.commons.collections4.set.ListOrderedSet; import org.junit.Test; /** @@ -31,113 +29,104 @@ */ public class TestCollectionUtil { - private final Random rand = new Random(); - - /** - * testIterableEnumeration - */ - @Test - public void testIterableEnumeration() { - final int size = 10; - Enumeration e = new Enumeration() { - int ctr = 0; - - @Override - public Integer nextElement() { - return (ctr++); - } - - @Override - public boolean hasMoreElements() { - return (ctr < size); - } + private final Random rand = new Random(); + + /** testIterableEnumeration */ + @Test + public void testIterableEnumeration() { + final int size = 10; + Enumeration e = + new Enumeration() { + int ctr = 0; + + @Override + public Integer nextElement() { + return (ctr++); + } + + @Override + public boolean hasMoreElements() { + return (ctr < size); + } }; - List found = new ArrayList(); - for (Integer i : CollectionUtil.iterable(e.asIterator())) - found.add(i); - assertEquals(size, found.size()); - } - - /** - * testAddAll - */ - @Test - public void testAddAll() { - int cnt = rand.nextInt(50) + 1; - List l = new ArrayList(); - Integer[] a = new Integer[cnt]; - for (int i = 0; i < cnt; i++) { - int next = rand.nextInt(); - l.add(next); - a[i] = next; - } // FOR - - Collection c = CollectionUtil.addAll(new HashSet(), l.iterator()); - assertEquals(l.size(), c.size()); - assert (c.containsAll(l)); - - c = CollectionUtil.addAll(new HashSet(), a); - assertEquals(l.size(), c.size()); - assert (c.containsAll(l)); - } - - /** - * testGetGreatest - */ - @Test - public void testGetGreatest() { - Map map = new HashMap(); - map.put("a", 1); - map.put("b", 2); - map.put("c", 4); - map.put("d", 3); - String key = CollectionUtil.getGreatest(map); - assertEquals("c", key); - } - - /** - * testGetFirst - */ - @Test - public void testGetFirst() { - List list = new ArrayList(); - list.add("a"); - list.add("b"); - list.add("c"); - String key = CollectionUtil.first(list); - assertEquals("a", key); - } - - /** - * testPop - */ - @SuppressWarnings("unchecked") - @Test - public void testPop() { - String[] expected = new String[11]; - RandomGenerator rng = new RandomGenerator(0); - for (int i = 0; i < expected.length; i++) { - expected[i] = rng.astring(1, 32); - } // FOR - - @SuppressWarnings("rawtypes") - Collection[] collections = new Collection[]{ - CollectionUtil.addAll(new ListOrderedSet(), expected), - CollectionUtil.addAll(new HashSet(), expected), - CollectionUtil.addAll(new ArrayList(), expected), + List found = new ArrayList(); + for (Integer i : CollectionUtil.iterable(e.asIterator())) found.add(i); + assertEquals(size, found.size()); + } + + /** testAddAll */ + @Test + public void testAddAll() { + int cnt = rand.nextInt(50) + 1; + List l = new ArrayList(); + Integer[] a = new Integer[cnt]; + for (int i = 0; i < cnt; i++) { + int next = rand.nextInt(); + l.add(next); + a[i] = next; + } // FOR + + Collection c = CollectionUtil.addAll(new HashSet(), l.iterator()); + assertEquals(l.size(), c.size()); + assert (c.containsAll(l)); + + c = CollectionUtil.addAll(new HashSet(), a); + assertEquals(l.size(), c.size()); + assert (c.containsAll(l)); + } + + /** testGetGreatest */ + @Test + public void testGetGreatest() { + Map map = new HashMap(); + map.put("a", 1); + map.put("b", 2); + map.put("c", 4); + map.put("d", 3); + String key = CollectionUtil.getGreatest(map); + assertEquals("c", key); + } + + /** testGetFirst */ + @Test + public void testGetFirst() { + List list = new ArrayList(); + list.add("a"); + list.add("b"); + list.add("c"); + String key = CollectionUtil.first(list); + assertEquals("a", key); + } + + /** testPop */ + @SuppressWarnings("unchecked") + @Test + public void testPop() { + String[] expected = new String[11]; + RandomGenerator rng = new RandomGenerator(0); + for (int i = 0; i < expected.length; i++) { + expected[i] = rng.astring(1, 32); + } // FOR + + @SuppressWarnings("rawtypes") + Collection[] collections = + new Collection[] { + CollectionUtil.addAll(new ListOrderedSet(), expected), + CollectionUtil.addAll(new HashSet(), expected), + CollectionUtil.addAll(new ArrayList(), expected), }; - for (Collection c : collections) { - assertNotNull(c); - assertEquals(c.getClass().getSimpleName(), expected.length, c.size()); - String pop = CollectionUtil.pop(c); - assertNotNull(c.getClass().getSimpleName(), pop); - assertEquals(c.getClass().getSimpleName(), expected.length - 1, c.size()); - assertFalse(c.getClass().getSimpleName(), c.contains(pop)); - - if (c instanceof List || c instanceof ListOrderedSet) { - assertEquals(c.getClass().getSimpleName(), expected[0], pop); - } - } // FOR - } + for (Collection c : collections) { + assertNotNull(c); + assertEquals(c.getClass().getSimpleName(), expected.length, c.size()); + String pop = CollectionUtil.pop(c); + assertNotNull(c.getClass().getSimpleName(), pop); + assertEquals(c.getClass().getSimpleName(), expected.length - 1, c.size()); + assertFalse(c.getClass().getSimpleName(), c.contains(pop)); + + if (c instanceof List || c instanceof ListOrderedSet) { + assertEquals(c.getClass().getSimpleName(), expected[0], pop); + } + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/util/TestCompositeIdRange.java b/src/test/java/com/oltpbenchmark/util/TestCompositeIdRange.java index 2046a845e..0b56a8ae0 100644 --- a/src/test/java/com/oltpbenchmark/util/TestCompositeIdRange.java +++ b/src/test/java/com/oltpbenchmark/util/TestCompositeIdRange.java @@ -14,85 +14,81 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.util; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.util.Objects; - -import static org.junit.Assert.assertEquals; +import org.junit.Test; public class TestCompositeIdRange { - public static class PackedLong extends CompositeId { - private static final int[] COMPOSITE_BITS = { - INT_MAX_DIGITS, // FIELD1 - LONG_MAX_DIGITS, // FIELD2 - }; - - protected int field1; - protected long field2; - - public PackedLong() { - } - - public PackedLong(int field1, long field2) { - this.field1 = field1; - this.field2 = field2; - } - - @Override - public String encode() { - return (this.encode(COMPOSITE_BITS)); - } - - @Override - public void decode(String composite_id) { - String[] values = super.decode(composite_id, COMPOSITE_BITS); - this.field1 = Integer.parseInt(values[0]); - this.field2 = Long.parseLong(values[1]); - } - - @Override - public String[] toArray() { - return (new String[]{Integer.toString(this.field1), Long.toString(this.field2)}); - } - - public int getField1() { - return this.field1; - } - - public long getField2() { - return this.field2; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PackedLong that = (PackedLong) o; - return field1 == that.field1 && field2 == that.field2; - } - - @Override - public int hashCode() { - return Objects.hash(field1, field2); - } + public static class PackedLong extends CompositeId { + private static final int[] COMPOSITE_BITS = { + INT_MAX_DIGITS, // FIELD1 + LONG_MAX_DIGITS, // FIELD2 + }; + + protected int field1; + protected long field2; + + public PackedLong() {} + + public PackedLong(int field1, long field2) { + this.field1 = field1; + this.field2 = field2; + } + + @Override + public String encode() { + return (this.encode(COMPOSITE_BITS)); + } + + @Override + public void decode(String composite_id) { + String[] values = super.decode(composite_id, COMPOSITE_BITS); + this.field1 = Integer.parseInt(values[0]); + this.field2 = Long.parseLong(values[1]); + } + + @Override + public String[] toArray() { + return (new String[] {Integer.toString(this.field1), Long.toString(this.field2)}); } - @Test - public void testPackOK() { - PackedLong packedLong = new PackedLong(1, 2); - String encodedLong = packedLong.encode(); - PackedLong packedLong2 = new PackedLong(); - packedLong2.decode(encodedLong); - assertEquals(packedLong.getField1(), packedLong2.getField1()); - assertEquals(packedLong.getField2(), packedLong2.getField2()); + public int getField1() { + return this.field1; } -} \ No newline at end of file + public long getField2() { + return this.field2; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PackedLong that = (PackedLong) o; + return field1 == that.field1 && field2 == that.field2; + } + + @Override + public int hashCode() { + return Objects.hash(field1, field2); + } + } + + @Test + public void testPackOK() { + PackedLong packedLong = new PackedLong(1, 2); + String encodedLong = packedLong.encode(); + PackedLong packedLong2 = new PackedLong(); + packedLong2.decode(encodedLong); + assertEquals(packedLong.getField1(), packedLong2.getField1()); + assertEquals(packedLong.getField2(), packedLong2.getField2()); + } +} diff --git a/src/test/java/com/oltpbenchmark/util/TestFileUtil.java b/src/test/java/com/oltpbenchmark/util/TestFileUtil.java index c64478e96..83b90fc43 100644 --- a/src/test/java/com/oltpbenchmark/util/TestFileUtil.java +++ b/src/test/java/com/oltpbenchmark/util/TestFileUtil.java @@ -18,54 +18,48 @@ import static org.junit.Assert.assertEquals; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; public class TestFileUtil { - @Before - public void setUp() throws Exception { - } - - @After - public void tearDown() throws Exception { - } + @Before + public void setUp() throws Exception {} - void touch(String name) { - try { - File f = new File(name); - if (!f.exists()) - new FileOutputStream(f).close(); - f.setLastModified(TimeUtil.getCurrentTime().getTime()); - } catch (IOException e) { - } - } + @After + public void tearDown() throws Exception {} - void rm(String name) { - File file = new File(name); - file.delete(); + void touch(String name) { + try { + File f = new File(name); + if (!f.exists()) new FileOutputStream(f).close(); + f.setLastModified(TimeUtil.getCurrentTime().getTime()); + } catch (IOException e) { } + } - @Test - public void testIncrementFileNames() { - - String basename = "base.res"; - assertEquals("base.res", FileUtil.getNextFilename(basename)); - touch("base.res"); - assertEquals("base.1.res", FileUtil.getNextFilename(basename)); - assertEquals("base.1.res", FileUtil.getNextFilename(basename)); - touch("base.1.res"); - assertEquals("base.2.res", FileUtil.getNextFilename(basename)); + void rm(String name) { + File file = new File(name); + file.delete(); + } + @Test + public void testIncrementFileNames() { - rm("base.res"); - rm("base.1.res"); - rm("base.2.res"); - } + String basename = "base.res"; + assertEquals("base.res", FileUtil.getNextFilename(basename)); + touch("base.res"); + assertEquals("base.1.res", FileUtil.getNextFilename(basename)); + assertEquals("base.1.res", FileUtil.getNextFilename(basename)); + touch("base.1.res"); + assertEquals("base.2.res", FileUtil.getNextFilename(basename)); + rm("base.res"); + rm("base.1.res"); + rm("base.2.res"); + } } diff --git a/src/test/java/com/oltpbenchmark/util/TestHistogram.java b/src/test/java/com/oltpbenchmark/util/TestHistogram.java index d1fda345d..9ed089f12 100644 --- a/src/test/java/com/oltpbenchmark/util/TestHistogram.java +++ b/src/test/java/com/oltpbenchmark/util/TestHistogram.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.util; import static org.junit.Assert.assertEquals; @@ -23,265 +22,247 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.lang.reflect.Field; +import java.util.*; import org.json.JSONObject; import org.junit.Before; import org.junit.Test; -import java.lang.reflect.Field; -import java.util.*; - /** * @author pavlo */ public class TestHistogram { - public static final int NUM_PARTITIONS = 100; - public static final int NUM_SAMPLES = 100; - public static final int RANGE = 20; - public static final double SKEW_FACTOR = 4.0; - - private final Histogram h = new Histogram(); - private final Random rand = new Random(1); - - @Before - public void setUp() throws Exception { - // Cluster a bunch in the center - int min = RANGE / 3; - for (int i = 0; i < NUM_SAMPLES; i++) { - h.put((rand.nextInt(min) + min)); - } - for (int i = 0; i < NUM_SAMPLES; i++) { - h.put((rand.nextInt(RANGE))); - } - } - - /** - * testMinMaxCount - */ - @Test - public void testMinMaxCount() throws Exception { - Histogram h = new Histogram(); - int expected = 10; - for (int i = 0; i < 10; i++) { - for (int j = 0; j < expected; j++) h.put(i); - } // FOR - long min_count = h.getMinCount(); - assertEquals(expected, min_count); - long max_count = h.getMaxCount(); - assertEquals(expected, max_count); - - for (int i = 9; i >= 0; i--) { - if (i == 5) continue; - for (int j = 0; j < expected; j++) h.put(i); - } // FOR -// System.err.println(h); - min_count = h.getMinCount(); - assertEquals(expected, min_count); - max_count = h.getMaxCount(); - assertEquals(expected * 2, max_count); - } - - /** - * testMinCountValues - */ - @Test - public void testMinCountValues() throws Exception { - Histogram h = new Histogram(); - long expected = -1981; - h.put(expected); - for (int i = 0; i < 1000; i++) { - h.put((long) 99999); - } // FOR - Collection min_values = h.getMinCountValues(); - assertNotNull(min_values); - assertEquals(1, min_values.size()); - - Long min_value = CollectionUtil.first(min_values); - assertNotNull(min_value); - assertEquals(expected, min_value.longValue()); - - // Test whether we can get both in a set - long expected2 = -99999; - h.put(expected2); - - min_values = h.getMinCountValues(); - assertNotNull(min_values); - assertEquals(2, min_values.size()); - assert (min_values.contains(expected)); - assert (min_values.contains(expected2)); - } - - /** - * testMaxCountValues - */ - @Test - public void testMaxCountValues() throws Exception { - int expected = -1981; - int count = 1000; - for (int i = 0; i < count; i++) { - h.put(expected); - } // FOR - Collection max_values = h.getMaxCountValues(); - assertNotNull(max_values); - assertEquals(1, max_values.size()); - - Integer max_value = CollectionUtil.first(max_values); - assertNotNull(max_value); - assertEquals(expected, max_value.intValue()); - - // Test whether we can get both in a set - int expected2 = -99999; - for (int i = 0; i < count; i++) { - h.put(expected2); - } // FOR - - max_values = h.getMaxCountValues(); - assertNotNull(max_values); - assertEquals(2, max_values.size()); - assert (max_values.contains(expected)); - assert (max_values.contains(expected2)); - } - - /** - * testClearValues - */ - @Test - public void testClearValues() throws Exception { - Set keys = new HashSet(this.h.values()); - - // Make sure that the keys are all still there - h.setKeepZeroEntries(true); - h.clearValues(); - assertEquals(keys.size(), h.getValueCount()); - assertEquals(keys.size(), h.values().size()); - assertEquals(0, h.getSampleCount()); - for (Object o : keys) { - Integer k = (Integer) o; - assertEquals(0, h.get(k).intValue()); - } // FOR - - // Now make sure they get wiped out - h.setKeepZeroEntries(false); - h.clearValues(); - assertEquals(0, h.getValueCount()); - assertEquals(0, h.values().size()); - assertEquals(0, h.getSampleCount()); - for (Object o : keys) { - Integer k = (Integer) o; - assertNull(h.get(k)); - } // FOR - } - - /** - * testZeroEntries - */ - @Test - public void testZeroEntries() { - Set attempted = new HashSet(); - - // First try to add a bunch of zero entries and make sure that they aren't included - // in the list of values stored in the histogram - h.setKeepZeroEntries(false); - assertFalse(h.isZeroEntriesEnabled()); - for (int i = 0; i < NUM_SAMPLES; i++) { - int key = 0; - do { - key = rand.nextInt(); - } while (h.contains(key) || attempted.contains(key)); - h.put(key, 0); - attempted.add(key); - } // FOR - for (Integer key : attempted) { - assertFalse(h.contains(key)); - assertNull(h.get(key)); - } // FOR + public static final int NUM_PARTITIONS = 100; + public static final int NUM_SAMPLES = 100; + public static final int RANGE = 20; + public static final double SKEW_FACTOR = 4.0; - // Now enable zero entries and make sure that our entries make it in there - h.setKeepZeroEntries(true); - assert (h.isZeroEntriesEnabled()); - for (Integer key : attempted) { - h.put(key, 0); - assert (h.contains(key)); - assertEquals(0, h.get(key).longValue()); - } // FOR + private final Histogram h = new Histogram(); + private final Random rand = new Random(1); - // Disable zero entries again and make sure that our entries from the last step are removed - h.setKeepZeroEntries(false); - assertFalse(h.isZeroEntriesEnabled()); - for (Integer key : attempted) { - assertFalse(h.contains(key)); - assertNull(h.get(key)); - } // FOR + @Before + public void setUp() throws Exception { + // Cluster a bunch in the center + int min = RANGE / 3; + for (int i = 0; i < NUM_SAMPLES; i++) { + h.put((rand.nextInt(min) + min)); } - - /** - * testPutValues - */ - @Test - public void testPutValues() { - Histogram hist = new Histogram(); - hist.put(49); - hist.put(50); - - List partitions = new ArrayList(); - for (int i = 0; i < NUM_PARTITIONS; i++) - partitions.add(i); - - hist.putAll(partitions); - assertEquals(partitions.size(), hist.getValueCount()); - assertTrue(hist.values().containsAll(partitions)); - - for (int i : partitions) { - assertNotNull(hist.get(i)); - int cnt = hist.get(i).intValue(); - int expected = (i == 49 || i == 50 ? 2 : 1); - assertEquals(expected, cnt); - } // FOR + for (int i = 0; i < NUM_SAMPLES; i++) { + h.put((rand.nextInt(RANGE))); } - - /** - * testToJSONString - */ - @Test - public void testToJSONString() throws Exception { - String json = h.toJSONString(); - assertNotNull(json); - for (Histogram.Members element : Histogram.Members.values()) { - if (element == Histogram.Members.KEEP_ZERO_ENTRIES) continue; - assertTrue(json.indexOf(element.name()) != -1); + } + + /** testMinMaxCount */ + @Test + public void testMinMaxCount() throws Exception { + Histogram h = new Histogram(); + int expected = 10; + for (int i = 0; i < 10; i++) { + for (int j = 0; j < expected; j++) h.put(i); + } // FOR + long min_count = h.getMinCount(); + assertEquals(expected, min_count); + long max_count = h.getMaxCount(); + assertEquals(expected, max_count); + + for (int i = 9; i >= 0; i--) { + if (i == 5) continue; + for (int j = 0; j < expected; j++) h.put(i); + } // FOR + // System.err.println(h); + min_count = h.getMinCount(); + assertEquals(expected, min_count); + max_count = h.getMaxCount(); + assertEquals(expected * 2, max_count); + } + + /** testMinCountValues */ + @Test + public void testMinCountValues() throws Exception { + Histogram h = new Histogram(); + long expected = -1981; + h.put(expected); + for (int i = 0; i < 1000; i++) { + h.put((long) 99999); + } // FOR + Collection min_values = h.getMinCountValues(); + assertNotNull(min_values); + assertEquals(1, min_values.size()); + + Long min_value = CollectionUtil.first(min_values); + assertNotNull(min_value); + assertEquals(expected, min_value.longValue()); + + // Test whether we can get both in a set + long expected2 = -99999; + h.put(expected2); + + min_values = h.getMinCountValues(); + assertNotNull(min_values); + assertEquals(2, min_values.size()); + assert (min_values.contains(expected)); + assert (min_values.contains(expected2)); + } + + /** testMaxCountValues */ + @Test + public void testMaxCountValues() throws Exception { + int expected = -1981; + int count = 1000; + for (int i = 0; i < count; i++) { + h.put(expected); + } // FOR + Collection max_values = h.getMaxCountValues(); + assertNotNull(max_values); + assertEquals(1, max_values.size()); + + Integer max_value = CollectionUtil.first(max_values); + assertNotNull(max_value); + assertEquals(expected, max_value.intValue()); + + // Test whether we can get both in a set + int expected2 = -99999; + for (int i = 0; i < count; i++) { + h.put(expected2); + } // FOR + + max_values = h.getMaxCountValues(); + assertNotNull(max_values); + assertEquals(2, max_values.size()); + assert (max_values.contains(expected)); + assert (max_values.contains(expected2)); + } + + /** testClearValues */ + @Test + public void testClearValues() throws Exception { + Set keys = new HashSet(this.h.values()); + + // Make sure that the keys are all still there + h.setKeepZeroEntries(true); + h.clearValues(); + assertEquals(keys.size(), h.getValueCount()); + assertEquals(keys.size(), h.values().size()); + assertEquals(0, h.getSampleCount()); + for (Object o : keys) { + Integer k = (Integer) o; + assertEquals(0, h.get(k).intValue()); + } // FOR + + // Now make sure they get wiped out + h.setKeepZeroEntries(false); + h.clearValues(); + assertEquals(0, h.getValueCount()); + assertEquals(0, h.values().size()); + assertEquals(0, h.getSampleCount()); + for (Object o : keys) { + Integer k = (Integer) o; + assertNull(h.get(k)); + } // FOR + } + + /** testZeroEntries */ + @Test + public void testZeroEntries() { + Set attempted = new HashSet(); + + // First try to add a bunch of zero entries and make sure that they aren't included + // in the list of values stored in the histogram + h.setKeepZeroEntries(false); + assertFalse(h.isZeroEntriesEnabled()); + for (int i = 0; i < NUM_SAMPLES; i++) { + int key = 0; + do { + key = rand.nextInt(); + } while (h.contains(key) || attempted.contains(key)); + h.put(key, 0); + attempted.add(key); + } // FOR + for (Integer key : attempted) { + assertFalse(h.contains(key)); + assertNull(h.get(key)); + } // FOR + + // Now enable zero entries and make sure that our entries make it in there + h.setKeepZeroEntries(true); + assert (h.isZeroEntriesEnabled()); + for (Integer key : attempted) { + h.put(key, 0); + assert (h.contains(key)); + assertEquals(0, h.get(key).longValue()); + } // FOR + + // Disable zero entries again and make sure that our entries from the last step are removed + h.setKeepZeroEntries(false); + assertFalse(h.isZeroEntriesEnabled()); + for (Integer key : attempted) { + assertFalse(h.contains(key)); + assertNull(h.get(key)); + } // FOR + } + + /** testPutValues */ + @Test + public void testPutValues() { + Histogram hist = new Histogram(); + hist.put(49); + hist.put(50); + + List partitions = new ArrayList(); + for (int i = 0; i < NUM_PARTITIONS; i++) partitions.add(i); + + hist.putAll(partitions); + assertEquals(partitions.size(), hist.getValueCount()); + assertTrue(hist.values().containsAll(partitions)); + + for (int i : partitions) { + assertNotNull(hist.get(i)); + int cnt = hist.get(i).intValue(); + int expected = (i == 49 || i == 50 ? 2 : 1); + assertEquals(expected, cnt); + } // FOR + } + + /** testToJSONString */ + @Test + public void testToJSONString() throws Exception { + String json = h.toJSONString(); + assertNotNull(json); + for (Histogram.Members element : Histogram.Members.values()) { + if (element == Histogram.Members.KEEP_ZERO_ENTRIES) continue; + assertTrue(json.indexOf(element.name()) != -1); + } // FOR + } + + /** testFromJSON */ + @Test + public void testFromJSON() throws Exception { + String json = h.toJSONString(); + assertNotNull(json); + JSONObject jsonObject = new JSONObject(json); + // System.err.println(jsonObject.toString(1)); + + Histogram copy = new Histogram(); + copy.fromJSON(jsonObject); + assertEquals(h.getValueCount(), copy.getValueCount()); + for (Histogram.Members element : Histogram.Members.values()) { + if (element == Histogram.Members.VALUE_TYPE) continue; + String field_name = element.toString().toLowerCase(); + Field field = Histogram.class.getDeclaredField(field_name); + assertNotNull(field); + + Object orig_value = field.get(h); + Object copy_value = field.get(copy); + + if (element == Histogram.Members.HISTOGRAM) { + for (Integer value : h.values()) { + assertNotNull(value); + assertEquals(h.get(value), copy.get(value)); } // FOR - } - - /** - * testFromJSON - */ - @Test - public void testFromJSON() throws Exception { - String json = h.toJSONString(); - assertNotNull(json); - JSONObject jsonObject = new JSONObject(json); -// System.err.println(jsonObject.toString(1)); - - Histogram copy = new Histogram(); - copy.fromJSON(jsonObject); - assertEquals(h.getValueCount(), copy.getValueCount()); - for (Histogram.Members element : Histogram.Members.values()) { - if (element == Histogram.Members.VALUE_TYPE) continue; - String field_name = element.toString().toLowerCase(); - Field field = Histogram.class.getDeclaredField(field_name); - assertNotNull(field); - - Object orig_value = field.get(h); - Object copy_value = field.get(copy); - - if (element == Histogram.Members.HISTOGRAM) { - for (Integer value : h.values()) { - assertNotNull(value); - assertEquals(h.get(value), copy.get(value)); - } // FOR - } else { - assertEquals(orig_value.toString(), copy_value.toString()); - } - } // FOR - } + } else { + assertEquals(orig_value.toString(), copy_value.toString()); + } + } // FOR + } } diff --git a/src/test/java/com/oltpbenchmark/util/TestRandomDistribution.java b/src/test/java/com/oltpbenchmark/util/TestRandomDistribution.java index 89720e169..8018e7c2c 100644 --- a/src/test/java/com/oltpbenchmark/util/TestRandomDistribution.java +++ b/src/test/java/com/oltpbenchmark/util/TestRandomDistribution.java @@ -14,7 +14,6 @@ * limitations under the License. * ******************************************************************************/ - package com.oltpbenchmark.util; import static org.junit.Assert.assertEquals; @@ -25,164 +24,152 @@ public class TestRandomDistribution { - private final Random rand = new Random(0); - - private final int min = 0; - private final int max = 20; - - private final int num_records = 100000; - private final int num_rounds = 10; - - /** - * testCalculateMean - */ - @Test - public void testCalculateMean() throws Exception { - final int expected = ((max - min) / 2) + min; - final int samples = 10000; - - RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); - double mean = gaussian.calculateMean(samples); -// System.err.println("mean="+ mean); - assert ((expected - 1) <= mean) : (expected - 1) + " <= " + mean; - assert ((expected + 1) >= mean) : (expected - 1) + " >= " + mean; - } - - /** - * testHistory - */ - @Test - public void testHistory() throws Exception { - double sigma = 1.0000001d; - RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, sigma); - zipf.enableHistory(); - - Histogram hist = new Histogram(); - for (int i = 0; i < num_records; i++) { - hist.put((long) zipf.nextInt()); - } // FOR - - Histogram tracking_hist = zipf.getHistory(); - assertEquals(hist.getSampleCount(), tracking_hist.getSampleCount()); - for (Long value : hist.values()) { - assert (tracking_hist.contains(value)); - assertEquals(hist.get(value), tracking_hist.get(value)); - } // FOR - } - - /** - * testGaussianInt - */ - @Test - public void testGaussian() throws Exception { - int expected = ((max - min) / 2) + min; - - int round = num_rounds; - while (round-- > 0) { - RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); - Histogram hist = new Histogram(); - for (int i = 0; i < num_records; i++) { - int value = gaussian.nextInt(); - // double value = rand.nextGaussian(); - hist.put(value); - } // FOR - // System.out.println(hist); - int max_count_value = CollectionUtil.first(hist.getMaxCountValues()); - // System.out.println("expected=" + expected + ", max_count_value=" + max_count_value); - assertTrue((expected - 1) <= max_count_value); - assertTrue((expected + 1) >= max_count_value); - } // WHILE - } - - /** - * testGaussianLong - */ - @Test - public void testGaussianLong() throws Exception { - int expected = ((max - min) / 2) + min; - - int round = num_rounds; - while (round-- > 0) { - RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); - Histogram hist = new Histogram(); - for (int i = 0; i < num_records; i++) { - long value = gaussian.nextLong(); - // double value = rand.nextGaussian(); - hist.put(value); - } // FOR - // System.out.println(hist); - Long max_count_value = CollectionUtil.first(hist.getMaxCountValues()); - // System.out.println("expected=" + expected + ", max_count_value=" + max_count_value); - assertTrue((expected - 1) <= max_count_value); - assertTrue((expected + 1) >= max_count_value); - } // WHILE - } - - /** - * testZipfian - */ - @Test - public void testZipfian() throws Exception { - double sigma = 1.0000001d; - - int round = num_rounds; - while (round-- > 0) { - RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, sigma); - Histogram hist = new Histogram(); - // System.out.println("Round #" + Math.abs(num_rounds - 10) + " [sigma=" + sigma + "]"); - for (int i = 0; i < num_records; i++) { - int value = zipf.nextInt(); - hist.put(value); - } // FOR - Long last = null; - for (Integer value : hist.values()) { - long current = hist.get(value); - if (last != null) { - // assertTrue(last >= current); - } - last = current; - } -// System.out.println(hist); -// System.out.println("----------------------------------------------"); - sigma += 0.5d; - } // FOR - } - - /** - * testFlatHistogramInt - */ - @Test - public void testFlatHistogramInt() throws Exception { - Histogram hist = new Histogram(); - RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, 1.0000001d); - for (int i = 0; i < num_records; i++) { - hist.put(zipf.nextInt()); - } // FOR - - RandomDistribution.FlatHistogram flat = new RandomDistribution.FlatHistogram(this.rand, hist); - Histogram hist2 = new Histogram(); - for (int i = 0; i < num_records; i++) { - hist2.put(flat.nextInt()); - } // FOR - assertEquals(hist.getMaxCountValues(), hist2.getMaxCountValues()); - } - - /** - * testFlatHistogramLong - */ - @Test - public void testFlatHistogramLong() throws Exception { - Histogram hist = new Histogram(); - RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, 1.0000001d); - for (int i = 0; i < num_records; i++) { - hist.put(zipf.nextLong()); - } // FOR - - RandomDistribution.FlatHistogram flat = new RandomDistribution.FlatHistogram(this.rand, hist); - Histogram hist2 = new Histogram(); - for (int i = 0; i < num_records; i++) { - hist2.put(flat.nextLong()); - } // FOR - assertEquals(hist.getMaxCountValues(), hist2.getMaxCountValues()); - } -} \ No newline at end of file + private final Random rand = new Random(0); + + private final int min = 0; + private final int max = 20; + + private final int num_records = 100000; + private final int num_rounds = 10; + + /** testCalculateMean */ + @Test + public void testCalculateMean() throws Exception { + final int expected = ((max - min) / 2) + min; + final int samples = 10000; + + RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); + double mean = gaussian.calculateMean(samples); + // System.err.println("mean="+ mean); + assert ((expected - 1) <= mean) : (expected - 1) + " <= " + mean; + assert ((expected + 1) >= mean) : (expected - 1) + " >= " + mean; + } + + /** testHistory */ + @Test + public void testHistory() throws Exception { + double sigma = 1.0000001d; + RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, sigma); + zipf.enableHistory(); + + Histogram hist = new Histogram(); + for (int i = 0; i < num_records; i++) { + hist.put((long) zipf.nextInt()); + } // FOR + + Histogram tracking_hist = zipf.getHistory(); + assertEquals(hist.getSampleCount(), tracking_hist.getSampleCount()); + for (Long value : hist.values()) { + assert (tracking_hist.contains(value)); + assertEquals(hist.get(value), tracking_hist.get(value)); + } // FOR + } + + /** testGaussianInt */ + @Test + public void testGaussian() throws Exception { + int expected = ((max - min) / 2) + min; + + int round = num_rounds; + while (round-- > 0) { + RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); + Histogram hist = new Histogram(); + for (int i = 0; i < num_records; i++) { + int value = gaussian.nextInt(); + // double value = rand.nextGaussian(); + hist.put(value); + } // FOR + // System.out.println(hist); + int max_count_value = CollectionUtil.first(hist.getMaxCountValues()); + // System.out.println("expected=" + expected + ", max_count_value=" + max_count_value); + assertTrue((expected - 1) <= max_count_value); + assertTrue((expected + 1) >= max_count_value); + } // WHILE + } + + /** testGaussianLong */ + @Test + public void testGaussianLong() throws Exception { + int expected = ((max - min) / 2) + min; + + int round = num_rounds; + while (round-- > 0) { + RandomDistribution.Gaussian gaussian = new RandomDistribution.Gaussian(this.rand, min, max); + Histogram hist = new Histogram(); + for (int i = 0; i < num_records; i++) { + long value = gaussian.nextLong(); + // double value = rand.nextGaussian(); + hist.put(value); + } // FOR + // System.out.println(hist); + Long max_count_value = CollectionUtil.first(hist.getMaxCountValues()); + // System.out.println("expected=" + expected + ", max_count_value=" + max_count_value); + assertTrue((expected - 1) <= max_count_value); + assertTrue((expected + 1) >= max_count_value); + } // WHILE + } + + /** testZipfian */ + @Test + public void testZipfian() throws Exception { + double sigma = 1.0000001d; + + int round = num_rounds; + while (round-- > 0) { + RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, sigma); + Histogram hist = new Histogram(); + // System.out.println("Round #" + Math.abs(num_rounds - 10) + " [sigma=" + sigma + "]"); + for (int i = 0; i < num_records; i++) { + int value = zipf.nextInt(); + hist.put(value); + } // FOR + Long last = null; + for (Integer value : hist.values()) { + long current = hist.get(value); + if (last != null) { + // assertTrue(last >= current); + } + last = current; + } + // System.out.println(hist); + // System.out.println("----------------------------------------------"); + sigma += 0.5d; + } // FOR + } + + /** testFlatHistogramInt */ + @Test + public void testFlatHistogramInt() throws Exception { + Histogram hist = new Histogram(); + RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, 1.0000001d); + for (int i = 0; i < num_records; i++) { + hist.put(zipf.nextInt()); + } // FOR + + RandomDistribution.FlatHistogram flat = + new RandomDistribution.FlatHistogram(this.rand, hist); + Histogram hist2 = new Histogram(); + for (int i = 0; i < num_records; i++) { + hist2.put(flat.nextInt()); + } // FOR + assertEquals(hist.getMaxCountValues(), hist2.getMaxCountValues()); + } + + /** testFlatHistogramLong */ + @Test + public void testFlatHistogramLong() throws Exception { + Histogram hist = new Histogram(); + RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, min, max, 1.0000001d); + for (int i = 0; i < num_records; i++) { + hist.put(zipf.nextLong()); + } // FOR + + RandomDistribution.FlatHistogram flat = + new RandomDistribution.FlatHistogram(this.rand, hist); + Histogram hist2 = new Histogram(); + for (int i = 0; i < num_records; i++) { + hist2.put(flat.nextLong()); + } // FOR + assertEquals(hist.getMaxCountValues(), hist2.getMaxCountValues()); + } +} diff --git a/src/test/java/com/oltpbenchmark/util/TestTextGenerator.java b/src/test/java/com/oltpbenchmark/util/TestTextGenerator.java index e4d27b1a0..5db7015f6 100644 --- a/src/test/java/com/oltpbenchmark/util/TestTextGenerator.java +++ b/src/test/java/com/oltpbenchmark/util/TestTextGenerator.java @@ -26,108 +26,95 @@ public class TestTextGenerator { - final Random rng = new Random(); - final int MAX_SIZE = 2048; - final int NUM_ROUNDS = 10000; - - /** - * testRandomChars - */ - @Test - public void testRandomChars() throws Exception { - int strLen = rng.nextInt(MAX_SIZE) + 10; - for (int i = 0; i < NUM_ROUNDS; i++) { - // Make sure that the random strings are not null and - // the length that they are supposed to be. - char[] text = TextGenerator.randomChars(rng, strLen); - assertNotNull(text); - assertEquals(strLen, text.length); - } // FOR - } - - /** - * testRandomCharsPrealloc - */ - @Test - public void testRandomCharsPrealloc() throws Exception { - int strLen = rng.nextInt(MAX_SIZE); - char[] text = new char[strLen]; - for (int i = 0; i < NUM_ROUNDS; i++) { - TextGenerator.randomChars(rng, text); - assertNotNull(text); - assertEquals(strLen, text.length); - } // FOR - } - - /** - * testFastRandomChars - */ - @Test - public void testFastRandomChars() throws Exception { - for (int i = 0; i < NUM_ROUNDS; i++) { - int strLen = rng.nextInt(MAX_SIZE) + 10; - char[] text = new char[strLen]; - TextGenerator.randomFastChars(rng, text); - assertNotNull(text); - assertEquals(strLen, text.length); - } // FOR - } - - /** - * testIncreaseText - */ - @Test - public void testIncreaseText() throws Exception { - int strLen = rng.nextInt(2048); - char[] text = TextGenerator.randomChars(rng, strLen); - assertNotNull(text); - - int delta = rng.nextInt(2048); - char[] newText = TextGenerator.resizeText(rng, text, delta); - assertEquals(text.length + delta, newText.length); - - // Make sure the first portion is the same - for (int i = 0; i < text.length; i++) { - assertEquals(text[i], newText[i]); - } // FOR - } - - /** - * testDecreaseText - */ - @Test - public void testDecreaseText() throws Exception { - // Make sure that the original length is always greater than the delta size - int strLen = rng.nextInt(2048) + 200; - char[] text = TextGenerator.randomChars(rng, strLen); - assertNotNull(text); - - int delta = -1 * rng.nextInt(100); - char[] newText = TextGenerator.resizeText(rng, text, delta); - assertEquals(text.length + delta, newText.length); - } - - /** - * testPermuteText - */ - @Test - public void testPermuteText() throws Exception { - int strLen = 64; // rng.nextInt(64); - char[] orig = TextGenerator.randomChars(rng, strLen); - assertNotNull(orig); - - // Permute it and make sure at least one block is changed - char[] newText = TextGenerator.permuteText(rng, Arrays.copyOf(orig, strLen)); - assertEquals(orig.length, newText.length); - - boolean valid = false; - for (int i = 0; i < newText.length; i++) { - if (orig[i] != newText[i]) { - valid = true; - break; - } - } // FOR - assertTrue(valid); - } - + final Random rng = new Random(); + final int MAX_SIZE = 2048; + final int NUM_ROUNDS = 10000; + + /** testRandomChars */ + @Test + public void testRandomChars() throws Exception { + int strLen = rng.nextInt(MAX_SIZE) + 10; + for (int i = 0; i < NUM_ROUNDS; i++) { + // Make sure that the random strings are not null and + // the length that they are supposed to be. + char[] text = TextGenerator.randomChars(rng, strLen); + assertNotNull(text); + assertEquals(strLen, text.length); + } // FOR + } + + /** testRandomCharsPrealloc */ + @Test + public void testRandomCharsPrealloc() throws Exception { + int strLen = rng.nextInt(MAX_SIZE); + char[] text = new char[strLen]; + for (int i = 0; i < NUM_ROUNDS; i++) { + TextGenerator.randomChars(rng, text); + assertNotNull(text); + assertEquals(strLen, text.length); + } // FOR + } + + /** testFastRandomChars */ + @Test + public void testFastRandomChars() throws Exception { + for (int i = 0; i < NUM_ROUNDS; i++) { + int strLen = rng.nextInt(MAX_SIZE) + 10; + char[] text = new char[strLen]; + TextGenerator.randomFastChars(rng, text); + assertNotNull(text); + assertEquals(strLen, text.length); + } // FOR + } + + /** testIncreaseText */ + @Test + public void testIncreaseText() throws Exception { + int strLen = rng.nextInt(2048); + char[] text = TextGenerator.randomChars(rng, strLen); + assertNotNull(text); + + int delta = rng.nextInt(2048); + char[] newText = TextGenerator.resizeText(rng, text, delta); + assertEquals(text.length + delta, newText.length); + + // Make sure the first portion is the same + for (int i = 0; i < text.length; i++) { + assertEquals(text[i], newText[i]); + } // FOR + } + + /** testDecreaseText */ + @Test + public void testDecreaseText() throws Exception { + // Make sure that the original length is always greater than the delta size + int strLen = rng.nextInt(2048) + 200; + char[] text = TextGenerator.randomChars(rng, strLen); + assertNotNull(text); + + int delta = -1 * rng.nextInt(100); + char[] newText = TextGenerator.resizeText(rng, text, delta); + assertEquals(text.length + delta, newText.length); + } + + /** testPermuteText */ + @Test + public void testPermuteText() throws Exception { + int strLen = 64; // rng.nextInt(64); + char[] orig = TextGenerator.randomChars(rng, strLen); + assertNotNull(orig); + + // Permute it and make sure at least one block is changed + char[] newText = TextGenerator.permuteText(rng, Arrays.copyOf(orig, strLen)); + assertEquals(orig.length, newText.length); + + boolean valid = false; + for (int i = 0; i < newText.length; i++) { + if (orig[i] != newText[i]) { + valid = true; + break; + } + } // FOR + assertTrue(valid); + } }