├── .gitignore ├── README.md ├── database ├── add_fkey_idx.sql ├── create_tables.sql └── load_data.sql ├── pom.xml ├── src └── main │ ├── java │ └── com │ │ └── codefutures │ │ └── tpcc │ │ ├── AbortedTransactionException.java │ │ ├── Counter.java │ │ ├── Delivery.java │ │ ├── Driver.java │ │ ├── Load.java │ │ ├── NamedThreadFactory.java │ │ ├── NewOrder.java │ │ ├── OrderStat.java │ │ ├── Payment.java │ │ ├── RtHist.java │ │ ├── Slev.java │ │ ├── Tpcc.java │ │ ├── TpccConstants.java │ │ ├── TpccLoad.java │ │ ├── TpccLoadConfig.java │ │ ├── TpccStatements.java │ │ ├── TpccThread.java │ │ ├── Util.java │ │ └── load │ │ ├── FileLoader.java │ │ ├── JdbcPreparedStatementLoader.java │ │ ├── JdbcStatementLoader.java │ │ ├── Record.java │ │ └── RecordLoader.java │ └── resources │ └── log4j2.xml └── tpcc.properties /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .idea 3 | *.iml 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Java TPC-C 2 | ========== 3 | 4 | This project is a Java implementation of the TPC-C benchmark. 5 | 6 | ========= 7 | Compiling 8 | ========= 9 | 10 | Use this command to compile the code and produce a fat jar. 11 | 12 | ``` 13 | mvn package assembly:single 14 | ``` 15 | 16 | ======== 17 | Database 18 | ======== 19 | 20 | To create the tpcc schema in MySQL: 21 | 22 | ``` 23 | cd database 24 | mysql -u root 25 | > create database tpcc; 26 | > use tpcc; 27 | > source create_tables.sql 28 | > source add_fkey_idx.sql 29 | ``` 30 | 31 | It is possible to load data without the foreign keys and indexes in place and then add those 32 | after loading data to improve loading times. 33 | 34 | ================================= 35 | Generating and loading TPC-C data 36 | ================================= 37 | 38 | Data can be loaded directly into a MySQL instance and can also be generated to CSV files that 39 | can be loaded into MySQL later using LOAD DATA INFILE. 40 | 41 | In `tpcc.properties` set the MODE to either CSV or JDBC. 42 | 43 | To run the load process: 44 | 45 | ``` 46 | java -classpath target/tpcc-1.0.0-SNAPSHOT-jar-with-dependencies.jar com.codefutures.tpcc.TpccLoad 47 | ``` 48 | 49 | It is possible to load data into shards where the warehouse ID is used as a shard key. The 50 | SHARDCOUNT and SHARDID properties must be set correctly when generating or loading data. 51 | 52 | This option requires the use of a JDBC driver that supports automatic sharding, such as 53 | dbShards (http://www.dbshards.com). 54 | 55 | =========================== 56 | Running the TPC-C Benchmark 57 | =========================== 58 | 59 | Review the TPC-C settings in `tpcc.properties`, then run this command To run the tpcc benchmarks: 60 | 61 | ``` 62 | java -classpath target/tpcc-1.0.0-SNAPSHOT-jar-with-dependencies.jar com.codefutures.tpcc.Tpcc 63 | ``` 64 | 65 | Bugs can be reported to support@codefutures.com. 66 | 67 | (c) 2014 CodeFutures Corporation. 68 | -------------------------------------------------------------------------------- /database/add_fkey_idx.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 2 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 3 | 4 | CREATE INDEX idx_customer ON customer (c_w_id,c_d_id,c_last,c_first); 5 | CREATE INDEX idx_orders ON orders (o_w_id,o_d_id,o_c_id,o_id); 6 | CREATE INDEX fkey_stock_2 ON stock (s_i_id); 7 | CREATE INDEX fkey_order_line_2 ON order_line (ol_supply_w_id,ol_i_id); 8 | 9 | ALTER TABLE district ADD CONSTRAINT fkey_district_1 FOREIGN KEY(d_w_id) REFERENCES warehouse(w_id); 10 | ALTER TABLE customer ADD CONSTRAINT fkey_customer_1 FOREIGN KEY(c_w_id,c_d_id) REFERENCES district(d_w_id,d_id); 11 | ALTER TABLE history ADD CONSTRAINT fkey_history_2 FOREIGN KEY(h_w_id,h_d_id) REFERENCES district(d_w_id,d_id); 12 | ALTER TABLE new_orders ADD CONSTRAINT fkey_new_orders_1 FOREIGN KEY(no_w_id,no_d_id,no_o_id) REFERENCES orders(o_w_id,o_d_id,o_id); 13 | ALTER TABLE orders ADD CONSTRAINT fkey_orders_1 FOREIGN KEY(o_w_id,o_d_id,o_c_id) REFERENCES customer(c_w_id,c_d_id,c_id); 14 | ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_1 FOREIGN KEY(ol_w_id,ol_d_id,ol_o_id) REFERENCES orders(o_w_id,o_d_id,o_id); 15 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_1 FOREIGN KEY(s_w_id) REFERENCES warehouse(w_id); 16 | ALTER TABLE stock ADD CONSTRAINT fkey_stock_2 FOREIGN KEY(s_i_id) REFERENCES item(i_id); 17 | 18 | 19 | #NOTE: the following FKs are not shard-safe since they can reference a warehouse in another shard 20 | #ALTER TABLE order_line ADD CONSTRAINT fkey_order_line_2 FOREIGN KEY(ol_supply_w_id,ol_i_id) REFERENCES stock(s_w_id,s_i_id); 21 | #ALTER TABLE history ADD CONSTRAINT fkey_history_1 FOREIGN KEY(h_c_w_id,h_c_d_id,h_c_id) REFERENCES customer(c_w_id,c_d_id,c_id); 22 | 23 | 24 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 25 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 26 | -------------------------------------------------------------------------------- /database/create_tables.sql: -------------------------------------------------------------------------------- 1 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 2 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 3 | 4 | drop table if exists warehouse; 5 | 6 | create table warehouse ( 7 | w_id smallint not null, 8 | w_name varchar(10), 9 | w_street_1 varchar(20), 10 | w_street_2 varchar(20), 11 | w_city varchar(20), 12 | w_state char(2), 13 | w_zip char(9), 14 | w_tax decimal(4,2), 15 | w_ytd decimal(12,2), 16 | primary key (w_id) ) Engine=InnoDB; 17 | 18 | drop table if exists district; 19 | 20 | create table district ( 21 | d_id tinyint not null, 22 | d_w_id smallint not null, 23 | d_name varchar(10), 24 | d_street_1 varchar(20), 25 | d_street_2 varchar(20), 26 | d_city varchar(20), 27 | d_state char(2), 28 | d_zip char(9), 29 | d_tax decimal(4,2), 30 | d_ytd decimal(12,2), 31 | d_next_o_id int, 32 | primary key (d_w_id, d_id) ) Engine=InnoDB; 33 | 34 | drop table if exists customer; 35 | 36 | create table customer ( 37 | c_id int not null, 38 | c_d_id tinyint not null, 39 | c_w_id smallint not null, 40 | c_first varchar(16), 41 | c_middle char(2), 42 | c_last varchar(16), 43 | c_street_1 varchar(20), 44 | c_street_2 varchar(20), 45 | c_city varchar(20), 46 | c_state char(2), 47 | c_zip char(9), 48 | c_phone char(16), 49 | c_since datetime, 50 | c_credit char(2), 51 | c_credit_lim bigint, 52 | c_discount decimal(4,2), 53 | c_balance decimal(12,2), 54 | c_ytd_payment decimal(12,2), 55 | c_payment_cnt smallint, 56 | c_delivery_cnt smallint, 57 | c_data text, 58 | PRIMARY KEY(c_w_id, c_d_id, c_id) ) Engine=InnoDB; 59 | 60 | drop table if exists history; 61 | 62 | create table history ( 63 | h_c_id int, 64 | h_c_d_id tinyint, 65 | h_c_w_id smallint, 66 | h_d_id tinyint, 67 | h_w_id smallint, 68 | h_date datetime, 69 | h_amount decimal(6,2), 70 | h_data varchar(24) ) Engine=InnoDB; 71 | 72 | drop table if exists new_orders; 73 | 74 | create table new_orders ( 75 | no_o_id int not null, 76 | no_d_id tinyint not null, 77 | no_w_id smallint not null, 78 | PRIMARY KEY(no_w_id, no_d_id, no_o_id)) Engine=InnoDB; 79 | 80 | drop table if exists orders; 81 | 82 | create table orders ( 83 | o_id int not null, 84 | o_d_id tinyint not null, 85 | o_w_id smallint not null, 86 | o_c_id int, 87 | o_entry_d datetime, 88 | o_carrier_id tinyint, 89 | o_ol_cnt tinyint, 90 | o_all_local tinyint, 91 | PRIMARY KEY(o_w_id, o_d_id, o_id) ) Engine=InnoDB ; 92 | 93 | drop table if exists order_line; 94 | 95 | create table order_line ( 96 | ol_o_id int not null, 97 | ol_d_id tinyint not null, 98 | ol_w_id smallint not null, 99 | ol_number tinyint not null, 100 | ol_i_id int, 101 | ol_supply_w_id smallint, 102 | ol_delivery_d datetime, 103 | ol_quantity tinyint, 104 | ol_amount decimal(6,2), 105 | ol_dist_info char(24), 106 | PRIMARY KEY(ol_w_id, ol_d_id, ol_o_id, ol_number) ) Engine=InnoDB ; 107 | 108 | drop table if exists item; 109 | 110 | create table item ( 111 | i_id int not null, 112 | i_im_id int, 113 | i_name varchar(24), 114 | i_price decimal(5,2), 115 | i_data varchar(50), 116 | PRIMARY KEY(i_id) ) Engine=InnoDB; 117 | 118 | drop table if exists stock; 119 | 120 | create table stock ( 121 | s_i_id int not null, 122 | s_w_id smallint not null, 123 | s_quantity smallint, 124 | s_dist_01 char(24), 125 | s_dist_02 char(24), 126 | s_dist_03 char(24), 127 | s_dist_04 char(24), 128 | s_dist_05 char(24), 129 | s_dist_06 char(24), 130 | s_dist_07 char(24), 131 | s_dist_08 char(24), 132 | s_dist_09 char(24), 133 | s_dist_10 char(24), 134 | s_ytd decimal(8,0), 135 | s_order_cnt smallint, 136 | s_remote_cnt smallint, 137 | s_data varchar(50), 138 | PRIMARY KEY(s_w_id, s_i_id) ) Engine=InnoDB ; 139 | 140 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS; 141 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS; 142 | 143 | -------------------------------------------------------------------------------- /database/load_data.sql: -------------------------------------------------------------------------------- 1 | LOAD DATA INFILE 'warehouse.txt' INTO TABLE warehouse; 2 | LOAD DATA INFILE 'district.txt' INTO TABLE district; 3 | LOAD DATA INFILE 'customer.txt' INTO TABLE customer; 4 | LOAD DATA INFILE 'history.txt' INTO TABLE history; 5 | LOAD DATA INFILE 'orders.txt' INTO TABLE orders; 6 | LOAD DATA INFILE 'new_orders.txt' INTO TABLE new_orders; 7 | LOAD DATA INFILE 'order_line.txt' INTO TABLE order_line; 8 | LOAD DATA INFILE 'item.txt' INTO TABLE item; 9 | LOAD DATA INFILE 'stock.txt' INTO TABLE stock; 10 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.codefutures 8 | tpcc 9 | tpcc 10 | 1.0.0-SNAPSHOT 11 | jar 12 | 13 | 14 | 15 | Apache License 2.0 16 | http://www.apache.org/licenses/LICENSE-2.0 17 | 18 | 19 | 20 | 21 | CodeFutures 22 | http://www.codefutures.com 23 | 24 | 25 | 26 | 27 | 28 | mysql 29 | mysql-connector-java 30 | 6.0.4 31 | 32 | 33 | 34 | org.slf4j 35 | slf4j-api 36 | 1.7.7 37 | 38 | 39 | 40 | org.apache.logging.log4j 41 | log4j-api 42 | 2.0.2 43 | 44 | 45 | 46 | org.apache.logging.log4j 47 | log4j-core 48 | 2.0.2 49 | 50 | 51 | 52 | org.apache.logging.log4j 53 | log4j-slf4j-impl 54 | 2.0.2 55 | 56 | 57 | 58 | commons-cli 59 | commons-cli 60 | 1.2 61 | 62 | 63 | 64 | 65 | 66 | junit 67 | junit 68 | 4.8.2 69 | test 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | org.apache.maven.plugins 80 | maven-compiler-plugin 81 | 82 | 1.8 83 | 1.8 84 | 85 | 86 | 87 | 88 | maven-assembly-plugin 89 | 90 | 91 | package 92 | 93 | single 94 | 95 | 96 | 97 | 98 | 99 | jar-with-dependencies 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/AbortedTransactionException.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | public class AbortedTransactionException extends Exception { 4 | public AbortedTransactionException() { 5 | super(); 6 | } 7 | 8 | public AbortedTransactionException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Counter.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | public class Counter { 4 | 5 | private long count = 0; 6 | 7 | public Counter() { 8 | } 9 | 10 | public synchronized long increment() { 11 | return ++count; 12 | } 13 | 14 | public synchronized long get() { 15 | return count; 16 | } 17 | 18 | public synchronized long reset() { 19 | long ret = count; 20 | count = 0; 21 | return ret; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Delivery.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.*; 4 | import java.util.Calendar; 5 | import java.util.Date; 6 | 7 | import org.slf4j.LoggerFactory; 8 | import org.slf4j.Logger; 9 | 10 | public class Delivery implements TpccConstants { 11 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 12 | private static final boolean DEBUG = logger.isDebugEnabled(); 13 | private static final boolean TRACE = logger.isTraceEnabled(); 14 | 15 | private TpccStatements pStmts; 16 | 17 | public Delivery(TpccStatements pStmts) { 18 | this.pStmts = pStmts; 19 | } 20 | 21 | public int delivery(int w_id_arg, int o_carrier_id_arg) { 22 | try { 23 | // Start a transaction. 24 | pStmts.setAutoCommit(false); 25 | if (DEBUG) logger.debug("Transaction: Delivery"); 26 | int w_id = w_id_arg; 27 | int o_carrier_id = o_carrier_id_arg; 28 | int d_id = 0; 29 | int c_id = 0; 30 | int no_o_id = 0; 31 | float ol_total = 0; 32 | 33 | Calendar calendar = Calendar.getInstance(); 34 | Date now = calendar.getTime(); 35 | Timestamp currentTimeStamp = new Timestamp(now.getTime()); 36 | 37 | for (d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 38 | 39 | 40 | // Get the prepared statement. 41 | //"SELECT COALESCE(MIN(no_o_id),0) FROM new_orders WHERE no_d_id = ? AND no_w_id = ?" 42 | if (TRACE) 43 | logger.trace("SELECT COALESCE(MIN(no_o_id),0) FROM new_orders WHERE no_d_id = " + d_id + " AND no_w_id = " + w_id); 44 | try { 45 | pStmts.getStatement(25).setInt(1, d_id); 46 | pStmts.getStatement(25).setInt(2, w_id); 47 | ResultSet rs = pStmts.getStatement(25).executeQuery(); 48 | 49 | if (rs.next()) { 50 | no_o_id = rs.getInt(1); 51 | } 52 | 53 | rs.close(); 54 | } catch (SQLException e) { 55 | logger.error("SELECT COALESCE(MIN(no_o_id),0) FROM new_orders WHERE no_d_id = " + d_id + " AND no_w_id = " + w_id, e); 56 | throw new Exception("Delivery Select transaction error", e); 57 | } 58 | 59 | if (no_o_id == 0) { 60 | continue; 61 | } else { 62 | if (DEBUG) logger.debug("No_o_id did not equal 0 -> " + no_o_id); 63 | } 64 | 65 | //Get the prepared statement 66 | //"DELETE FROM new_orders WHERE no_o_id = ? AND no_d_id = ? AND no_w_id = ?" 67 | if (TRACE) 68 | logger.trace("DELETE FROM new_orders WHERE no_o_id = " + no_o_id + " AND no_d_id = " + d_id + " AND no_w_id = " + w_id); 69 | try { 70 | pStmts.getStatement(26).setInt(1, no_o_id); 71 | pStmts.getStatement(26).setInt(2, d_id); 72 | pStmts.getStatement(26).setInt(3, w_id); 73 | pStmts.getStatement(26).executeUpdate(); 74 | 75 | 76 | } catch (SQLException e) { 77 | logger.error("DELETE FROM new_orders WHERE no_o_id = " + no_o_id + " AND no_d_id = " + d_id + " AND no_w_id = " + w_id, e); 78 | throw new Exception(" Delivery Delete transaction error", e); 79 | } 80 | 81 | 82 | //Get the prepared statement 83 | //"SELECT o_c_id FROM orders WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?" 84 | if (TRACE) 85 | logger.trace("SELECT o_c_id FROM orders WHERE o_id = " + no_o_id + " AND o_d_id = " + d_id + " AND o_w_id = " + w_id); 86 | try { 87 | pStmts.getStatement(27).setInt(1, no_o_id); 88 | pStmts.getStatement(27).setInt(2, d_id); 89 | pStmts.getStatement(27).setInt(3, w_id); 90 | ResultSet rs = pStmts.getStatement(27).executeQuery(); 91 | 92 | if (rs.next()) { 93 | c_id = rs.getInt(1); 94 | } 95 | 96 | 97 | rs.close(); 98 | } catch (SQLException e) { 99 | logger.error("SELECT o_c_id FROM orders WHERE o_id = " + no_o_id + " AND o_d_id = " + d_id + " AND o_w_id = " + w_id, e); 100 | throw new Exception(" Delivery Select transaction error", e); 101 | } 102 | 103 | //Get the prepared Statement 104 | //"UPDATE orders SET o_carrier_id = ? WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?" 105 | if (TRACE) 106 | logger.trace("UPDATE orders SET o_carrier_id = " + o_carrier_id + " WHERE o_id = " + no_o_id + " AND o_d_id = " + d_id + " AND o_w_id = " + w_id); 107 | try { 108 | pStmts.getStatement(28).setInt(1, o_carrier_id); 109 | pStmts.getStatement(28).setInt(2, no_o_id); 110 | pStmts.getStatement(28).setInt(3, d_id); 111 | pStmts.getStatement(28).setInt(4, w_id); 112 | pStmts.getStatement(28).executeUpdate(); 113 | 114 | 115 | } catch (SQLException e) { 116 | logger.error("UPDATE orders SET o_carrier_id = " + o_carrier_id + " WHERE o_id = " + no_o_id + " AND o_d_id = " + d_id + " AND o_w_id = " + w_id, e); 117 | throw new Exception("Delivery Update transcation error", e); 118 | } 119 | 120 | 121 | //Get the prepared Statement 122 | //"UPDATE order_line SET ol_delivery_d = ? WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?" 123 | if (TRACE) 124 | logger.trace("UPDATE order_line SET ol_delivery_d = " + currentTimeStamp.toString() + " WHERE ol_o_id = " + no_o_id + " AND ol_d_id = " + d_id + " AND ol_w_id = " + w_id); 125 | try { 126 | pStmts.getStatement(29).setString(1, currentTimeStamp.toString()); 127 | pStmts.getStatement(29).setInt(2, no_o_id); 128 | pStmts.getStatement(29).setInt(3, d_id); 129 | pStmts.getStatement(29).setInt(4, w_id); 130 | pStmts.getStatement(29).executeUpdate(); 131 | 132 | 133 | } catch (SQLException e) { 134 | logger.error("UPDATE order_line SET ol_delivery_d = " + currentTimeStamp.toString() + " WHERE ol_o_id = " + no_o_id + " AND ol_d_id = " + d_id + " AND ol_w_id = " + w_id, e); 135 | throw new Exception("Delivery Update transaction error", e); 136 | } 137 | 138 | 139 | //Get the prepared Statement 140 | //"SELECT SUM(ol_amount) FROM order_line WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?" 141 | if (TRACE) 142 | logger.trace("SELECT SUM(ol_amount) FROM order_line WHERE ol_o_id = " + no_o_id + " AND ol_d_id = " + d_id + " AND ol_w_id = " + w_id); 143 | try { 144 | pStmts.getStatement(30).setInt(1, no_o_id); 145 | pStmts.getStatement(30).setInt(2, d_id); 146 | pStmts.getStatement(30).setInt(3, w_id); 147 | ResultSet rs = pStmts.getStatement(30).executeQuery(); 148 | if (rs.next()) { 149 | ol_total = rs.getFloat(1); 150 | } 151 | 152 | 153 | rs.close(); 154 | } catch (SQLException e) { 155 | logger.error("SELECT SUM(ol_amount) FROM order_line WHERE ol_o_id = " + no_o_id + " AND ol_d_id = " + d_id + " AND ol_w_id = " + w_id, e); 156 | throw new Exception("Delivery Select transaction error", e); 157 | } 158 | 159 | 160 | //Get the prepared statement 161 | //"UPDATE customer SET c_balance = c_balance + ? , c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = ? AND c_d_id = ? AND c_w_id = ?" 162 | if (TRACE) 163 | logger.trace("UPDATE customer SET c_balance = c_balance + " + ol_total + ", c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = " + c_id + " AND c_d_id = " + d_id + " AND c_w_id = " + w_id); 164 | try { 165 | pStmts.getStatement(31).setFloat(1, ol_total); 166 | pStmts.getStatement(31).setInt(2, c_id); 167 | pStmts.getStatement(31).setInt(3, d_id); 168 | pStmts.getStatement(31).setInt(4, w_id); 169 | pStmts.getStatement(31).executeUpdate(); 170 | 171 | 172 | } catch (SQLException e) { 173 | logger.error("UPDATE customer SET c_balance = c_balance + " + ol_total + ", c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = " + c_id + " AND c_d_id = " + d_id + " AND c_w_id = " + w_id, e); 174 | throw new Exception("Delivery Update transaction error", e); 175 | } 176 | } 177 | 178 | // Commit. 179 | pStmts.commit(); 180 | 181 | return 1; 182 | 183 | } catch (Exception e) { 184 | try { 185 | // Rollback if an aborted transaction, they are intentional in some percentage of cases. 186 | pStmts.rollback(); 187 | return 0; 188 | } catch (Throwable th) { 189 | throw new RuntimeException("Delivery error", th); 190 | } finally { 191 | logger.error("Delivery error", e); 192 | } 193 | } 194 | 195 | } 196 | 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Driver.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.util.Arrays; 6 | import java.util.concurrent.*; 7 | 8 | import org.slf4j.LoggerFactory; 9 | import org.slf4j.Logger; 10 | 11 | 12 | public class Driver implements TpccConstants { 13 | 14 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 15 | private static final boolean DEBUG = logger.isDebugEnabled(); 16 | 17 | /** 18 | * For debug use only. 19 | */ 20 | private static final boolean DETECT_LOCK_WAIT_TIMEOUTS = false; 21 | 22 | /** 23 | * Can be disabled for debug use only. 24 | */ 25 | private static final boolean ALLOW_MULTI_WAREHOUSE_TX = true; 26 | 27 | //CHECK: The following variables are externs?? 28 | // public int counting_on; 29 | public int num_ware; 30 | public int num_conn; 31 | 32 | public int num_node; 33 | // public int time_count; 34 | // public PrintWriter freport_file; 35 | 36 | // total count for all threads 37 | private int[] success; 38 | private int[] late; 39 | private int[] retry; 40 | private int[] failure; 41 | 42 | // per thread counts 43 | private int[][] success2; 44 | private int[][] late2; 45 | private int[][] retry2; 46 | private int[][] failure2; 47 | 48 | public double[] max_rt = new double[TRANSACTION_COUNT]; 49 | 50 | //Private variables 51 | private final int MAX_RETRY = 2000; 52 | private final int RTIME_NEWORD = 5 * 1000; 53 | private final int RTIME_PAYMENT = 5 * 1000; 54 | private final int RTIME_ORDSTAT = 5 * 1000; 55 | private final int RTIME_DELIVERY = 5 * 1000; 56 | private final int RTIME_SLEV = 20 * 1000; 57 | 58 | private Connection conn; 59 | private TpccStatements pStmts; 60 | 61 | // Transaction instances. 62 | private NewOrder newOrder; 63 | private Payment payment; 64 | private OrderStat orderStat; 65 | private Slev slev; 66 | private Delivery delivery; 67 | 68 | /** 69 | * Constructor. 70 | * 71 | * @param conn 72 | */ 73 | public Driver(Connection conn, int fetchSize, 74 | int[] success, int[] late, int[] retry, int[] failure, 75 | int[][] success2, int[][] late2, int[][] retry2, int[][] failure2, boolean joins) { 76 | try { 77 | this.conn = conn; 78 | 79 | pStmts = new TpccStatements(conn, fetchSize); 80 | 81 | // Initialize the transactions. 82 | newOrder = new NewOrder(pStmts, joins); 83 | payment = new Payment(pStmts); 84 | orderStat = new OrderStat(pStmts); 85 | slev = new Slev(pStmts); 86 | delivery = new Delivery(pStmts); 87 | 88 | this.success = success; 89 | this.late = late; 90 | this.retry = retry; 91 | this.failure = failure; 92 | 93 | this.success2 = success2; 94 | this.late2 = late2; 95 | this.retry2 = retry2; 96 | this.failure2 = failure2; 97 | 98 | for (int i = 0; i < TRANSACTION_COUNT; i++) { 99 | max_rt[i] = 0.0; 100 | } 101 | 102 | } catch (Throwable th) { 103 | throw new RuntimeException("Error initializing Driver", th); 104 | } 105 | } 106 | 107 | private final Executor exec = Executors.newSingleThreadExecutor(); 108 | 109 | public int runTransaction(final int t_num, final int numWare, final int numConn) { 110 | 111 | num_ware = numWare; 112 | num_conn = numConn; 113 | 114 | int count = 0; 115 | 116 | /* Actually, WaitTimes are needed... */ 117 | //CHECK: Is activate_transaction handled correctly? 118 | int sequence = Util.seqGet(); 119 | while (Tpcc.activate_transaction == 1) { 120 | 121 | try { 122 | if (DEBUG) logger.debug("BEFORE runTransaction: sequence: " + sequence); 123 | 124 | if (DETECT_LOCK_WAIT_TIMEOUTS) { 125 | final int _sequence = sequence; 126 | FutureTask t = new FutureTask(new Callable() { 127 | public Object call() throws Exception { 128 | doNextTransaction(t_num, _sequence); 129 | return null; 130 | } 131 | }); 132 | exec.execute(t); 133 | 134 | try { 135 | t.get(15, TimeUnit.SECONDS); 136 | } catch (InterruptedException e) { 137 | logger.error("InterruptedException", e); 138 | Tpcc.activate_transaction = 0; 139 | } catch (ExecutionException e) { 140 | logger.error("Unhandled exception", e); 141 | Tpcc.activate_transaction = 0; 142 | } catch (TimeoutException e) { 143 | logger.error("Detected Lock Wait", e); 144 | Tpcc.activate_transaction = 0; 145 | } 146 | 147 | } else { 148 | doNextTransaction(t_num, sequence); 149 | } 150 | 151 | count++; 152 | } catch (Throwable th) { 153 | logger.error("FAILED", th); 154 | Tpcc.activate_transaction = 0; 155 | try { 156 | conn.rollback(); 157 | } catch (SQLException e) { 158 | logger.error("", e); 159 | } 160 | return -1; 161 | } finally { 162 | if (DEBUG) logger.debug("AFTER runTransaction: sequence: " + sequence); 163 | } 164 | 165 | sequence = Util.seqGet(); 166 | 167 | } 168 | 169 | logger.debug("Driver terminated after {} transactions", count); 170 | 171 | return (0); 172 | 173 | } 174 | 175 | private void doNextTransaction(int t_num, int sequence) throws SQLException { 176 | if (sequence == 0) { 177 | doNeword(t_num); 178 | } else if (sequence == 1) { 179 | doPayment(t_num); 180 | } else if (sequence == 2) { 181 | doOrdstat(t_num); 182 | } else if (sequence == 3) { 183 | doDelivery(t_num); 184 | } else if (sequence == 4) { 185 | doSlev(t_num); 186 | } else { 187 | throw new IllegalStateException("Error - Unknown sequence"); 188 | } 189 | } 190 | 191 | /* 192 | * prepare data and execute the new order transaction for one order 193 | * officially, this is supposed to be simulated terminal I/O 194 | */ 195 | private int doNeword(int t_num) throws SQLException { 196 | int c_num = 0; 197 | int i = 0; 198 | int ret = 0; 199 | double rt = 0.0; 200 | 201 | long beginTime = 0; 202 | long endTime = 0; 203 | 204 | int w_id = 0; 205 | int d_id = 0; 206 | int c_id = 0; 207 | int ol_cnt = 0; 208 | int all_local = 1; 209 | int notfound = MAXITEMS + 1; 210 | int rbk = 0; 211 | 212 | int[] itemid = new int[MAX_NUM_ITEMS]; 213 | int[] supware = new int[MAX_NUM_ITEMS]; 214 | int[] qty = new int[MAX_NUM_ITEMS]; 215 | 216 | if (num_node == 0) { 217 | w_id = Util.randomNumber(1, num_ware); 218 | } else { 219 | c_num = ((num_node * t_num) / num_conn); /* drop moduls */ 220 | w_id = Util.randomNumber(1 + (num_ware * c_num) / num_node, 221 | (num_ware * (c_num + 1)) / num_node); 222 | } 223 | if (w_id < 1) { 224 | throw new IllegalStateException("Invalid warehouse ID " + w_id); 225 | } 226 | 227 | 228 | d_id = Util.randomNumber(1, DIST_PER_WARE); 229 | c_id = Util.nuRand(1023, 1, CUST_PER_DIST); 230 | 231 | ol_cnt = Util.randomNumber(5, 15); 232 | rbk = Util.randomNumber(1, 100); 233 | 234 | for (i = 0; i < ol_cnt; i++) { 235 | itemid[i] = Util.nuRand(8191, 1, MAXITEMS); 236 | if ((i == ol_cnt - 1) && (rbk == 1)) { 237 | itemid[i] = notfound; 238 | } 239 | if (ALLOW_MULTI_WAREHOUSE_TX) { 240 | if (Util.randomNumber(1, 100) != 1) { 241 | supware[i] = w_id; 242 | } else { 243 | supware[i] = otherWare(w_id); 244 | all_local = 0; 245 | } 246 | } else { 247 | supware[i] = w_id; 248 | } 249 | qty[i] = Util.randomNumber(1, 10); 250 | } 251 | 252 | beginTime = System.currentTimeMillis(); 253 | for (i = 0; i < MAX_RETRY; i++) { 254 | if (DEBUG) 255 | logger.debug("t_num: " + t_num + " w_id: " + w_id + " c_id: " + c_id + " ol_cnt: " + ol_cnt + " all_local: " + all_local + " qty: " + Arrays.toString(qty)); 256 | ret = newOrder.neword(t_num, w_id, d_id, c_id, ol_cnt, all_local, itemid, supware, qty); 257 | endTime = System.currentTimeMillis(); 258 | 259 | if (ret == 1) { 260 | 261 | rt = (double) (endTime - beginTime); 262 | if (DEBUG) logger.debug("BEFORE rt value: " + rt + " max_rt[0] value: " + max_rt[0]); 263 | 264 | if (rt > max_rt[0]) 265 | max_rt[0] = rt; 266 | 267 | if (DEBUG) logger.debug("AFTER rt value: " + rt + " max_rt[0] value: " + max_rt[0]); 268 | 269 | RtHist.histInc(0, rt); 270 | 271 | if (Tpcc.counting_on) { 272 | if (DEBUG) logger.debug(" rt: " + rt + " RTIME_NEWORD " + RTIME_NEWORD); 273 | if (rt < RTIME_NEWORD) { 274 | if (DEBUG) logger.debug("Rt < RTIME_NEWORD"); 275 | success[0]++; 276 | success2[0][t_num]++; 277 | } else { 278 | if (DEBUG) logger.debug("Rt > RTIME_NEWORD"); 279 | late[0]++; 280 | late2[0][t_num]++; 281 | } 282 | } 283 | 284 | return (1); /* end */ 285 | } else { 286 | 287 | if (Tpcc.counting_on) { 288 | 289 | retry[0]++; 290 | retry2[0][t_num]++; 291 | } 292 | 293 | } 294 | } 295 | 296 | if (Tpcc.counting_on) { 297 | retry[0]--; 298 | retry2[0][t_num]--; 299 | failure[0]++; 300 | failure2[0][t_num]++; 301 | } 302 | 303 | return (0); 304 | } 305 | 306 | /* 307 | * produce the id of a valid warehouse other than home_ware 308 | * (assuming there is one) 309 | */ 310 | private int otherWare(int home_ware) { 311 | int tmp; 312 | 313 | if (num_ware == 1) return home_ware; 314 | while ((tmp = Util.randomNumber(1, num_ware)) == home_ware) ; 315 | return tmp; 316 | } 317 | 318 | /* 319 | * prepare data and execute payment transaction 320 | */ 321 | private int doPayment(int t_num) { 322 | int c_num = 0; 323 | int byname = 0; 324 | int i = 0; 325 | int ret = 0; 326 | double rt = 0.0; 327 | 328 | //clock_t clk1,clk2; 329 | //struct timespec tbuf1; 330 | //struct timespec tbuf2; 331 | 332 | long beginTime = 0; 333 | long endTime = 0; 334 | int w_id = 0; 335 | int d_id = 0; 336 | int c_w_id = 0; 337 | int c_d_id = 0; 338 | int c_id = 0; 339 | int h_amount = 0; 340 | String c_last = null; 341 | 342 | if (num_node == 0) { 343 | w_id = Util.randomNumber(1, num_ware); 344 | } else { 345 | c_num = ((num_node * t_num) / num_conn); /* drop moduls */ 346 | w_id = Util.randomNumber(1 + (num_ware * c_num) / num_node, 347 | (num_ware * (c_num + 1)) / num_node); 348 | } 349 | d_id = Util.randomNumber(1, DIST_PER_WARE); 350 | c_id = Util.nuRand(1023, 1, CUST_PER_DIST); 351 | c_last = Util.lastName(Util.nuRand(255, 0, 999)); 352 | h_amount = Util.randomNumber(1, 5000); 353 | if (Util.randomNumber(1, 100) <= 60) { 354 | byname = 1; /* select by last name */ 355 | } else { 356 | byname = 0; /* select by customer id */ 357 | } 358 | if (ALLOW_MULTI_WAREHOUSE_TX) { 359 | if (Util.randomNumber(1, 100) <= 85) { 360 | c_w_id = w_id; 361 | c_d_id = d_id; 362 | } else { 363 | c_w_id = otherWare(w_id); 364 | c_d_id = Util.randomNumber(1, DIST_PER_WARE); 365 | } 366 | } else { 367 | c_w_id = w_id; 368 | c_d_id = d_id; 369 | } 370 | 371 | // if(DEBUG) logger.debug("Payment| cnum: " + c_num + " w_id: " +w_id + " d_id: " + d_id + " c_id: " + c_id + " c_last: " + c_last + " h_amount: " + h_amount + " byname: " + byname + " c_w_id: " + c_w_id + " c_d_id: " + c_d_id ); 372 | 373 | //clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 374 | beginTime = System.currentTimeMillis(); 375 | for (i = 0; i < MAX_RETRY; i++) { 376 | ret = payment.payment(t_num, w_id, d_id, byname, c_w_id, c_d_id, c_id, c_last, h_amount); 377 | // clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 378 | endTime = System.currentTimeMillis(); 379 | 380 | if (ret >= 1) { 381 | 382 | //rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0); 383 | rt = (double) (endTime - beginTime); 384 | if (rt > max_rt[1]) 385 | max_rt[1] = rt; 386 | RtHist.histInc(1, rt); 387 | if (Tpcc.counting_on) { 388 | if (rt < RTIME_PAYMENT) { 389 | success[1]++; 390 | success2[1][t_num]++; 391 | } else { 392 | late[1]++; 393 | late2[1][t_num]++; 394 | } 395 | } 396 | 397 | return (1); /* end */ 398 | } else { 399 | 400 | if (Tpcc.counting_on) { 401 | retry[1]++; 402 | retry2[1][t_num]++; 403 | } 404 | 405 | } 406 | } 407 | 408 | if (Tpcc.counting_on) { 409 | retry[1]--; 410 | retry2[1][t_num]--; 411 | failure[1]++; 412 | failure2[1][t_num]++; 413 | } 414 | 415 | return (0); 416 | } 417 | 418 | /* 419 | * prepare data and execute order status transaction 420 | */ 421 | private int doOrdstat(int t_num) { 422 | int c_num = 0; 423 | int byname = 0; 424 | int i = 0; 425 | int ret = 0; 426 | double rt = 0.0; 427 | /*clock_t clk1,clk2; 428 | struct timespec tbuf1; 429 | struct timespec tbuf2;*/ 430 | long beginTime = 0; 431 | long endTime = 0; 432 | 433 | int w_id = 0; 434 | int d_id = 0; 435 | int c_id = 0; 436 | String c_last = null; 437 | 438 | if (num_node == 0) { 439 | w_id = Util.randomNumber(1, num_ware); 440 | } else { 441 | c_num = ((num_node * t_num) / num_conn); /* drop moduls */ 442 | w_id = Util.randomNumber(1 + (num_ware * c_num) / num_node, 443 | (num_ware * (c_num + 1)) / num_node); 444 | } 445 | d_id = Util.randomNumber(1, DIST_PER_WARE); 446 | c_id = Util.nuRand(1023, 1, CUST_PER_DIST); 447 | c_last = Util.lastName(Util.nuRand(255, 0, 999)); 448 | if (Util.randomNumber(1, 100) <= 60) { 449 | byname = 1; /* select by last name */ 450 | } else { 451 | byname = 0; /* select by customer id */ 452 | } 453 | 454 | //clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 455 | beginTime = System.currentTimeMillis(); 456 | for (i = 0; i < MAX_RETRY; i++) { 457 | ret = orderStat.ordStat(t_num, w_id, d_id, byname, c_id, c_last); 458 | // clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 459 | endTime = System.currentTimeMillis(); 460 | 461 | if (ret >= 1) { 462 | 463 | //rt = (double)(tbuf2.tv_sec * 1000.0 + tbuf2.tv_nsec/1000000.0-tbuf1.tv_sec * 1000.0 - tbuf1.tv_nsec/1000000.0) 464 | rt = (double) (endTime - beginTime); 465 | if (rt > max_rt[2]) 466 | max_rt[2] = rt; 467 | RtHist.histInc(2, rt); 468 | if (Tpcc.counting_on) { 469 | if (rt < RTIME_ORDSTAT) { 470 | success[2]++; 471 | success2[2][t_num]++; 472 | } else { 473 | late[2]++; 474 | late2[2][t_num]++; 475 | } 476 | } 477 | 478 | return (1); /* end */ 479 | } else { 480 | 481 | if (Tpcc.counting_on) { 482 | retry[2]++; 483 | retry2[2][t_num]++; 484 | } 485 | 486 | } 487 | } 488 | 489 | if (Tpcc.counting_on) { 490 | retry[2]--; 491 | retry2[2][t_num]--; 492 | failure[2]++; 493 | failure2[2][t_num]++; 494 | } 495 | 496 | return (0); 497 | 498 | } 499 | 500 | /* 501 | * execute delivery transaction 502 | */ 503 | private int doDelivery(int t_num) { 504 | int c_num = 0; 505 | int i = 0; 506 | int ret = 0; 507 | double rt = 0.0; 508 | long beginTime = 0; 509 | long endTime = 0; 510 | int w_id = 0; 511 | int o_carrier_id = 0; 512 | 513 | if (num_node == 0) { 514 | w_id = Util.randomNumber(1, num_ware); 515 | } else { 516 | c_num = ((num_node * t_num) / num_conn); /* drop moduls */ 517 | w_id = Util.randomNumber(1 + (num_ware * c_num) / num_node, 518 | (num_ware * (c_num + 1)) / num_node); 519 | } 520 | o_carrier_id = Util.randomNumber(1, 10); 521 | 522 | beginTime = System.currentTimeMillis(); 523 | for (i = 0; i < MAX_RETRY; i++) { 524 | ret = delivery.delivery(w_id, o_carrier_id); 525 | endTime = System.currentTimeMillis(); 526 | if (ret >= 1) { 527 | 528 | rt = (double) (endTime - beginTime); 529 | if (rt > max_rt[3]) 530 | max_rt[3] = rt; 531 | RtHist.histInc(3, rt); 532 | if (Tpcc.counting_on) { 533 | if (rt < RTIME_DELIVERY) { 534 | success[3]++; 535 | success2[3][t_num]++; 536 | } else { 537 | late[3]++; 538 | late2[3][t_num]++; 539 | } 540 | } 541 | 542 | return (1); /* end */ 543 | } else { 544 | 545 | if (Tpcc.counting_on) { 546 | retry[3]++; 547 | retry2[3][t_num]++; 548 | } 549 | 550 | } 551 | } 552 | 553 | if (Tpcc.counting_on) { 554 | retry[3]--; 555 | retry2[3][t_num]--; 556 | failure[3]++; 557 | failure2[3][t_num]++; 558 | } 559 | 560 | return (0); 561 | 562 | } 563 | 564 | /* 565 | * prepare data and execute the stock level transaction 566 | */ 567 | private int doSlev(int t_num) { 568 | int c_num = 0; 569 | int i = 0; 570 | int ret = 0; 571 | double rt = 0.0; 572 | long beginTime = 0; 573 | long endTime = 0; 574 | int w_id = 0; 575 | int d_id = 0; 576 | int level = 0; 577 | 578 | if (num_node == 0) { 579 | w_id = Util.randomNumber(1, num_ware); 580 | } else { 581 | c_num = ((num_node * t_num) / num_conn); /* drop moduls */ 582 | w_id = Util.randomNumber(1 + (num_ware * c_num) / num_node, 583 | (num_ware * (c_num + 1)) / num_node); 584 | } 585 | d_id = Util.randomNumber(1, DIST_PER_WARE); 586 | level = Util.randomNumber(10, 20); 587 | 588 | // clk1 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf1 ); 589 | beginTime = System.currentTimeMillis(); 590 | for (i = 0; i < MAX_RETRY; i++) { 591 | ret = slev.slev(t_num, w_id, d_id, level); 592 | //clk2 = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tbuf2 ); 593 | endTime = System.currentTimeMillis(); 594 | 595 | if (ret >= 1) { 596 | 597 | rt = (double) (endTime - beginTime); 598 | if (rt > max_rt[4]) 599 | max_rt[4] = rt; 600 | RtHist.histInc(4, rt); 601 | if (Tpcc.counting_on) { 602 | if (rt < RTIME_SLEV) { 603 | success[4]++; 604 | success2[4][t_num]++; 605 | } else { 606 | late[4]++; 607 | late2[4][t_num]++; 608 | } 609 | } 610 | 611 | return (1); /* end */ 612 | } else { 613 | 614 | if (Tpcc.counting_on) { 615 | retry[4]++; 616 | retry2[4][t_num]++; 617 | } 618 | 619 | } 620 | } 621 | 622 | if (Tpcc.counting_on) { 623 | retry[4]--; 624 | retry2[4][t_num]--; 625 | failure[4]++; 626 | failure2[4][t_num]++; 627 | } 628 | 629 | return (0); 630 | 631 | } 632 | 633 | 634 | } 635 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Load.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import com.codefutures.tpcc.load.Record; 4 | import com.codefutures.tpcc.load.RecordLoader; 5 | 6 | import java.util.Calendar; 7 | import java.util.Date; 8 | 9 | public class Load implements TpccConstants { 10 | private static boolean optionDebug = false; 11 | 12 | /* 13 | * ==================================================================+ | 14 | * ROUTINE NAME | LoadItems | DESCRIPTION | Loads the Item table | 15 | * ARGUMENTS | none 16 | * +================================================================== 17 | */ 18 | public static void loadItems(TpccLoadConfig loadConfig, boolean option_debug) throws Exception { 19 | optionDebug = option_debug; 20 | int i_id = 0; 21 | int i_im_id = 0; 22 | String i_name = null; 23 | float i_price = 0; 24 | String i_data = null; 25 | 26 | // int idatasize = 0; 27 | int[] orig = new int[MAXITEMS + 1]; 28 | int pos = 0; 29 | int i = 0; 30 | // int retried = 0; 31 | 32 | 33 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 34 | 35 | System.out.printf("Loading Item \n"); 36 | 37 | for (i = 0; i < MAXITEMS / 10; i++) { 38 | orig[i] = 0; 39 | } 40 | for (i = 0; i < MAXITEMS / 10; i++) { 41 | do { 42 | pos = Util.randomNumber(0, MAXITEMS); 43 | } while (orig[pos] != 0); 44 | orig[pos] = 1; 45 | } 46 | 47 | final String ITEM_COLUMN_NAME[] = {"i_id", " i_im_id", " i_name", " i_price", " i_data"}; 48 | final Record itemRecord = new Record(5); 49 | final RecordLoader itemLoader = loadConfig.createLoader("item", ITEM_COLUMN_NAME); 50 | 51 | for (i_id = 1; i_id <= MAXITEMS; i_id++) { 52 | 53 | /* Generate Item Data */ 54 | i_im_id = Util.randomNumber(1, 10000); 55 | 56 | i_name = Util.makeAlphaString(14, 24); 57 | if (i_name == null) { 58 | System.out.println("I_name null."); 59 | System.exit(1); 60 | } 61 | 62 | i_price = (float) ((int) (Util.randomNumber(100, 10000)) / 100.0); 63 | 64 | i_data = Util.makeAlphaString(26, 50); 65 | if (orig[i_id] != 0) { 66 | pos = Util.randomNumber(0, i_data.length() - 8); 67 | i_data = i_data.substring(0, pos) + "original" + i_data.substring(pos + 8); 68 | } 69 | 70 | /*System.out.printf("IID = %d, Name= %s, Price = %f\n", 71 | i_id, i_name, i_price); *///DEBUG 72 | 73 | /* EXEC SQL INSERT INTO 74 | item 75 | values(:i_id,:i_im_id,:i_name,:i_price,:i_data); */ 76 | itemRecord.reset(); 77 | itemRecord.add(i_id); 78 | itemRecord.add(i_im_id); 79 | itemRecord.add(i_name); 80 | itemRecord.add(i_price); 81 | itemRecord.add(i_data); 82 | 83 | itemLoader.load(itemRecord); 84 | 85 | if ((i_id % 100) == 0) { 86 | System.out.printf("."); 87 | if ((i_id % 5000) == 0) 88 | System.out.printf(" %d\n", i_id); 89 | } 90 | } 91 | 92 | /* EXEC SQL COMMIT WORK; */ 93 | 94 | itemLoader.close(); 95 | 96 | System.out.printf("Item Done. \n"); 97 | } 98 | 99 | /* 100 | * ==================================================================+ | 101 | * ROUTINE NAME | LoadWare | DESCRIPTION | Loads the Warehouse 102 | * table | Loads Stock, District as Warehouses are created | ARGUMENTS | 103 | * none +================================================================== 104 | */ 105 | public static void loadWare(TpccLoadConfig loadConfig, int shardCount, int min_ware, int max_ware, boolean option_debug, int shardId) throws Exception { 106 | 107 | int w_id; 108 | String w_name = null; 109 | String w_street_1 = null; 110 | String w_street_2 = null; 111 | String w_city = null; 112 | String w_state = null; 113 | String w_zip = null; 114 | double w_tax = 0; 115 | double w_ytd = 0; 116 | 117 | int tmp = 0; 118 | //boolean retried = false; 119 | int currentShard = 0; 120 | 121 | System.out.printf("Loading Warehouse \n"); 122 | 123 | final String WAREHOUSE_COLUMN_NAME[] = {"w_id", " w_name", " w_street_1", " w_street_2", " w_city", " w_state", " w_zip", " w_tax", " w_ytd"}; 124 | final Record warehouseRecord = new Record(9); 125 | final RecordLoader warehouseLoader = loadConfig.createLoader("warehouse", WAREHOUSE_COLUMN_NAME); 126 | 127 | 128 | //retry: 129 | // if (retried) 130 | // System.out.printf("Retrying ....\n"); 131 | // retried = true; 132 | for (w_id = min_ware; w_id <= max_ware; w_id++) { 133 | 134 | if (shardCount > 0) { 135 | currentShard = (w_id % shardCount); 136 | if (currentShard == 0) { 137 | currentShard = shardCount; 138 | } 139 | } 140 | 141 | if ((currentShard == shardId) || (shardId == 0)) { 142 | System.out.println("Current Shard: " + currentShard); 143 | /* Generate Warehouse Data */ 144 | 145 | w_name = Util.makeAlphaString(6, 10); 146 | w_street_1 = Util.makeAlphaString(10, 20); 147 | w_street_2 = Util.makeAlphaString(10, 20); 148 | w_city = Util.makeAlphaString(10, 20); 149 | w_state = Util.makeAlphaString(2, 2); 150 | w_zip = Util.makeAlphaString(9, 9); 151 | 152 | w_tax = ((double) Util.randomNumber(10, 20) / 100.0); 153 | w_ytd = 3000000.00; 154 | 155 | //if (option_debug) 156 | System.out.printf("WID = %d, Name= %s, Tax = %f\n", 157 | w_id, w_name, w_tax); 158 | /*EXEC SQL INSERT INTO 159 | warehouse 160 | values(:w_id,:w_name, 161 | :w_street_1,:w_street_2,:w_city,:w_state, 162 | :w_zip,:w_tax,:w_ytd);*/ 163 | 164 | warehouseRecord.reset(); 165 | warehouseRecord.add(w_id); 166 | warehouseRecord.add(w_name); 167 | warehouseRecord.add(w_street_1); 168 | warehouseRecord.add(w_street_2); 169 | warehouseRecord.add(w_city); 170 | warehouseRecord.add(w_state); 171 | warehouseRecord.add(w_zip); 172 | warehouseRecord.add(w_tax); 173 | warehouseRecord.add(w_ytd); 174 | 175 | warehouseLoader.load(warehouseRecord); 176 | warehouseLoader.commit(); 177 | 178 | /** Make Rows associated with Warehouse **/ 179 | stock(loadConfig, w_id); 180 | district(loadConfig, w_id); 181 | } 182 | 183 | } 184 | 185 | /* EXEC SQL COMMIT WORK; */ 186 | 187 | warehouseLoader.close(); 188 | } 189 | 190 | /* 191 | * ==================================================================+ | 192 | * ROUTINE NAME | LoadCust | DESCRIPTION | Loads the Customer Table 193 | * | ARGUMENTS | none 194 | * +================================================================== 195 | */ 196 | public static void loadCust(TpccLoadConfig loadConfig, int shardCount, int min_ware, int max_ware, int shardId) { 197 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr; */ 198 | try { 199 | for (int w_id = min_ware; w_id <= max_ware; w_id++) { 200 | for (int d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 201 | loadCustomer(loadConfig, d_id, w_id, shardCount, shardId); 202 | } 203 | } 204 | } catch (Exception e) { 205 | throw new RuntimeException("Error loading customers", e); 206 | } 207 | } 208 | 209 | /* 210 | * ==================================================================+ | 211 | * ROUTINE NAME | LoadOrd | DESCRIPTION | Loads the Orders and 212 | * Order_Line Tables | ARGUMENTS | none 213 | * +================================================================== 214 | */ 215 | public static void loadOrd(TpccLoadConfig loadConfig, int shardCount, int max_ware, int shardId) { 216 | try { 217 | // for each warehouse 218 | for (int w_id = 1; w_id <= max_ware; w_id++) { 219 | // for each district 220 | for (int d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 221 | // generate orders 222 | loadOrders(loadConfig, d_id, w_id, shardCount, shardId); 223 | } 224 | } 225 | } catch (Exception e) { 226 | throw new RuntimeException("Failed to load orders", e); 227 | } 228 | } 229 | 230 | /* 231 | * ==================================================================+ | 232 | * ROUTINE NAME | Stock | DESCRIPTION | Loads the Stock table | 233 | * ARGUMENTS | w_id - warehouse id 234 | * +================================================================== 235 | */ 236 | public static boolean stock(TpccLoadConfig loadConfig, int w_id) throws Exception { 237 | 238 | int s_i_id = 0; 239 | int s_w_id = 0; 240 | int s_quantity = 0; 241 | 242 | String s_dist_01 = null; 243 | String s_dist_02 = null; 244 | String s_dist_03 = null; 245 | String s_dist_04 = null; 246 | String s_dist_05 = null; 247 | String s_dist_06 = null; 248 | String s_dist_07 = null; 249 | String s_dist_08 = null; 250 | String s_dist_09 = null; 251 | String s_dist_10 = null; 252 | String s_data = null; 253 | 254 | //int sdatasize = 0; 255 | int[] orig = new int[MAXITEMS + 1]; 256 | int pos = 0; 257 | int i = 0; 258 | boolean error = false; 259 | 260 | final String STOCK_COLUMN_NAME[] = {"s_i_id", " s_w_id", " s_quantity", " " + 261 | "s_dist_01", " s_dist_02", " s_dist_03", " s_dist_04", " s_dist_05", " s_dist_06", " " + 262 | "s_dist_07", " s_dist_08", " s_dist_09", " s_dist_10", " s_ytd", " s_order_cnt", " " + 263 | "s_remote_cnt", " s_data" 264 | }; 265 | 266 | final Record stockRecord = new Record(17); 267 | RecordLoader stockLoader = loadConfig.createLoader("stock", STOCK_COLUMN_NAME); 268 | 269 | /* EXEC SQL WHENEVER SQLERROR GOTO sqlerr;*/ 270 | System.out.printf("Loading Stock Wid=%d\n", w_id); 271 | s_w_id = w_id; 272 | 273 | for (i = 0; i < MAXITEMS / 10; i++) { 274 | orig[i] = 0; 275 | } 276 | 277 | for (i = 0; i < MAXITEMS / 10; i++) { 278 | do { 279 | pos = Util.randomNumber(0, MAXITEMS); 280 | } while (orig[pos] != 0); //TODO: FIx later 281 | orig[pos] = 1; 282 | } 283 | 284 | ////retry: 285 | for (s_i_id = 1; s_i_id <= MAXITEMS; s_i_id++) { 286 | 287 | /* Generate Stock Data */ 288 | s_quantity = Util.randomNumber(10, 100); 289 | 290 | s_dist_01 = Util.makeAlphaString(24, 24); 291 | s_dist_02 = Util.makeAlphaString(24, 24); 292 | s_dist_03 = Util.makeAlphaString(24, 24); 293 | s_dist_04 = Util.makeAlphaString(24, 24); 294 | s_dist_05 = Util.makeAlphaString(24, 24); 295 | s_dist_06 = Util.makeAlphaString(24, 24); 296 | s_dist_07 = Util.makeAlphaString(24, 24); 297 | s_dist_08 = Util.makeAlphaString(24, 24); 298 | s_dist_09 = Util.makeAlphaString(24, 24); 299 | s_dist_10 = Util.makeAlphaString(24, 24); 300 | 301 | 302 | s_data = Util.makeAlphaString(26, 50); 303 | //sdatasize = s_data.length(); 304 | if (orig[s_i_id] != 0) {//TODO:Change this later 305 | //pos = Util.randomNumber(0, sdatasize - 8); 306 | s_data = "original"; 307 | } 308 | /*EXEC SQL INSERT INTO 309 | stock 310 | values(:s_i_id,:s_w_id,:s_quantity, 311 | :s_dist_01,:s_dist_02,:s_dist_03,:s_dist_04,:s_dist_05, 312 | :s_dist_06,:s_dist_07,:s_dist_08,:s_dist_09,:s_dist_10, 313 | 0, 0, 0,:s_data);*/ 314 | 315 | stockRecord.reset(); 316 | stockRecord.add(s_i_id); 317 | stockRecord.add(s_w_id); 318 | stockRecord.add(s_quantity); 319 | stockRecord.add(s_dist_01); 320 | stockRecord.add(s_dist_02); 321 | stockRecord.add(s_dist_03); 322 | stockRecord.add(s_dist_04); 323 | stockRecord.add(s_dist_05); 324 | stockRecord.add(s_dist_06); 325 | stockRecord.add(s_dist_07); 326 | stockRecord.add(s_dist_08); 327 | stockRecord.add(s_dist_09); 328 | stockRecord.add(s_dist_10); 329 | stockRecord.add(0); 330 | stockRecord.add(0); 331 | stockRecord.add(0); 332 | stockRecord.add(s_data); 333 | 334 | stockLoader.load(stockRecord); 335 | 336 | if (optionDebug) 337 | System.out.printf("SID = %d, WID = %d, Quan = %d\n", 338 | s_i_id, s_w_id, s_quantity); 339 | 340 | if ((s_i_id % 100) == 0) { 341 | System.out.printf("."); 342 | if ((s_i_id % 5000) == 0) 343 | System.out.printf(" %d\n", s_i_id); 344 | } 345 | } 346 | 347 | stockLoader.close(); 348 | 349 | System.out.printf(" Stock Done.\n"); 350 | return error; 351 | 352 | } 353 | 354 | /* 355 | * ==================================================================+ | 356 | * ROUTINE NAME | District | DESCRIPTION | Loads the District table 357 | * | ARGUMENTS | w_id - warehouse id 358 | * +================================================================== 359 | */ 360 | public static boolean district(TpccLoadConfig loadConfig, int w_id) throws Exception { 361 | int d_id; 362 | int d_w_id; 363 | String d_name; 364 | String d_street_1; 365 | String d_street_2; 366 | String d_city; 367 | String d_state; 368 | String d_zip; 369 | float d_tax; 370 | float d_ytd; 371 | int d_next_o_id; 372 | boolean error = false; 373 | 374 | System.out.printf("Loading District\n"); 375 | d_w_id = w_id; 376 | d_ytd = (float) 30000.0; 377 | d_next_o_id = 3001; 378 | 379 | final String[] DISTRICT_COLUMN_NAME = {"d_id", " d_w_id", " d_name", " d_street_1", " d_street_2", " d_city", " d_state", " d_zip", " d_tax", " d_ytd", " d_next_o_id"}; 380 | final Record districtRecord = new Record(11); 381 | final RecordLoader districtLoader = loadConfig.createLoader("district", DISTRICT_COLUMN_NAME); 382 | 383 | //retry: 384 | for (d_id = 1; d_id <= DIST_PER_WARE; d_id++) { 385 | 386 | /* Generate District Data */ 387 | 388 | d_name = Util.makeAlphaString(6, 10); 389 | d_street_1 = Util.makeAlphaString(10, 20); 390 | d_street_2 = Util.makeAlphaString(10, 20); 391 | d_city = Util.makeAlphaString(10, 20); 392 | d_state = Util.makeAlphaString(2, 2); 393 | d_zip = Util.makeAlphaString(9, 9); 394 | 395 | d_tax = (float) (((float) Util.randomNumber(10, 20)) / 100.0); 396 | 397 | /*EXEC SQL INSERT INTO 398 | district 399 | values(:d_id,:d_w_id,:d_name, 400 | :d_street_1,:d_street_2,:d_city,:d_state,:d_zip, 401 | :d_tax,:d_ytd,:d_next_o_id);*/ 402 | 403 | districtRecord.reset(); 404 | districtRecord.add(d_id); 405 | districtRecord.add(d_w_id); 406 | districtRecord.add(d_name); 407 | districtRecord.add(d_street_1); 408 | districtRecord.add(d_street_2); 409 | districtRecord.add(d_city); 410 | districtRecord.add(d_state); 411 | districtRecord.add(d_zip); 412 | districtRecord.add(d_tax); 413 | districtRecord.add(d_ytd); 414 | districtRecord.add(d_next_o_id); 415 | 416 | districtLoader.load(districtRecord); 417 | 418 | if (optionDebug) 419 | System.out.printf("DID = %d, WID = %d, Name = %s, Tax = %f\n", 420 | d_id, d_w_id, d_name, d_tax); 421 | 422 | } 423 | 424 | districtLoader.close(); 425 | 426 | return error; 427 | 428 | } 429 | 430 | /* 431 | * ==================================================================+ | 432 | * ROUTINE NAME | Customer | DESCRIPTION | Loads Customer Table | 433 | * Also inserts corresponding history record | ARGUMENTS | id - 434 | * customer id | d_id - district id | w_id - warehouse id 435 | * +================================================================== 436 | */ 437 | public static void loadCustomer(TpccLoadConfig loadConfig, int d_id, int w_id, int shardCount, int shardId) throws Exception { 438 | int c_id = 0; 439 | int c_d_id = 0; 440 | int c_w_id = 0; 441 | String c_first = null; 442 | String c_middle = null; 443 | String c_last = null; 444 | String c_street_1 = null; 445 | String c_street_2 = null; 446 | String c_city = null; 447 | String c_state = null; 448 | String c_zip = null; 449 | String c_phone = null; 450 | // String c_since = null; 451 | String c_credit = null; 452 | 453 | int c_credit_lim = 0; 454 | float c_discount = 0; 455 | float c_balance = 0; 456 | String c_data = null; 457 | 458 | double h_amount = 0.0; 459 | 460 | String h_data = null; 461 | // //boolean retried = false; 462 | 463 | System.out.printf("Loading Customer for DID=%d, WID=%d\n", d_id, w_id); 464 | int currentShard = 0; 465 | if (shardCount > 0) { 466 | currentShard = (w_id % shardCount); 467 | if (currentShard == 0) { 468 | currentShard = shardCount; 469 | } 470 | } 471 | 472 | final String[] CUSTOMER_COLUMNS = { 473 | "c_id", "c_d_id", "c_w_id", "c_first", "c_middle", "c_last", "c_street_1", "c_street_2", "c_city", 474 | "c_state", "c_zip", "c_phone", "c_since", "c_credit", "c_credit_lim", 475 | "c_discount", "c_balance", "c_ytd_payment", "c_payment_cnt", "c_delivery_cnt", "c_data" 476 | }; 477 | final Record customerRecord = new Record(21); 478 | final RecordLoader customerLoader = loadConfig.createLoader("customer", CUSTOMER_COLUMNS); 479 | 480 | final String[] HISTORY_COLUMN_NAME = { 481 | "h_c_id", "h_c_d_id", "h_c_w_id", "h_d_id", "h_w_id", "h_date", "h_amount", "h_data" 482 | }; 483 | final Record historyRecord = new Record(8); 484 | final RecordLoader historyLoader = loadConfig.createLoader("history", HISTORY_COLUMN_NAME); 485 | 486 | if ((currentShard == shardId) || (shardId == 0)) { 487 | //retry: 488 | // if (retried) 489 | // System.out.printf("Retrying ...\n"); 490 | // retried = true; 491 | for (c_id = 1; c_id <= CUST_PER_DIST; c_id++) { 492 | 493 | /* Generate Customer Data */ 494 | c_d_id = d_id; 495 | c_w_id = w_id; 496 | 497 | c_first = Util.makeAlphaString(8, 16); 498 | c_middle = "O" + "E"; 499 | 500 | if (c_id <= 1000) { 501 | c_last = Util.lastName(c_id - 1); 502 | } else { 503 | c_last = Util.lastName(Util.nuRand(255, 0, 999)); 504 | } 505 | 506 | c_street_1 = Util.makeAlphaString(10, 20); 507 | c_street_2 = Util.makeAlphaString(10, 20); 508 | c_city = Util.makeAlphaString(10, 20); 509 | c_state = Util.makeAlphaString(2, 2); 510 | c_zip = Util.makeAlphaString(9, 9); 511 | 512 | c_phone = Util.makeNumberString(16, 16); 513 | 514 | if (Util.randomNumber(0, 1) == 1) 515 | c_credit = "G"; 516 | else 517 | c_credit = "B"; 518 | c_credit += "C"; 519 | 520 | c_credit_lim = 50000; 521 | c_discount = (float) (((float) Util.randomNumber(0, 50)) / 100.0); 522 | c_balance = (float) -10.0; 523 | 524 | c_data = Util.makeAlphaString(300, 500); 525 | //gettimestamp(datetime, STRFTIME_FORMAT, TIMESTAMP_LEN); Java Equivalent below? 526 | Calendar calendar = Calendar.getInstance(); 527 | //Date now = calendar.getTime(); 528 | //Timestamp currentTimeStamp = new Timestamp(now.getTime()); 529 | Date date = new java.sql.Date(calendar.getTimeInMillis()); 530 | /*EXEC SQL INSERT INTO 531 | customer 532 | values(:c_id,:c_d_id,:c_w_id, 533 | :c_first,:c_middle,:c_last, 534 | :c_street_1,:c_street_2,:c_city,:c_state, 535 | :c_zip, 536 | :c_phone, :timestamp, 537 | :c_credit, 538 | :c_credit_lim,:c_discount,:c_balance, 539 | 10.0, 1, 0,:c_data);*/ 540 | try { 541 | 542 | 543 | customerRecord.reset(); 544 | customerRecord.add(c_id); 545 | customerRecord.add(c_d_id); 546 | customerRecord.add(c_w_id); 547 | customerRecord.add(c_first); 548 | customerRecord.add(c_middle); 549 | customerRecord.add(c_last); 550 | customerRecord.add(c_street_1); 551 | customerRecord.add(c_street_2); 552 | customerRecord.add(c_city); 553 | customerRecord.add(c_state); 554 | customerRecord.add(c_zip); 555 | customerRecord.add(c_phone); 556 | customerRecord.add(date); 557 | customerRecord.add(c_credit); 558 | customerRecord.add(c_credit_lim); 559 | customerRecord.add(c_discount); 560 | customerRecord.add(c_balance); 561 | customerRecord.add(10.0); 562 | customerRecord.add(1); 563 | customerRecord.add(0); 564 | customerRecord.add(c_data); 565 | 566 | customerLoader.load(customerRecord); 567 | 568 | } catch (Exception e) { 569 | throw new RuntimeException("Customer insert error", e); 570 | } 571 | 572 | h_amount = 10.0; 573 | 574 | h_data = Util.makeAlphaString(12, 24); 575 | 576 | /*EXEC SQL INSERT INTO 577 | history 578 | values(:c_id,:c_d_id,:c_w_id, 579 | :c_d_id,:c_w_id, :timestamp, 580 | :h_amount,:h_data);*/ 581 | try { 582 | 583 | historyRecord.reset(); 584 | historyRecord.add(c_id); 585 | historyRecord.add(c_d_id); 586 | historyRecord.add(c_w_id); 587 | historyRecord.add(c_d_id); 588 | historyRecord.add(c_w_id); 589 | historyRecord.add(date); 590 | historyRecord.add(h_amount); 591 | historyRecord.add(h_data); 592 | 593 | historyLoader.load(historyRecord); 594 | 595 | } catch (Exception e) { 596 | throw new RuntimeException("Insert into History error", e); 597 | } 598 | if (optionDebug) { 599 | System.out.printf("CID = %d, LST = %s, P# = %s\n", 600 | c_id, c_last, c_phone); 601 | } 602 | if ((c_id % 100) == 0) { 603 | System.out.printf("."); 604 | if ((c_id % 1000) == 0) 605 | System.out.printf(" %d\n", c_id); 606 | } 607 | } 608 | 609 | } 610 | 611 | customerLoader.close(); 612 | historyLoader.close(); 613 | 614 | System.out.printf("Customer Done.\n"); 615 | } 616 | 617 | /* 618 | * ==================================================================+ | 619 | * ROUTINE NAME | Orders | DESCRIPTION | Loads the Orders table | 620 | * Also loads the Order_Line table on the fly | ARGUMENTS | w_id - 621 | * warehouse id 622 | * +================================================================== 623 | */ 624 | public static void loadOrders(TpccLoadConfig loadConfig, int d_id, int w_id, int shardCount, int shardId) throws Exception { 625 | int o_id; 626 | int o_c_id; 627 | int o_d_id; 628 | int o_w_id; 629 | int o_carrier_id; 630 | int o_ol_cnt; 631 | int ol; 632 | int ol_i_id; 633 | int ol_supply_w_id; 634 | int ol_quantity; 635 | float ol_amount; 636 | String ol_dist_info; 637 | 638 | //TODO: shouldn't these variables be used? 639 | // float i_price; 640 | // float c_discount; 641 | 642 | float tmp_float; 643 | 644 | int currentShard = 0; 645 | if (shardCount > 0) { 646 | currentShard = (w_id % shardCount); 647 | if (currentShard == 0) { 648 | currentShard = shardCount; 649 | } 650 | } 651 | 652 | final String ORDERS_COLUMN_NAME[] = {"o_id", "o_d_id", "o_w_id", "o_c_id", "o_entry_d", "o_carrier_id", "o_ol_cnt", "o_all_local"}; 653 | final Record orderRecord = new Record(8); 654 | final RecordLoader orderLoader = loadConfig.createLoader("orders", ORDERS_COLUMN_NAME); 655 | 656 | final String NEW_ORDERS_COLUMN_NAMES[] = {"no_o_id", "no_d_id", "no_w_id"}; 657 | final Record newOrderRecord = new Record(3); 658 | final RecordLoader newOrderLoader = loadConfig.createLoader("new_orders", NEW_ORDERS_COLUMN_NAMES); 659 | 660 | final String ORDER_LINE_COLUMN_NAME[] = {"ol_o_id", "ol_d_id", "ol_w_id", "ol_number", "ol_i_id", "ol_supply_w_id", "ol_delivery_d", "ol_quantity", "ol_amount", "ol_dist_info"}; 661 | final Record orderLineRecord = new Record(10); 662 | final RecordLoader orderLineLoader = loadConfig.createLoader("order_line", ORDER_LINE_COLUMN_NAME); 663 | 664 | if ((currentShard == shardId) || (shardId == 0)) { 665 | System.out.printf("Loading Orders for D=%d, W=%d\n", d_id, w_id); 666 | o_d_id = d_id; 667 | o_w_id = w_id; 668 | Util.initPermutation(); /* initialize permutation of customer numbers */ 669 | for (o_id = 1; o_id <= ORD_PER_DIST; o_id++) { 670 | 671 | /* Generate Order Data */ 672 | o_c_id = Util.getPermutation(); 673 | o_carrier_id = Util.randomNumber(1, 10); 674 | o_ol_cnt = Util.randomNumber(5, 15); 675 | 676 | //gettimestamp(datetime, STRFTIME_FORMAT, TIMESTAMP_LEN); Java Equivalent below? 677 | Date date = new java.sql.Date(System.currentTimeMillis()); 678 | 679 | 680 | if (o_id > 2100) { /* the last 900 orders have not been 681 | * delivered) */ 682 | /*EXEC SQL INSERT INTO 683 | orders 684 | values(:o_id,:o_d_id,:o_w_id,:o_c_id, 685 | :timestamp, 686 | NULL,:o_ol_cnt, 1);*/ 687 | 688 | orderRecord.reset(); 689 | orderRecord.add(o_id); 690 | orderRecord.add(o_d_id); 691 | orderRecord.add(o_w_id); 692 | orderRecord.add(o_c_id); 693 | orderRecord.add(date); 694 | orderRecord.add(null); 695 | orderRecord.add(o_ol_cnt); 696 | orderRecord.add(1); 697 | 698 | orderLoader.load(orderRecord); 699 | 700 | 701 | /*EXEC SQL INSERT INTO 702 | new_orders 703 | values(:o_id,:o_d_id,:o_w_id);*/ 704 | newOrderRecord.reset(); 705 | newOrderRecord.add(o_id); 706 | newOrderRecord.add(o_d_id); 707 | newOrderRecord.add(o_w_id); 708 | 709 | newOrderLoader.load(newOrderRecord); 710 | 711 | } else { 712 | /*EXEC SQL INSERT INTO 713 | orders 714 | values(:o_id,:o_d_id,:o_w_id,:o_c_id, 715 | :timestamp, 716 | :o_carrier_id,:o_ol_cnt, 1);*/ 717 | orderRecord.reset(); 718 | orderRecord.add(o_id); 719 | orderRecord.add(o_d_id); 720 | orderRecord.add(o_w_id); 721 | orderRecord.add(o_c_id); 722 | orderRecord.add(date); 723 | orderRecord.add(o_carrier_id); 724 | orderRecord.add(o_ol_cnt); 725 | orderRecord.add(1); 726 | 727 | orderLoader.load(orderRecord); 728 | 729 | } 730 | 731 | 732 | if (optionDebug) 733 | System.out.printf("OID = %d, CID = %d, DID = %d, WID = %d\n", 734 | o_id, o_c_id, o_d_id, o_w_id); 735 | 736 | for (ol = 1; ol <= o_ol_cnt; ol++) { 737 | /* Generate Order Line Data */ 738 | ol_i_id = Util.randomNumber(1, MAXITEMS); 739 | ol_supply_w_id = o_w_id; 740 | ol_quantity = 5; 741 | ol_amount = (float) 0.0; 742 | 743 | ol_dist_info = Util.makeAlphaString(24, 24); 744 | 745 | tmp_float = (float) ((float) (Util.randomNumber(10, 10000)) / 100.0); 746 | 747 | if (o_id > 2100) { 748 | /*EXEC SQL INSERT INTO 749 | order_line 750 | values(:o_id,:o_d_id,:o_w_id,:ol, 751 | :ol_i_id,:ol_supply_w_id, NULL, 752 | :ol_quantity,:ol_amount,:ol_dist_info);*/ 753 | orderLineRecord.reset(); 754 | orderLineRecord.add(o_id); 755 | orderLineRecord.add(o_d_id); 756 | orderLineRecord.add(o_w_id); 757 | orderLineRecord.add(ol); 758 | orderLineRecord.add(ol_i_id); 759 | orderLineRecord.add(ol_supply_w_id); 760 | orderLineRecord.add(null); 761 | orderLineRecord.add(ol_quantity); 762 | orderLineRecord.add(ol_amount); 763 | orderLineRecord.add(ol_dist_info); 764 | 765 | orderLineLoader.load(orderLineRecord); 766 | 767 | } else { 768 | /*EXEC SQL INSERT INTO 769 | order_line 770 | values(:o_id,:o_d_id,:o_w_id,:ol, 771 | :ol_i_id,:ol_supply_w_id, 772 | :timestamp, 773 | :ol_quantity,:tmp_float,:ol_dist_info);*/ 774 | orderLineRecord.reset(); 775 | orderLineRecord.add(o_id); 776 | orderLineRecord.add(o_d_id); 777 | orderLineRecord.add(o_w_id); 778 | orderLineRecord.add(ol); 779 | orderLineRecord.add(ol_i_id); 780 | orderLineRecord.add(ol_supply_w_id); 781 | orderLineRecord.add(date); 782 | orderLineRecord.add(ol_quantity); 783 | orderLineRecord.add(tmp_float); 784 | orderLineRecord.add(ol_dist_info); 785 | 786 | orderLineLoader.load(orderLineRecord); 787 | 788 | } 789 | 790 | if (optionDebug) { 791 | System.out.printf("OL = %d, IID = %d, QUAN = %d, AMT = %f\n", 792 | ol, ol_i_id, ol_quantity, ol_amount); 793 | } 794 | 795 | } 796 | if ((o_id % 100) == 0) { 797 | System.out.printf("."); 798 | 799 | if ((o_id % 1000) == 0) { 800 | System.out.printf(" %d\n", o_id); 801 | } 802 | } 803 | } 804 | 805 | orderLoader.close(); 806 | orderLineLoader.close(); 807 | newOrderLoader.close(); 808 | } 809 | 810 | 811 | System.out.printf("Orders Done.\n"); 812 | } 813 | 814 | 815 | } 816 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/NamedThreadFactory.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.util.concurrent.ThreadFactory; 4 | 5 | public class NamedThreadFactory implements ThreadFactory { 6 | 7 | private String namePrefix; 8 | 9 | private int nextID = 1; 10 | 11 | public NamedThreadFactory(String namePrefix) { 12 | this.namePrefix = namePrefix; 13 | } 14 | 15 | public Thread newThread(Runnable runnable) { 16 | int id; 17 | synchronized (this) { 18 | id = nextID++; 19 | 20 | } 21 | return new Thread(runnable, namePrefix + "-" + id); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/NewOrder.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.*; 4 | 5 | import org.slf4j.LoggerFactory; 6 | import org.slf4j.Logger; 7 | 8 | public class NewOrder implements TpccConstants { 9 | 10 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 11 | private static final boolean DEBUG = logger.isDebugEnabled(); 12 | private static final boolean TRACE = logger.isTraceEnabled(); 13 | private TpccStatements pStmts; 14 | 15 | private String s_dist_01 = null; 16 | private String s_dist_02 = null; 17 | private String s_dist_03 = null; 18 | private String s_dist_04 = null; 19 | private String s_dist_05 = null; 20 | private String s_dist_06 = null; 21 | private String s_dist_07 = null; 22 | private String s_dist_08 = null; 23 | private String s_dist_09 = null; 24 | private String s_dist_10 = null; 25 | 26 | String[] iname = new String[MAX_NUM_ITEMS]; 27 | String[] bg = new String[MAX_NUM_ITEMS]; 28 | float[] amt = new float[MAX_NUM_ITEMS]; 29 | float[] price = new float[MAX_NUM_ITEMS]; 30 | int[] stock = new int[MAX_NUM_ITEMS]; 31 | int[] ol_num_seq = new int[MAX_NUM_ITEMS]; 32 | boolean joins; 33 | 34 | /** 35 | * Constructor. 36 | * 37 | * @param pStmts 38 | */ 39 | public NewOrder(TpccStatements pStmts, boolean joins) { 40 | this.pStmts = pStmts; 41 | this.joins = joins; 42 | } 43 | 44 | private String pickDistInfo(String ol_dist_info, int ol_supply_w_id) { 45 | switch (ol_supply_w_id) { 46 | case 1: 47 | ol_dist_info = s_dist_01; 48 | break; 49 | case 2: 50 | ol_dist_info = s_dist_02; 51 | break; 52 | case 3: 53 | ol_dist_info = s_dist_03; 54 | break; 55 | case 4: 56 | ol_dist_info = s_dist_04; 57 | break; 58 | case 5: 59 | ol_dist_info = s_dist_05; 60 | break; 61 | case 6: 62 | ol_dist_info = s_dist_06; 63 | break; 64 | case 7: 65 | ol_dist_info = s_dist_07; 66 | break; 67 | case 8: 68 | ol_dist_info = s_dist_08; 69 | break; 70 | case 9: 71 | ol_dist_info = s_dist_09; 72 | break; 73 | case 10: 74 | ol_dist_info = s_dist_10; 75 | break; 76 | } 77 | 78 | return ol_dist_info; 79 | } 80 | 81 | public int neword(int t_num, /* thread number (not used) */ 82 | int w_id_arg, /* warehouse id */ 83 | int d_id_arg, /* district id */ 84 | int c_id_arg, /* customer id */ 85 | int o_ol_cnt_arg, /* number of items */ 86 | int o_all_local_arg, /* are all order lines local */ 87 | int itemid[], /* ids of items to be ordered */ 88 | int supware[], /* warehouses supplying items */ 89 | int qty[] 90 | ) throws SQLException { 91 | 92 | try { 93 | 94 | // Start a transaction. 95 | pStmts.setAutoCommit(false); 96 | if (DEBUG) logger.debug("Transaction: New Order"); 97 | int w_id = w_id_arg; 98 | int d_id = d_id_arg; 99 | int c_id = c_id_arg; 100 | int o_ol_cnt = o_ol_cnt_arg; 101 | int o_all_local = o_all_local_arg; 102 | float c_discount = 0; 103 | String c_last = null; 104 | String c_credit = null; 105 | float w_tax = 0; 106 | int d_next_o_id = 0; 107 | float d_tax = 0; 108 | int o_id = 0; 109 | String i_name = null; 110 | float i_price = 0; 111 | String i_data = null; 112 | int ol_i_id = 0; 113 | int s_quantity = 0; 114 | String s_data = null; 115 | 116 | String ol_dist_info = null; 117 | int ol_supply_w_id = 0; 118 | float ol_amount = 0; 119 | int ol_number = 0; 120 | int ol_quantity = 0; 121 | 122 | 123 | int min_num = 0; 124 | int i = 0, j = 0, tmp = 0, swp = 0; 125 | 126 | 127 | //struct timespec tbuf1,tbuf_start; 128 | //clock_t clk1,clk_start; 129 | 130 | 131 | //Timestamp 132 | java.sql.Timestamp time = new Timestamp(System.currentTimeMillis()); 133 | //String currentTimeStamp = "'" + time.toString() + "'"; 134 | String currentTimeStamp = time.toString(); 135 | 136 | 137 | // Changing how this works if joins = false 138 | if (joins) { 139 | //Get prepared statement 140 | //"SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = ? AND c_w_id = w_id AND c_d_id = ? AND c_id = ?" 141 | logger.debug("joins = true"); 142 | try { 143 | int column = 1; 144 | final PreparedStatement pstmt0 = pStmts.getStatement(0); 145 | pstmt0.setInt(column++, w_id); 146 | pstmt0.setInt(column++, w_id); 147 | pstmt0.setInt(column++, d_id); 148 | pstmt0.setInt(column++, c_id); 149 | if (TRACE) 150 | logger.trace("SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = " + w_id + " AND c_w_id = " + w_id + " AND c_d_id = " + d_id + " AND c_id = " + c_id); 151 | try (ResultSet rs = pstmt0.executeQuery()) { 152 | if (rs.next()) { 153 | c_discount = rs.getFloat(1); 154 | c_last = rs.getString(2); 155 | c_credit = rs.getString(3); 156 | w_tax = rs.getFloat(4); 157 | } 158 | } 159 | } catch (SQLException e) { 160 | logger.error("SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = " + w_id + " AND c_w_id = " + w_id + " AND c_d_id = " + d_id + " AND c_id = " + c_id, e); 161 | throw new Exception("NewOrder select transaction error", e); 162 | } 163 | } else { 164 | logger.debug("joins = false"); 165 | // Running 2 seperate queries here 166 | try { 167 | int column = 1; 168 | //SELECT c_discount, c_last, c_credit FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ? 169 | final PreparedStatement pstmt35 = pStmts.getStatement(35); 170 | pstmt35.setInt(column++, w_id); 171 | pstmt35.setInt(column++, d_id); 172 | pstmt35.setInt(column++, c_id); 173 | 174 | //SELECT w_tax FROM warehouse WHERE w_id = ? 175 | final PreparedStatement pstmt36 = pStmts.getStatement(36); 176 | pstmt36.setInt(1, w_id); 177 | 178 | if (TRACE) 179 | logger.trace("SELECT c_discount, c_last, c_credit FROM customer WHERE c_w_id = " + w_id + " AND c_d_id = " + d_id + " AND c_id = " + c_id); 180 | if (TRACE) 181 | logger.trace("SELECT w_tax FROM warehouse WHERE w_id = " + w_id); 182 | try (ResultSet rs0 = pstmt35.executeQuery()) { 183 | if (rs0.next()) { 184 | c_discount = rs0.getFloat(1); 185 | c_last = rs0.getString(2); 186 | c_credit = rs0.getString(3); 187 | } 188 | } 189 | try (ResultSet rs1 = pstmt36.executeQuery()) { 190 | if (rs1.next()) { 191 | w_tax = rs1.getFloat(1); 192 | } 193 | } 194 | } catch (SQLException e) { 195 | logger.error("SELECT c_discount, c_last, c_credit FROM customer WHERE c_w_id = " + w_id + " AND c_d_id = " + d_id + " AND c_id = " + c_id, e); 196 | throw new Exception("NewOrder (join = false) select transaction error", e); 197 | } 198 | } 199 | //Get prepared statement 200 | //"SELECT d_next_o_id, d_tax FROM district WHERE d_id = ? AND d_w_id = ? FOR UPDATE" 201 | 202 | try { 203 | final PreparedStatement pstmt1 = pStmts.getStatement(1); 204 | pstmt1.setInt(1, d_id); 205 | pstmt1.setInt(2, w_id); 206 | if (TRACE) 207 | logger.trace("SELECT d_next_o_id, d_tax FROM district WHERE d_id = " + d_id + " AND d_w_id = " + w_id + " FOR UPDATE"); 208 | try (ResultSet rs = pstmt1.executeQuery()) { 209 | if (rs.next()) { 210 | d_next_o_id = rs.getInt(1); 211 | d_tax = rs.getFloat(2); 212 | } else { 213 | logger.error("Failed to obtain d_next_o_id. No results to query: " 214 | + "SELECT d_next_o_id, d_tax FROM district WHERE d_id = " + d_id + " AND d_w_id = " + w_id + " FOR UPDATE"); 215 | } 216 | } 217 | } catch (SQLException e) { 218 | logger.error("SELECT d_next_o_id, d_tax FROM district WHERE d_id = " + d_id + " AND d_w_id = " + w_id + " FOR UPDATE", e); 219 | throw new Exception("Neworder select transaction error", e); 220 | } 221 | 222 | //Get prepared statement 223 | //"UPDATE district SET d_next_o_id = ? + 1 WHERE d_id = ? AND d_w_id = ?" 224 | 225 | try { 226 | final PreparedStatement pstmt2 = pStmts.getStatement(2); 227 | pstmt2.setInt(1, d_next_o_id); 228 | pstmt2.setInt(2, d_id); 229 | pstmt2.setInt(3, w_id); 230 | if (TRACE) 231 | logger.trace("UPDATE district SET d_next_o_id = " + d_next_o_id + " + 1 WHERE d_id = " + d_id + " AND d_w_id = " + w_id); 232 | pstmt2.executeUpdate(); 233 | 234 | 235 | } catch (SQLException e) { 236 | logger.error("UPDATE district SET d_next_o_id = " + d_next_o_id + " + 1 WHERE d_id = " + d_id + " AND d_w_id = " + w_id, e); 237 | throw new Exception("NewOrder update transaction error", e); 238 | } 239 | 240 | o_id = d_next_o_id; 241 | 242 | //Get prepared statement 243 | //"INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES(?, ?, ?, ?, ?, ?, ?)" 244 | 245 | try { 246 | final PreparedStatement pstmt3 = pStmts.getStatement(3); 247 | pstmt3.setInt(1, o_id); 248 | pstmt3.setInt(2, d_id); 249 | pstmt3.setInt(3, w_id); 250 | pstmt3.setInt(4, c_id); 251 | pstmt3.setString(5, currentTimeStamp); 252 | pstmt3.setInt(6, o_ol_cnt); 253 | pstmt3.setInt(7, o_all_local); 254 | if (TRACE) 255 | logger.trace("INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) " + 256 | "VALUES(" + o_id + "," + d_id + "," + w_id + "," + c_id + "," + currentTimeStamp + "," + o_ol_cnt + "," + o_all_local + ")"); 257 | pstmt3.executeUpdate(); 258 | 259 | 260 | } catch (SQLException e) { 261 | logger.error("INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) " + 262 | "VALUES(" + o_id + "," + d_id + "," + w_id + "," + c_id + "," + currentTimeStamp + "," + o_ol_cnt + "," + o_all_local + ")", e); 263 | throw new Exception("NewOrder insert transaction error", e); 264 | } 265 | 266 | //Get prepared statement 267 | //"INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) VALUES (?,?,?) 268 | try { 269 | final PreparedStatement pstmt4 = pStmts.getStatement(4); 270 | pstmt4.setInt(1, o_id); 271 | pstmt4.setInt(2, d_id); 272 | pstmt4.setInt(3, w_id); 273 | if (TRACE) 274 | logger.trace("INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) VALUES (" + o_id + "," + d_id + "," + w_id + ")"); 275 | pstmt4.executeUpdate(); 276 | 277 | 278 | } catch (SQLException e) { 279 | logger.error("INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) VALUES (" + o_id + "," + d_id + "," + w_id + ")", e); 280 | throw new Exception("NewOrder insert transaction error", e); 281 | } 282 | 283 | /* sort orders to avoid DeadLock */ 284 | for (i = 0; i < o_ol_cnt; i++) { 285 | ol_num_seq[i] = i; 286 | } 287 | 288 | for (i = 0; i < (o_ol_cnt - 1); i++) { 289 | tmp = (MAXITEMS + 1) * supware[ol_num_seq[i]] + itemid[ol_num_seq[i]]; 290 | min_num = i; 291 | for (j = i + 1; j < o_ol_cnt; j++) { 292 | if ((MAXITEMS + 1) * supware[ol_num_seq[j]] + itemid[ol_num_seq[j]] < tmp) { 293 | tmp = (MAXITEMS + 1) * supware[ol_num_seq[j]] + itemid[ol_num_seq[j]]; 294 | min_num = j; 295 | } 296 | } 297 | if (min_num != i) { 298 | swp = ol_num_seq[min_num]; 299 | ol_num_seq[min_num] = ol_num_seq[i]; 300 | ol_num_seq[i] = swp; 301 | } 302 | } 303 | 304 | for (ol_number = 1; ol_number <= o_ol_cnt; ol_number++) { 305 | ol_supply_w_id = supware[ol_num_seq[ol_number - 1]]; 306 | ol_i_id = itemid[ol_num_seq[ol_number - 1]]; 307 | ol_quantity = qty[ol_num_seq[ol_number - 1]]; 308 | 309 | /* EXEC SQL WHENEVER NOT FOUND GOTO invaliditem; */ 310 | //Get prepared statement 311 | //"SELECT i_price, i_name, i_data FROM item WHERE i_id = ?" 312 | 313 | try { 314 | final PreparedStatement pstmt5 = pStmts.getStatement(5); 315 | pstmt5.setInt(1, ol_i_id); 316 | if (TRACE) logger.trace("SELECT i_price, i_name, i_data FROM item WHERE i_id =" + ol_i_id); 317 | try (ResultSet rs = pstmt5.executeQuery()) { 318 | if (rs.next()) { 319 | i_price = rs.getFloat(1); 320 | i_name = rs.getString(2); 321 | i_data = rs.getString(3); 322 | } else { 323 | if (DEBUG) { 324 | logger.debug("No item found for item id " + ol_i_id); 325 | } 326 | throw new AbortedTransactionException(); 327 | } 328 | } 329 | } catch (SQLException e) { 330 | logger.error("SELECT i_price, i_name, i_data FROM item WHERE i_id =" + ol_i_id, e); 331 | throw new Exception("NewOrder select transaction error", e); 332 | } 333 | 334 | price[ol_num_seq[ol_number - 1]] = i_price; 335 | iname[ol_num_seq[ol_number - 1]] = i_name; 336 | 337 | //Get prepared statement 338 | //"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 stock WHERE s_i_id = ? AND s_w_id = ? FOR UPDATE" 339 | try { 340 | final PreparedStatement pstmt6 = pStmts.getStatement(6); 341 | pstmt6.setInt(1, ol_i_id); 342 | pstmt6.setInt(2, ol_supply_w_id); 343 | if (TRACE) 344 | logger.trace("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 " + 345 | "stock WHERE s_i_id = " + ol_i_id + " AND s_w_id = " + ol_supply_w_id + " FOR UPDATE"); 346 | 347 | try (ResultSet rs = pstmt6.executeQuery()) { 348 | if (rs.next()) { 349 | s_quantity = rs.getInt(1); 350 | s_data = rs.getString(2); 351 | s_dist_01 = rs.getString(3); 352 | s_dist_02 = rs.getString(4); 353 | s_dist_03 = rs.getString(5); 354 | s_dist_04 = rs.getString(6); 355 | s_dist_05 = rs.getString(7); 356 | s_dist_06 = rs.getString(8); 357 | s_dist_07 = rs.getString(9); 358 | s_dist_08 = rs.getString(10); 359 | s_dist_09 = rs.getString(11); 360 | s_dist_10 = rs.getString(12); 361 | } 362 | } 363 | 364 | } catch (SQLException e) { 365 | logger.error("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 " + 366 | "stock WHERE s_i_id = " + ol_i_id + " AND s_w_id = " + ol_supply_w_id + " FOR UPDATE", e); 367 | throw new Exception("NewOrder select transaction error", e); 368 | } 369 | 370 | ol_dist_info = pickDistInfo(ol_dist_info, d_id); /* pick correct * s_dist_xx */ 371 | 372 | stock[ol_num_seq[ol_number - 1]] = s_quantity; 373 | 374 | if ((i_data.contains("original")) && (s_data.contains("original"))) { 375 | bg[ol_num_seq[ol_number - 1]] = "B"; 376 | 377 | } else { 378 | bg[ol_num_seq[ol_number - 1]] = "G"; 379 | 380 | } 381 | 382 | if (s_quantity > ol_quantity) { 383 | s_quantity = s_quantity - ol_quantity; 384 | } else { 385 | s_quantity = s_quantity - ol_quantity + 91; 386 | } 387 | 388 | //Get the prepared statement 389 | //"UPDATE stock SET s_quantity = ? WHERE s_i_id = ? AND s_w_id = ?" 390 | try { 391 | final PreparedStatement pstmt7 = pStmts.getStatement(7); 392 | pstmt7.setInt(1, s_quantity); 393 | pstmt7.setInt(2, ol_i_id); 394 | pstmt7.setInt(3, ol_supply_w_id); 395 | if (TRACE) 396 | logger.trace("UPDATE stock SET s_quantity = " + s_quantity + " WHERE s_i_id = " + ol_i_id + " AND s_w_id = " + ol_supply_w_id); 397 | pstmt7.executeUpdate(); 398 | 399 | 400 | } catch (SQLException e) { 401 | logger.error("UPDATE stock SET s_quantity = " + s_quantity + " WHERE s_i_id = " + ol_i_id + " AND s_w_id = " + ol_supply_w_id, e); 402 | throw new Exception("NewOrder update transaction error", e); 403 | } 404 | 405 | ol_amount = ol_quantity * i_price * (1 + w_tax + d_tax) * (1 - c_discount); 406 | amt[ol_num_seq[ol_number - 1]] = ol_amount; 407 | 408 | 409 | //Get prepared statement 410 | //"INSERT INTO order_line (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 (?, ?, ?, ?, ?, ?, ?, ?, ?)" 411 | 412 | try { 413 | final PreparedStatement pstmt8 = pStmts.getStatement(8); 414 | pstmt8.setInt(1, o_id); 415 | pstmt8.setInt(2, d_id); 416 | pstmt8.setInt(3, w_id); 417 | pstmt8.setInt(4, ol_number); 418 | pstmt8.setInt(5, ol_i_id); 419 | pstmt8.setInt(6, ol_supply_w_id); 420 | pstmt8.setInt(7, ol_quantity); 421 | pstmt8.setFloat(8, ol_amount); 422 | pstmt8.setString(9, ol_dist_info); 423 | if (TRACE) 424 | logger.trace("INSERT INTO order_line (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) " + 425 | "VALUES (" + o_id + "," + d_id + "," + w_id + "," + ol_number + "," + ol_i_id + "," + ol_supply_w_id + "," + ol_quantity + "," 426 | + ol_amount + "," + ol_dist_info + ")"); 427 | pstmt8.executeUpdate(); 428 | 429 | 430 | } catch (SQLException e) { 431 | logger.error("INSERT INTO order_line (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) " + 432 | "VALUES (" + o_id + "," + d_id + "," + w_id + "," + ol_number + "," + ol_i_id + "," + ol_supply_w_id + "," + ol_quantity + "," 433 | + ol_amount + "," + ol_dist_info + ")", e); 434 | throw new Exception("NewOrder insert transaction error", e); 435 | } 436 | 437 | } 438 | // Commit. 439 | pStmts.commit(); 440 | 441 | return 1; 442 | } catch (AbortedTransactionException ate) { 443 | // Rollback if an aborted transaction, they are intentional in some percentage of cases. 444 | if (logger.isDebugEnabled()) { 445 | logger.debug("Caught AbortedTransactionException"); 446 | } 447 | pStmts.rollback(); 448 | return 1; // this is not an error! 449 | } catch (Exception e) { 450 | logger.error("New Order error", e); 451 | pStmts.rollback(); 452 | return 0; 453 | } 454 | 455 | 456 | } 457 | } 458 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/OrderStat.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | 6 | import org.slf4j.LoggerFactory; 7 | import org.slf4j.Logger; 8 | 9 | public class OrderStat implements TpccConstants { 10 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 11 | private static final boolean DEBUG = logger.isDebugEnabled(); 12 | private static final boolean TRACE = logger.isTraceEnabled(); 13 | 14 | private TpccStatements pStmts; 15 | 16 | public OrderStat(TpccStatements pStmts) { 17 | this.pStmts = pStmts; 18 | } 19 | 20 | public int ordStat(int t_num, 21 | int w_id_arg, /* warehouse id */ 22 | int d_id_arg, /* district id */ 23 | int byname, /* select by c_id or c_last? */ 24 | int c_id_arg, /* customer id */ 25 | String c_last_arg /* customer last name, format? */ 26 | ) { 27 | 28 | try { 29 | 30 | pStmts.setAutoCommit(false); 31 | if (DEBUG) logger.debug("Transaction: ORDER STAT"); 32 | int w_id = w_id_arg; 33 | int d_id = d_id_arg; 34 | int c_id = c_id_arg; 35 | int c_d_id = d_id; 36 | int c_w_id = w_id; 37 | String c_first = null; 38 | String c_middle = null; 39 | String c_last = null; 40 | float c_balance = 0; 41 | int o_id = 0; 42 | String o_entry_d = null; 43 | int o_carrier_id = 0; 44 | int ol_i_id = 0; 45 | int ol_supply_w_id = 0; 46 | int ol_quantity = 0; 47 | float ol_amount = 0; 48 | String ol_delivery_d = null; 49 | int namecnt = 0; 50 | 51 | int n = 0; 52 | 53 | if (byname > 0) { 54 | 55 | c_last = c_last_arg; 56 | 57 | //Get Prepared Statement 58 | //"SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?" 59 | try { 60 | pStmts.getStatement(20).setInt(1, c_w_id); 61 | pStmts.getStatement(20).setInt(2, c_d_id); 62 | pStmts.getStatement(20).setString(3, c_last); 63 | if (TRACE) 64 | logger.trace("SELECT count(c_id) FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last); 65 | 66 | ResultSet rs = pStmts.getStatement(20).executeQuery(); 67 | if (rs.next()) { 68 | namecnt = rs.getInt(1); 69 | } 70 | 71 | rs.close(); 72 | } catch (SQLException e) { 73 | logger.error("SELECT count(c_id) FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last, e); 74 | throw new Exception("OrderStat Select transaction error", e); 75 | } 76 | 77 | 78 | //Get the prepared statement 79 | //"SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first" 80 | 81 | try { 82 | pStmts.getStatement(21).setInt(1, c_w_id); 83 | pStmts.getStatement(21).setInt(2, c_d_id); 84 | pStmts.getStatement(21).setString(3, c_last); 85 | if (TRACE) logger.trace("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE " + 86 | "c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last + " ORDER BY c_first"); 87 | 88 | ResultSet rs = pStmts.getStatement(21).executeQuery(); 89 | if (namecnt % 2 == 1) { //?? Check 90 | namecnt++; 91 | } /* Locate midpoint customer; */ 92 | 93 | // Use a for loop to find midpoint customer based on namecnt. 94 | for (n = 0; n < namecnt / 2; n++) { 95 | rs.next(); 96 | c_balance = rs.getFloat(1); 97 | c_first = rs.getString(2); 98 | c_middle = rs.getString(3); 99 | c_last = rs.getString(4); 100 | } 101 | 102 | rs.close(); 103 | } catch (SQLException e) { 104 | logger.error("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE " + 105 | "c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last + " ORDER BY c_first", e); 106 | throw new Exception("OrderStat Select transaction error", e); 107 | } 108 | 109 | } else { /* by number */ 110 | 111 | //Get Transaction Number 112 | //"SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?" 113 | try { 114 | pStmts.getStatement(22).setInt(1, c_w_id); 115 | pStmts.getStatement(22).setInt(2, c_d_id); 116 | pStmts.getStatement(22).setInt(3, c_id); 117 | if (TRACE) logger.trace("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE " + 118 | "c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id); 119 | ResultSet rs = pStmts.getStatement(22).executeQuery(); 120 | if (rs.next()) { 121 | c_balance = rs.getFloat(1); 122 | c_first = rs.getString(2); 123 | c_middle = rs.getString(3); 124 | c_last = rs.getString(4); 125 | } 126 | 127 | rs.close(); 128 | } catch (SQLException e) { 129 | logger.error("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE " + 130 | "c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id, e); 131 | throw new Exception("OrderStat select transaction error", e); 132 | } 133 | 134 | } 135 | 136 | /* find the most recent order for this customer */ 137 | 138 | //Get prepared statement 139 | //"SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? AND o_id = (SELECT MAX(o_id) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ?)" 140 | try { 141 | pStmts.getStatement(23).setInt(1, c_w_id); 142 | pStmts.getStatement(23).setInt(2, c_d_id); 143 | pStmts.getStatement(23).setInt(3, c_id); 144 | pStmts.getStatement(23).setInt(4, c_w_id); 145 | pStmts.getStatement(23).setInt(5, c_d_id); 146 | pStmts.getStatement(23).setInt(6, c_id); 147 | if (TRACE) logger.trace("SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders " + 148 | "WHERE o_w_id = " + c_w_id + " AND o_d_id = " + c_d_id + " AND o_c_id = " + c_id + " AND o_id = " + 149 | "(SELECT MAX(o_id) FROM orders WHERE o_w_id = " + c_w_id + " AND o_d_id = " + c_d_id + " AND o_c_id = " + c_id); 150 | ResultSet rs = pStmts.getStatement(23).executeQuery(); 151 | if (rs.next()) { 152 | o_id = rs.getInt(1); 153 | o_entry_d = rs.getString(2); 154 | o_carrier_id = rs.getInt(3); 155 | } 156 | 157 | rs.close(); 158 | } catch (SQLException e) { 159 | logger.error("SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders " + 160 | "WHERE o_w_id = " + c_w_id + " AND o_d_id = " + c_d_id + " AND o_c_id = " + c_id + " AND o_id = " + 161 | "(SELECT MAX(o_id) FROM orders WHERE o_w_id = " + c_w_id + " AND o_d_id = " + c_d_id + " AND o_c_id = " + c_id, e); 162 | throw new Exception("OrderState select transaction error", e); 163 | } 164 | 165 | 166 | //Get prepared statement 167 | //"SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id = ?" 168 | try { 169 | pStmts.getStatement(24).setInt(1, c_w_id); 170 | pStmts.getStatement(24).setInt(2, c_d_id); 171 | pStmts.getStatement(24).setInt(3, o_id); 172 | if (TRACE) 173 | logger.trace("SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line " + 174 | "WHERE ol_w_id = " + c_w_id + " AND ol_d_id = " + c_d_id + " AND ol_o_id = " + o_id); 175 | ResultSet rs = pStmts.getStatement(24).executeQuery(); 176 | while (rs.next()) { 177 | ol_i_id = rs.getInt(1); 178 | ol_supply_w_id = rs.getInt(2); 179 | ol_quantity = rs.getInt(3); 180 | ol_amount = rs.getFloat(4); 181 | ol_delivery_d = rs.getString(5); 182 | } 183 | 184 | rs.close(); 185 | } catch (SQLException e) { 186 | logger.error("SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line " + 187 | "WHERE ol_w_id = " + c_w_id + " AND ol_d_id = " + c_d_id + " AND ol_o_id = " + o_id, e); 188 | throw new Exception("OrderStat select transaction error", e); 189 | } 190 | 191 | // Commit. 192 | pStmts.commit(); 193 | 194 | return 1; 195 | } catch (Exception e) { 196 | try { 197 | // Rollback if an aborted transaction, they are intentional in some percentage of cases. 198 | pStmts.rollback(); 199 | return 0; 200 | } catch (Throwable th) { 201 | throw new RuntimeException("Order stat error", th); 202 | } finally { 203 | logger.error("Order stat error", e); 204 | } 205 | } 206 | 207 | 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Payment.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | import java.sql.Timestamp; 6 | 7 | import org.slf4j.LoggerFactory; 8 | import org.slf4j.Logger; 9 | 10 | public class Payment implements TpccConstants { 11 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 12 | private static final boolean DEBUG = logger.isDebugEnabled(); 13 | private static final boolean TRACE = logger.isTraceEnabled(); 14 | 15 | private TpccStatements pStmts; 16 | 17 | public Payment(TpccStatements pStmts) { 18 | this.pStmts = pStmts; 19 | } 20 | 21 | public int payment(int t_num, 22 | int w_id_arg, /* warehouse id */ 23 | int d_id_arg, /* district id */ 24 | int byname, /* select by c_id or c_last? */ 25 | int c_w_id_arg, 26 | int c_d_id_arg, 27 | int c_id_arg, /* customer id */ 28 | String c_last_arg, /* customer last name */ 29 | float h_amount_arg /* payment amount */ 30 | ) { 31 | try { 32 | // Start a transaction. 33 | pStmts.setAutoCommit(false); 34 | if (DEBUG) logger.debug("Transaction: PAYMENT"); 35 | int w_id = w_id_arg; 36 | int d_id = d_id_arg; 37 | int c_id = c_id_arg; 38 | String w_name = null; 39 | String w_street_1 = null; 40 | String w_street_2 = null; 41 | String w_city = null; 42 | String w_state = null; 43 | String w_zip = null; 44 | 45 | int c_d_id = c_d_id_arg; 46 | int c_w_id = c_w_id_arg; 47 | String c_first = null; 48 | String c_middle = null; 49 | String c_last = null; 50 | String c_street_1 = null; 51 | String c_street_2 = null; 52 | String c_city = null; 53 | String c_state = null; 54 | String c_zip = null; 55 | String c_phone = null; 56 | String c_since = null; 57 | String c_credit = null; 58 | 59 | 60 | int c_credit_lim = 0; 61 | float c_discount = 0; 62 | float c_balance = 0; 63 | String c_data = null; 64 | String c_new_data = null; 65 | 66 | 67 | float h_amount = h_amount_arg; 68 | String h_data = null; 69 | String d_name = null; 70 | String d_street_1 = null; 71 | String d_street_2 = null; 72 | String d_city = null; 73 | String d_state = null; 74 | String d_zip = null; 75 | 76 | 77 | int namecnt = 0; 78 | int n; 79 | int proceed = 0; 80 | 81 | //Time Stamp 82 | final Timestamp currentTimeStamp = new Timestamp(System.currentTimeMillis()); 83 | 84 | proceed = 1; 85 | 86 | //Get prepared statement 87 | //"UPDATE warehouse SET w_ytd = w_ytd + ? WHERE w_id = ?" 88 | try { 89 | 90 | pStmts.getStatement(9).setFloat(1, h_amount); 91 | pStmts.getStatement(9).setInt(2, w_id); 92 | if (TRACE) logger.trace("UPDATE warehouse SET w_ytd = w_ytd + " + h_amount + " WHERE w_id = " + w_id); 93 | pStmts.getStatement(9).executeUpdate(); 94 | 95 | } catch (SQLException e) { 96 | logger.error("UPDATE warehouse SET w_ytd = w_ytd + " + h_amount + " WHERE w_id = " + w_id, e); 97 | throw new Exception("Payment Update transaction error", e); 98 | } 99 | 100 | proceed = 2; 101 | //Get prepared statement 102 | //"SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = ?" 103 | 104 | try { 105 | pStmts.getStatement(10).setInt(1, w_id); 106 | if (TRACE) 107 | logger.trace("SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = " + w_id); 108 | ResultSet rs = pStmts.getStatement(10).executeQuery(); 109 | if (rs.next()) { 110 | w_street_1 = rs.getString(1); 111 | w_street_2 = rs.getString(2); 112 | w_city = rs.getString(3); 113 | w_state = rs.getString(4); 114 | w_zip = rs.getString(5); 115 | w_name = rs.getString(6); 116 | } 117 | 118 | rs.close(); 119 | 120 | } catch (SQLException e) { 121 | logger.error("SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = " + w_id, e); 122 | throw new Exception("Payment select transaction error", e); 123 | } 124 | 125 | proceed = 3; 126 | //Get prepared statement 127 | //"UPDATE district SET d_ytd = d_ytd + ? WHERE d_w_id = ? AND d_id = ?" 128 | try { 129 | pStmts.getStatement(11).setFloat(1, h_amount); 130 | pStmts.getStatement(11).setInt(2, w_id); 131 | pStmts.getStatement(11).setInt(3, d_id); 132 | if (TRACE) 133 | logger.trace("UPDATE district SET d_ytd = d_ytd + " + h_amount + " WHERE d_w_id = " + w_id + " AND d_id = " + d_id); 134 | pStmts.getStatement(11).executeUpdate(); 135 | 136 | } catch (SQLException e) { 137 | logger.error("UPDATE district SET d_ytd = d_ytd + " + h_amount + " WHERE d_w_id = " + w_id + " AND d_id = " + d_id, e); 138 | throw new Exception("Payment update transaction error", e); 139 | } 140 | 141 | proceed = 4; 142 | //Get prepared statement 143 | //"SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = ? AND d_id = ?" 144 | 145 | try { 146 | pStmts.getStatement(12).setInt(1, w_id); 147 | pStmts.getStatement(12).setInt(2, d_id); 148 | if (TRACE) 149 | logger.trace("SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = " + w_id + " AND d_id = " + d_id); 150 | ResultSet rs = pStmts.getStatement(12).executeQuery(); 151 | if (rs.next()) { 152 | d_street_1 = rs.getString(1); 153 | d_street_2 = rs.getString(2); 154 | d_city = rs.getString(3); 155 | d_state = rs.getString(4); 156 | d_zip = rs.getString(5); 157 | d_name = rs.getString(6); 158 | } 159 | 160 | rs.close(); 161 | } catch (SQLException e) { 162 | logger.error("SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = " + w_id + " AND d_id = " + d_id, e); 163 | throw new Exception("Payment select transaction error", e); 164 | } 165 | 166 | if (byname >= 1) { 167 | 168 | c_last = c_last_arg; 169 | 170 | proceed = 5; 171 | //Get prepared statement 172 | //"SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?" 173 | 174 | try { 175 | pStmts.getStatement(13).setInt(1, c_w_id); 176 | pStmts.getStatement(13).setInt(2, c_d_id); 177 | pStmts.getStatement(13).setString(3, c_last); 178 | if (TRACE) 179 | logger.trace("SELECT count(c_id) FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last); 180 | ResultSet rs = pStmts.getStatement(13).executeQuery(); 181 | if (rs.next()) { 182 | namecnt = rs.getInt(1); 183 | } 184 | 185 | rs.close(); 186 | } catch (SQLException e) { 187 | logger.error("SELECT count(c_id) FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last, e); 188 | throw new Exception("Payment select transaction error", e); 189 | } 190 | 191 | //Get prepared Transaction 192 | //"SELECT c_id FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first" 193 | 194 | try { 195 | pStmts.getStatement(14).setInt(1, c_w_id); 196 | pStmts.getStatement(14).setInt(2, c_d_id); 197 | pStmts.getStatement(14).setString(3, c_last); 198 | if (TRACE) 199 | logger.trace("SELECT c_id FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last + " ORDER BY c_first"); 200 | 201 | if (namecnt % 2 == 1) { 202 | namecnt++; /* Locate midpoint customer; */ 203 | } 204 | 205 | ResultSet rs = pStmts.getStatement(14).executeQuery(); 206 | for (n = 0; n < namecnt / 2; n++) { 207 | if (rs.next()) { 208 | //SUCCESS 209 | c_id = rs.getInt(1); 210 | } else { 211 | throw new IllegalStateException(); 212 | } 213 | } 214 | rs.close(); 215 | 216 | } catch (SQLException e) { 217 | logger.error("SELECT c_id FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_last = " + c_last + " ORDER BY c_first", e); 218 | throw new Exception("Payment select transaction error", e); 219 | } 220 | 221 | } 222 | 223 | proceed = 6; 224 | 225 | //Get the prepared statement 226 | //"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_since FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ? FOR UPDATE" 227 | try { 228 | pStmts.getStatement(15).setInt(1, c_w_id); 229 | pStmts.getStatement(15).setInt(2, c_d_id); 230 | pStmts.getStatement(15).setInt(3, c_id); 231 | if (TRACE) 232 | logger.trace("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_since FROM customer " + 233 | "WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id + " FOR UPDATE"); 234 | ResultSet rs = pStmts.getStatement(15).executeQuery(); 235 | if (rs.next()) { 236 | c_first = rs.getString(1); 237 | c_middle = rs.getString(2); 238 | c_last = rs.getString(3); 239 | c_street_1 = rs.getString(4); 240 | c_street_2 = rs.getString(5); 241 | c_city = rs.getString(6); 242 | c_state = rs.getString(7); 243 | c_zip = rs.getString(8); 244 | c_phone = rs.getString(9); 245 | c_credit = rs.getString(10); 246 | c_credit_lim = rs.getInt(11); 247 | c_discount = rs.getFloat(12); 248 | c_balance = rs.getFloat(13); 249 | c_since = rs.getString(14); 250 | } 251 | 252 | rs.close(); 253 | 254 | } catch (SQLException e) { 255 | logger.error("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_since FROM customer " + 256 | "WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id + " FOR UPDATE", e); 257 | throw new Exception("Payment select transaction error", e); 258 | } 259 | 260 | c_balance += h_amount; 261 | 262 | if (c_credit != null) { 263 | if (c_credit.contains("BC")) { 264 | proceed = 7; 265 | //Get Prepared Statement 266 | //"SELECT c_data FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?" 267 | try { 268 | pStmts.getStatement(16).setInt(1, c_w_id); 269 | pStmts.getStatement(16).setInt(2, c_d_id); 270 | pStmts.getStatement(16).setInt(3, c_id); 271 | if (TRACE) 272 | logger.trace("SELECT c_data FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id); 273 | ResultSet rs = pStmts.getStatement(16).executeQuery(); 274 | if (rs.next()) { 275 | c_data = rs.getString(1); 276 | } 277 | 278 | rs.close(); 279 | } catch (SQLException e) { 280 | logger.error("SELECT c_data FROM customer WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id, e); 281 | throw new Exception("Payment select transaction error", e); 282 | } 283 | 284 | //TODO: c_new_data is never used - this is a bug ported exactly from the original code 285 | c_new_data = String.format("| %d %d %d %d %d $%f %s %s", c_id, c_d_id, c_w_id, d_id, w_id, h_amount, currentTimeStamp.toString(), c_data); 286 | 287 | //TODO: fix this - causes index out of bounds exceptions 288 | //c_new_data = ( c_new_data + c_data.substring(0, (500 - c_new_data.length()) ) ); 289 | 290 | proceed = 8; 291 | //Get prepared statement 292 | //"UPDATE customer SET c_balance = ?, c_data = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?" 293 | try { 294 | //System.out.print("Executed UPDATE.\n"); 295 | pStmts.getStatement(17).setFloat(1, c_balance); 296 | pStmts.getStatement(17).setString(2, c_data); 297 | pStmts.getStatement(17).setInt(3, c_w_id); 298 | pStmts.getStatement(17).setInt(4, c_d_id); 299 | pStmts.getStatement(17).setInt(5, c_id); 300 | if (TRACE) 301 | logger.trace("UPDATE customer SET c_balance = " + c_balance + ", c_data = " + c_data + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id); 302 | pStmts.getStatement(17).executeUpdate(); 303 | 304 | } catch (SQLException e) { 305 | logger.error("UPDATE customer SET c_balance = " + c_balance + ", c_data = " + c_data + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id, e); 306 | throw new Exception("Payment update transaction error", e); 307 | } 308 | 309 | 310 | } else { 311 | proceed = 9; 312 | //Get prepared statement 313 | //"UPDATE customer SET c_balance = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?" 314 | 315 | try { 316 | pStmts.getStatement(18).setFloat(1, c_balance); 317 | pStmts.getStatement(18).setInt(2, c_w_id); 318 | pStmts.getStatement(18).setInt(3, c_d_id); 319 | pStmts.getStatement(18).setInt(4, c_id); 320 | if (TRACE) 321 | logger.trace("UPDATE customer SET c_balance = " + c_balance + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id); 322 | pStmts.getStatement(18).executeUpdate(); 323 | 324 | } catch (SQLException e) { 325 | logger.error("UPDATE customer SET c_balance = " + c_balance + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id, e); 326 | throw new Exception("Payment update transaction error", e); 327 | } 328 | 329 | } 330 | } else { 331 | proceed = 9; 332 | //Get prepared statement 333 | //"UPDATE customer SET c_balance = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?" 334 | 335 | try { 336 | pStmts.getStatement(18).setFloat(1, c_balance); 337 | pStmts.getStatement(18).setInt(2, c_w_id); 338 | pStmts.getStatement(18).setInt(3, c_d_id); 339 | pStmts.getStatement(18).setInt(4, c_id); 340 | if (TRACE) 341 | logger.trace("UPDATE customer SET c_balance = " + c_balance + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id); 342 | pStmts.getStatement(18).executeUpdate(); 343 | 344 | } catch (SQLException e) { 345 | logger.error("UPDATE customer SET c_balance = " + c_balance + " WHERE c_w_id = " + c_w_id + " AND c_d_id = " + c_d_id + " AND c_id = " + c_id, e); 346 | throw new Exception("Payment update transaction error", e); 347 | } 348 | 349 | } 350 | 351 | h_data = h_data + '\0' + d_name + ' ' + ' ' + ' ' + ' ' + '\0'; 352 | 353 | proceed = 10; 354 | //Get prepared statement 355 | //"INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES(?, ?, ?, ?, ?, ?, ?, ?)" 356 | try { 357 | pStmts.getStatement(19).setInt(1, c_d_id); 358 | pStmts.getStatement(19).setInt(2, c_w_id); 359 | pStmts.getStatement(19).setInt(3, c_id); 360 | pStmts.getStatement(19).setInt(4, d_id); 361 | pStmts.getStatement(19).setInt(5, w_id); 362 | pStmts.getStatement(19).setString(6, currentTimeStamp.toString()); 363 | pStmts.getStatement(19).setFloat(7, h_amount); 364 | pStmts.getStatement(19).setString(8, h_data); 365 | if (TRACE) 366 | logger.trace("INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data)" + 367 | " VALUES( " + c_d_id + "," + c_w_id + "," + c_id + "," + d_id + "," + w_id + "," + currentTimeStamp.toString() + "," + h_amount + "," /*+ h_data*/); 368 | pStmts.getStatement(19).executeUpdate(); 369 | 370 | } catch (SQLException e) { 371 | logger.error("INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data)" + 372 | " VALUES( " + c_d_id + "," + c_w_id + "," + c_id + "," + d_id + "," + w_id + "," + currentTimeStamp.toString() + "," + h_amount + "," /*+ h_data*/, e); 373 | throw new Exception("Payment insert transaction error", e); 374 | } 375 | 376 | 377 | // Commit. 378 | pStmts.commit(); 379 | 380 | return 1; 381 | 382 | 383 | } catch (Exception e) { 384 | try { 385 | // Rollback if an aborted transaction, they are intentional in some percentage of cases. 386 | pStmts.rollback(); 387 | return 0; 388 | } catch (Throwable th) { 389 | throw new RuntimeException("Payment error", th); 390 | } finally { 391 | logger.error("Payment error", e); 392 | } 393 | } 394 | 395 | 396 | } 397 | 398 | } 399 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/RtHist.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | public class RtHist implements TpccConstants { 4 | 5 | private static final int MAXREC = 20; 6 | private static final int REC_PER_SEC = 1000; 7 | private static int[][] total_hist = new int[5][MAXREC * REC_PER_SEC]; 8 | private static int[][] cur_hist = new int[5][MAXREC * REC_PER_SEC]; 9 | 10 | 11 | //CHECK: These are externs so should they be public???? 12 | public static double[] max_rt = new double[10]; 13 | public static double[] cur_max_rt = new double[10]; 14 | 15 | 16 | /* initialize */ 17 | public static void histInit() { 18 | int i = 0; 19 | int j = 0; 20 | 21 | for (i = 0; i < 5; i++) { 22 | for (j = 0; j < (MAXREC * REC_PER_SEC); j++) { 23 | total_hist[i][j] = cur_hist[i][j] = 0; 24 | } 25 | } 26 | } 27 | 28 | /* incliment matched one */ 29 | public static void histInc(int transaction, double rtclk) { 30 | int i = 0; 31 | i = (int) (rtclk * (double) REC_PER_SEC); 32 | if (i >= (MAXREC * REC_PER_SEC)) { 33 | i = (MAXREC * REC_PER_SEC) - 1; 34 | } 35 | if (rtclk > cur_max_rt[transaction]) { 36 | cur_max_rt[transaction] = rtclk; 37 | } 38 | ++cur_hist[transaction][i]; 39 | //System.out.print("In: %.3f, trx: %d, Added %d\n", rtclk, transaction, i); 40 | } 41 | 42 | /* check point, add on total histgram, return 90% line */ 43 | public static double histCkp(int transaction) { 44 | int i; 45 | int total, tmp, line, line_set; 46 | 47 | total = tmp = line_set = 0; 48 | line = MAXREC * REC_PER_SEC; 49 | for (i = 0; i < (MAXREC * REC_PER_SEC); i++) { 50 | total += cur_hist[transaction][i]; 51 | //total += i; 52 | } 53 | for (i = 0; i < (MAXREC * REC_PER_SEC); i++) { 54 | tmp += cur_hist[transaction][i]; 55 | //tmp += i; 56 | total_hist[transaction][i] += cur_hist[transaction][i]; 57 | cur_hist[transaction][i] = 0; 58 | if ((tmp >= (total * 99 / 100)) && (line_set == 0)) { 59 | line = i; 60 | line_set = 1; 61 | } 62 | } 63 | //System.out.print("CKP: trx: %d line: %d total: %d tmp: %d ret: %.3f\n", transaction, line, total, tmp,(double)(line)/(double)(REC_PER_SEC)); 64 | return ((double) (line) / (double) (REC_PER_SEC)); 65 | } 66 | 67 | public static void histReport() { 68 | int i = 0; 69 | int j = 0; 70 | int[] total = new int[5]; 71 | int[] tmp = new int[5]; 72 | int[] line = new int[5]; 73 | 74 | for (j = 0; j < 5; j++) { 75 | total[j] = tmp[j] = 0; 76 | line[j] = MAXREC * REC_PER_SEC; 77 | for (i = 0; i < (MAXREC * REC_PER_SEC); i++) { 78 | total[j] += total_hist[j][i]; 79 | } 80 | for (i = (MAXREC * REC_PER_SEC) - 1; i >= 0; i--) { 81 | tmp[j] += total_hist[j][i]; 82 | if ((tmp[j] * 10) <= total[j]) { 83 | line[j] = i; 84 | } 85 | } 86 | } 87 | System.out.print("\n\n"); 88 | 89 | for (j = 0; j < 5; j++) { 90 | switch (j) { 91 | case 0: 92 | System.out.print("\n1.New-Order\n\n"); 93 | break; 94 | case 1: 95 | System.out.print("\n2.Payment\n\n"); 96 | break; 97 | case 2: 98 | System.out.print("\n3.Order-Status\n\n"); 99 | break; 100 | case 3: 101 | System.out.print("\n4.Delivery\n\n"); 102 | break; 103 | case 4: 104 | System.out.print("\n5.Stock-Level\n\n"); 105 | } 106 | for (i = 0; (i < (MAXREC * REC_PER_SEC)) && (i <= line[j] * 4); i++) { 107 | System.out.printf("%3.2f, %6d\n", (double) (i + 1) / (double) (REC_PER_SEC), total_hist[j][i]); 108 | } 109 | System.out.print("\n"); 110 | } 111 | 112 | System.out.print("\n<90th Percentile RT (MaxRT)>\n"); 113 | for (j = 0; j < 5; j++) { 114 | switch (j) { 115 | case 0: 116 | System.out.print(" New-Order : "); 117 | break; 118 | case 1: 119 | System.out.print(" Payment : "); 120 | break; 121 | case 2: 122 | System.out.print("Order-Status : "); 123 | break; 124 | case 3: 125 | System.out.print(" Delivery : "); 126 | break; 127 | case 4: 128 | System.out.print(" Stock-Level : "); 129 | } 130 | System.out.printf("%3.2f (%.2f)\n", (double) (line[j]) / (double) (REC_PER_SEC), max_rt[j]); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Slev.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.sql.ResultSet; 4 | import java.sql.SQLException; 5 | 6 | import org.slf4j.LoggerFactory; 7 | import org.slf4j.Logger; 8 | 9 | public class Slev implements TpccConstants { 10 | private static final Logger logger = LoggerFactory.getLogger(Driver.class); 11 | private static final boolean DEBUG = logger.isDebugEnabled(); 12 | private static final boolean TRACE = logger.isTraceEnabled(); 13 | 14 | private TpccStatements pStmts; 15 | 16 | public Slev(TpccStatements pStms) { 17 | this.pStmts = pStms; 18 | } 19 | 20 | 21 | public int slev(int t_num, 22 | int w_id_arg, /* warehouse id */ 23 | int d_id_arg, /* district id */ 24 | int level_arg /* stock level */ 25 | ) { 26 | try { 27 | pStmts.setAutoCommit(false); 28 | 29 | if (DEBUG) logger.debug("Transaction: SLEV"); 30 | int w_id = w_id_arg; 31 | int d_id = d_id_arg; 32 | int level = level_arg; 33 | int d_next_o_id = 0; 34 | int i_count = 0; 35 | int ol_i_id = 0; 36 | 37 | //Get prepared statement 38 | //"SELECT d_next_o_id FROM district WHERE d_id = ? AND d_w_id = ?" 39 | 40 | try { 41 | pStmts.getStatement(32).setInt(1, d_id); 42 | pStmts.getStatement(32).setInt(2, w_id); 43 | if (TRACE) 44 | logger.trace("SELECT d_next_o_id FROM district WHERE d_id = " + d_id + " AND d_w_id = " + w_id); 45 | ResultSet rs = pStmts.getStatement(32).executeQuery(); 46 | 47 | if (rs.next()) { 48 | d_next_o_id = rs.getInt(1); 49 | } 50 | rs.close(); 51 | } catch (SQLException e) { 52 | logger.error("SELECT d_next_o_id FROM district WHERE d_id = " + d_id + " AND d_w_id = " + w_id, e); 53 | throw new Exception("Slev select transaction error", e); 54 | } 55 | 56 | //Get prepared statement 57 | //"SELECT DISTINCT ol_i_id FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id < ? AND ol_o_id >= (? - 20)" 58 | try { 59 | pStmts.getStatement(33).setInt(1, w_id); 60 | pStmts.getStatement(33).setInt(2, d_id); 61 | pStmts.getStatement(33).setInt(3, d_next_o_id); 62 | pStmts.getStatement(33).setInt(4, d_next_o_id); 63 | if (TRACE) 64 | logger.trace("SELECT DISTINCT ol_i_id FROM order_line WHERE ol_w_id = " + w_id + " AND ol_d_id = " + d_id + " AND ol_o_id < " + d_next_o_id + 65 | " AND ol_o_id >= (" + d_next_o_id + " - 20)"); 66 | ResultSet rs = pStmts.getStatement(32).executeQuery(); 67 | 68 | while (rs.next()) { 69 | ol_i_id = rs.getInt(1); 70 | } 71 | 72 | rs.close(); 73 | } catch (SQLException e) { 74 | logger.error("SELECT DISTINCT ol_i_id FROM order_line WHERE ol_w_id = " + w_id + " AND ol_d_id = " + d_id + " AND ol_o_id < " + d_next_o_id + 75 | " AND ol_o_id >= (" + d_next_o_id + " - 20)", e); 76 | throw new Exception("Slev select transaction error", e); 77 | } 78 | 79 | //Get prepared statement 80 | //"SELECT count(*) FROM stock WHERE s_w_id = ? AND s_i_id = ? AND s_quantity < ?" 81 | 82 | try { 83 | pStmts.getStatement(34).setInt(1, w_id); 84 | pStmts.getStatement(34).setInt(2, ol_i_id); 85 | pStmts.getStatement(34).setInt(3, level); 86 | if (TRACE) 87 | logger.trace("SELECT count(*) FROM stock WHERE s_w_id = " + w_id + " AND s_i_id = " + ol_i_id + " AND s_quantity < " + level); 88 | ResultSet rs = pStmts.getStatement(34).executeQuery(); 89 | if (rs.next()) { 90 | i_count = rs.getInt(1); 91 | } 92 | 93 | rs.close(); 94 | } catch (SQLException e) { 95 | logger.error("SELECT count(*) FROM stock WHERE s_w_id = " + w_id + " AND s_i_id = " + ol_i_id + " AND s_quantity < " + level, e); 96 | throw new Exception("Slev select transaction error", e); 97 | } 98 | 99 | // Commit. 100 | pStmts.commit(); 101 | 102 | return 1; 103 | 104 | } catch (Exception e) { 105 | try { 106 | // Rollback if an aborted transaction, they are intentional in some percentage of cases. 107 | pStmts.rollback(); 108 | return 0; 109 | } catch (Throwable th) { 110 | throw new RuntimeException("Slev error", th); 111 | } finally { 112 | logger.error("Slev error", e); 113 | } 114 | } 115 | 116 | 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Tpcc.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.text.DecimalFormat; 7 | import java.util.Properties; 8 | import java.util.concurrent.ExecutorService; 9 | import java.util.concurrent.Executors; 10 | import java.util.concurrent.TimeUnit; 11 | 12 | import com.sun.org.apache.xpath.internal.operations.Bool; 13 | import org.slf4j.LoggerFactory; 14 | import org.slf4j.Logger; 15 | 16 | public class Tpcc implements TpccConstants { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(Tpcc.class); 19 | private static final boolean DEBUG = logger.isDebugEnabled(); 20 | 21 | public static final String VERSION = "1.0.1"; 22 | 23 | private static final String DRIVER = "DRIVER"; 24 | private static final String WAREHOUSECOUNT = "WAREHOUSECOUNT"; 25 | private static final String DATABASE = "DATABASE"; 26 | private static final String USER = "USER"; 27 | private static final String PASSWORD = "PASSWORD"; 28 | private static final String CONNECTIONS = "CONNECTIONS"; 29 | private static final String RAMPUPTIME = "RAMPUPTIME"; 30 | private static final String DURATION = "DURATION"; 31 | private static final String JDBCURL = "JDBCURL"; 32 | private static final String JOINS = "JOINS"; 33 | 34 | 35 | private static final String PROPERTIESFILE = "tpcc.properties"; 36 | 37 | 38 | /* Global SQL Variables */ 39 | 40 | private String javaDriver; 41 | private String jdbcUrl; 42 | private String dbUser; 43 | private String dbPassword; 44 | private final boolean joins = true; 45 | 46 | 47 | private int numWare; 48 | private int numConn; 49 | private int rampupTime; 50 | private int measureTime; 51 | private int fetchSize = 100; 52 | 53 | private int num_node; /* number of servers that consists of cluster i.e. RAC (0:normal mode)*/ 54 | private static final String TRANSACTION_NAME[] = {"NewOrder", "Payment", "Order Stat", "Delivery", "Slev"}; 55 | 56 | private final int[] success = new int[TRANSACTION_COUNT]; 57 | private final int[] late = new int[TRANSACTION_COUNT]; 58 | private final int[] retry = new int[TRANSACTION_COUNT]; 59 | private final int[] failure = new int[TRANSACTION_COUNT]; 60 | 61 | private int[][] success2; 62 | private int[][] late2; 63 | private int[][] retry2; 64 | private int[][] failure2; 65 | public static volatile boolean counting_on = false; 66 | 67 | private int[] success2_sum = new int[TRANSACTION_COUNT]; 68 | private int[] late2_sum = new int[TRANSACTION_COUNT]; 69 | private int[] retry2_sum = new int[TRANSACTION_COUNT]; 70 | private int[] failure2_sum = new int[TRANSACTION_COUNT]; 71 | 72 | 73 | private int[] prev_s = new int[5]; 74 | private int[] prev_l = new int[5]; 75 | 76 | private double[] max_rt = new double[5]; 77 | private int port = 3306; 78 | 79 | private Properties properties; 80 | private InputStream inputStream; 81 | 82 | public static volatile int activate_transaction = 0; 83 | 84 | public Tpcc() { 85 | // Empty. 86 | } 87 | 88 | 89 | private void init() { 90 | logger.info("Loading properties from: " + PROPERTIESFILE); 91 | 92 | properties = new Properties(); 93 | try { 94 | inputStream = new FileInputStream(PROPERTIESFILE); 95 | properties.load(inputStream); 96 | } catch (IOException e) { 97 | throw new RuntimeException("Error loading properties file", e); 98 | } 99 | 100 | } 101 | 102 | 103 | private int runBenchmark(boolean overridePropertiesFile, String[] argv) { 104 | 105 | System.out.println("***************************************"); 106 | System.out.println("****** Java TPC-C Load Generator ******"); 107 | System.out.println("***************************************"); 108 | 109 | /* initialize */ 110 | RtHist.histInit(); 111 | activate_transaction = 1; 112 | 113 | 114 | for (int i = 0; i < TRANSACTION_COUNT; i++) { 115 | success[i] = 0; 116 | late[i] = 0; 117 | retry[i] = 0; 118 | failure[i] = 0; 119 | 120 | prev_s[i] = 0; 121 | prev_l[i] = 0; 122 | 123 | max_rt[i] = 0.0; 124 | } 125 | 126 | /* number of node (default 0) */ 127 | num_node = 0; 128 | 129 | if (overridePropertiesFile) { 130 | for (int i = 0; i < argv.length; i = i + 2) { 131 | if (argv[i].equals("-u")) { 132 | dbUser = argv[i + 1]; 133 | } else if (argv[i].equals("-p")) { 134 | dbPassword = argv[i + 1]; 135 | } else if (argv[i].equals("-w")) { 136 | numWare = Integer.parseInt(argv[i + 1]); 137 | } else if (argv[i].equals("-c")) { 138 | numConn = Integer.parseInt(argv[i + 1]); 139 | } else if (argv[i].equals("-r")) { 140 | rampupTime = Integer.parseInt(argv[i + 1]); 141 | } else if (argv[i].equals("-t")) { 142 | measureTime = Integer.parseInt(argv[i + 1]); 143 | } else if (argv[i].equals("-j")) { 144 | javaDriver = argv[i + 1]; 145 | } else if (argv[i].equals("-l")) { 146 | jdbcUrl = argv[i + 1]; 147 | } else if (argv[i].equals("-f")) { 148 | fetchSize = Integer.parseInt(argv[i + 1]); 149 | // } else if (argv[i].equals("-J")) { 150 | // joins = Boolean.parseBoolean(argv[i + 1]); 151 | } else { 152 | System.out.println("Incorrect Argument: " + argv[i]); 153 | System.out.println("The possible arguments are as follows: "); 154 | System.out.println("-h [database host]"); 155 | System.out.println("-d [database name]"); 156 | System.out.println("-u [database username]"); 157 | System.out.println("-p [database password]"); 158 | System.out.println("-w [number of warehouses]"); 159 | System.out.println("-c [number of connections]"); 160 | System.out.println("-r [ramp up time]"); 161 | System.out.println("-t [duration of the benchmark (sec)]"); 162 | System.out.println("-j [java driver]"); 163 | System.out.println("-l [jdbc url]"); 164 | System.out.println("-h [jdbc fetch size]"); 165 | System.out.println("-J [joins (true|false) default true]"); 166 | System.exit(-1); 167 | 168 | } 169 | } 170 | } else { 171 | 172 | dbUser = properties.getProperty(USER); 173 | dbPassword = properties.getProperty(PASSWORD); 174 | numWare = Integer.parseInt(properties.getProperty(WAREHOUSECOUNT)); 175 | numConn = Integer.parseInt(properties.getProperty(CONNECTIONS)); 176 | rampupTime = Integer.parseInt(properties.getProperty(RAMPUPTIME)); 177 | measureTime = Integer.parseInt(properties.getProperty(DURATION)); 178 | javaDriver = properties.getProperty(DRIVER); 179 | jdbcUrl = properties.getProperty(JDBCURL); 180 | String jdbcFetchSize = properties.getProperty("JDBCFETCHSIZE"); 181 | //joins = Boolean.parseBoolean(properties.getProperty(JOINS)); 182 | 183 | if (jdbcFetchSize != null) { 184 | fetchSize = Integer.parseInt(jdbcFetchSize); 185 | } 186 | 187 | } 188 | if (num_node > 0) { 189 | if (numWare % num_node != 0) { 190 | logger.error(" [warehouse] value must be devided by [num_node]."); 191 | return 1; 192 | } 193 | if (numConn % num_node != 0) { 194 | logger.error("[connection] value must be devided by [num_node]."); 195 | return 1; 196 | } 197 | } 198 | 199 | 200 | if (javaDriver == null) { 201 | throw new RuntimeException("Java Driver is null."); 202 | } 203 | if (jdbcUrl == null) { 204 | throw new RuntimeException("JDBC Url is null."); 205 | } 206 | if (dbUser == null) { 207 | throw new RuntimeException("User is null."); 208 | } 209 | if (dbPassword == null) { 210 | throw new RuntimeException("Password is null."); 211 | } 212 | if (numWare < 1) { 213 | throw new RuntimeException("Warehouse count has to be greater than or equal to 1."); 214 | } 215 | if (numConn < 1) { 216 | throw new RuntimeException("Connections has to be greater than or equal to 1."); 217 | } 218 | if (rampupTime < 1) { 219 | throw new RuntimeException("Rampup time has to be greater than or equal to 1."); 220 | } 221 | if (measureTime < 1) { 222 | throw new RuntimeException("Duration has to be greater than or equal to 1."); 223 | } 224 | 225 | 226 | // Init 2-dimensional arrays. 227 | success2 = new int[TRANSACTION_COUNT][numConn]; 228 | late2 = new int[TRANSACTION_COUNT][numConn]; 229 | retry2 = new int[TRANSACTION_COUNT][numConn]; 230 | failure2 = new int[TRANSACTION_COUNT][numConn]; 231 | 232 | //long delay1 = measure_time*1000; 233 | 234 | System.out.printf("\n"); 235 | 236 | System.out.printf(" [driver]: %s\n", javaDriver); 237 | System.out.printf(" [URL]: %s\n", jdbcUrl); 238 | System.out.printf(" [user]: %s\n", dbUser); 239 | System.out.printf(" [pass]: %s\n", dbPassword); 240 | System.out.printf(" [joins]: %b\n", joins); 241 | 242 | 243 | System.out.printf(" [warehouse]: %d\n", numWare); 244 | System.out.printf(" [connection]: %d\n", numConn); 245 | System.out.printf(" [rampup]: %d (sec.)\n", rampupTime); 246 | System.out.printf(" [measure]: %d (sec.)\n", measureTime); 247 | 248 | 249 | Util.seqInit(10, 10, 1, 1, 1); 250 | 251 | 252 | /* set up threads */ 253 | 254 | if (DEBUG) logger.debug("Creating TpccThread"); 255 | ExecutorService executor = Executors.newFixedThreadPool(numConn, new NamedThreadFactory("tpcc-thread")); 256 | 257 | // Start each server. 258 | 259 | for (int i = 0; i < numConn; i++) { 260 | Runnable worker = new TpccThread(i, port, 1, dbUser, dbPassword, numWare, numConn, 261 | javaDriver, jdbcUrl, fetchSize, 262 | success, late, retry, failure, success2, late2, retry2, failure2, joins); 263 | executor.execute(worker); 264 | } 265 | 266 | if (rampupTime > 0) { 267 | // rampup time 268 | System.out.printf("\nRAMPUP START.\n\n"); 269 | try { 270 | Thread.sleep(rampupTime * 1000); 271 | } catch (InterruptedException e) { 272 | logger.error("Rampup wait interrupted", e); 273 | } 274 | System.out.printf("\nRAMPUP END.\n\n"); 275 | } 276 | 277 | // measure time 278 | System.out.printf("\nMEASURING START.\n\n"); 279 | 280 | // start counting 281 | counting_on = true; 282 | 283 | // loop for the measure_time 284 | final long startTime = System.currentTimeMillis(); 285 | DecimalFormat df = new DecimalFormat("#,##0.0"); 286 | long runTime = 0; 287 | while ((runTime = System.currentTimeMillis() - startTime) < measureTime * 1000) { 288 | System.out.println("Current execution time lapse: " + df.format(runTime / 1000.0f) + " seconds"); 289 | try { 290 | Thread.sleep(1000); 291 | } catch (InterruptedException e) { 292 | logger.error("Sleep interrupted", e); 293 | } 294 | } 295 | final long actualTestTime = System.currentTimeMillis() - startTime; 296 | 297 | // show results 298 | System.out.println("---------------------------------------------------"); 299 | /* 300 | * Raw Results 301 | */ 302 | 303 | System.out.println(""); 304 | for (int i = 0; i < TRANSACTION_COUNT; i++) { 305 | System.out.printf(" |%s| sc:%d lt:%d rt:%d fl:%d \n", 306 | TRANSACTION_NAME[i], success[i], late[i], retry[i], failure[i]); 307 | } 308 | System.out.printf(" in %f sec.\n", actualTestTime / 1000.0f); 309 | 310 | /* 311 | * Raw Results 2 312 | */ 313 | System.out.println(""); 314 | for (int i = 0; i < TRANSACTION_COUNT; i++) { 315 | success2_sum[i] = 0; 316 | late2_sum[i] = 0; 317 | retry2_sum[i] = 0; 318 | failure2_sum[i] = 0; 319 | for (int k = 0; k < numConn; k++) { 320 | success2_sum[i] += success2[i][k]; 321 | late2_sum[i] += late2[i][k]; 322 | retry2_sum[i] += retry2[i][k]; 323 | failure2_sum[i] += failure2[i][k]; 324 | } 325 | } 326 | for (int i = 0; i < TRANSACTION_COUNT; i++) { 327 | System.out.printf(" |%s| sc:%d lt:%d rt:%d fl:%d \n", 328 | TRANSACTION_NAME[i], success2_sum[i], late2_sum[i], retry2_sum[i], failure2_sum[i]); 329 | } 330 | 331 | System.out.println(" (all must be [OK])\n [transaction percentage]"); 332 | int j = 0; 333 | int i; 334 | for (i = 0; i < TRANSACTION_COUNT; i++) { 335 | j += (success[i] + late[i]); 336 | } 337 | 338 | double f = 100.0 * (float) (success[1] + late[1]) / (float) j; 339 | System.out.printf(" Payment: %f%% (>=43.0%%)", f); 340 | if (f >= 43.0) { 341 | System.out.printf(" [OK]\n"); 342 | } else { 343 | System.out.printf(" [NG] *\n"); 344 | } 345 | f = 100.0 * (float) (success[2] + late[2]) / (float) j; 346 | System.out.printf(" Order-Status: %f%% (>= 4.0%%)", f); 347 | if (f >= 4.0) { 348 | System.out.printf(" [OK]\n"); 349 | } else { 350 | System.out.printf(" [NG] *\n"); 351 | } 352 | f = 100.0 * (float) (success[3] + late[3]) / (float) j; 353 | System.out.printf(" Delivery: %f%% (>= 4.0%%)", f); 354 | if (f >= 4.0) { 355 | System.out.printf(" [OK]\n"); 356 | } else { 357 | System.out.printf(" [NG] *\n"); 358 | } 359 | f = 100.0 * (float) (success[4] + late[4]) / (float) j; 360 | System.out.printf(" Stock-Level: %f%% (>= 4.0%%)", f); 361 | if (f >= 4.0) { 362 | System.out.printf(" [OK]\n"); 363 | } else { 364 | System.out.printf(" [NG] *\n"); 365 | } 366 | 367 | /* 368 | * Response Time 369 | */ 370 | System.out.printf(" [response time (at least 90%% passed)]\n"); 371 | 372 | for (int n = 0; n < TRANSACTION_NAME.length; n++) { 373 | f = 100.0 * (float) success[n] / (float) (success[n] + late[n]); 374 | if (DEBUG) logger.debug("f: " + f + " success[" + n + "]: " + success[n] + " late[" + n + "]: " + late[n]); 375 | System.out.printf(" %s: %f%% ", TRANSACTION_NAME[n], f); 376 | if (f >= 90.0) { 377 | System.out.printf(" [OK]\n"); 378 | } else { 379 | System.out.printf(" [NG] *\n"); 380 | } 381 | } 382 | 383 | double total = 0.0; 384 | for (j = 0; j < TRANSACTION_COUNT; j++) { 385 | total = total + success[j] + late[j]; 386 | System.out.println(" " + TRANSACTION_NAME[j] + " Total: " + (success[j] + late[j])); 387 | } 388 | 389 | float tpcm = (success[0] + late[0]) * 60000f / actualTestTime; 390 | 391 | System.out.println(); 392 | System.out.println(""); 393 | System.out.println(tpcm + " TpmC"); 394 | 395 | // stop threads 396 | System.out.printf("\nSTOPPING THREADS\n"); 397 | activate_transaction = 0; 398 | 399 | executor.shutdown(); 400 | try { 401 | executor.awaitTermination(30, TimeUnit.SECONDS); 402 | } catch (InterruptedException e) { 403 | System.out.println("Timed out waiting for executor to terminate"); 404 | } 405 | 406 | //TODO: To be implemented better later. 407 | //RtHist.histReport(); 408 | return 0; 409 | 410 | } 411 | 412 | public static void main(String[] argv) { 413 | 414 | System.out.println("TPCC version " + VERSION + " Number of Arguments: " + argv.length); 415 | 416 | 417 | // dump information about the environment we are running in 418 | String sysProp[] = { 419 | "os.name", 420 | "os.arch", 421 | "os.version", 422 | "java.runtime.name", 423 | "java.vm.version", 424 | "java.library.path" 425 | }; 426 | 427 | for (String s : sysProp) { 428 | logger.info("System Property: " + s + " = " + System.getProperty(s)); 429 | } 430 | 431 | DecimalFormat df = new DecimalFormat("#,##0.0"); 432 | System.out.println("maxMemory = " + df.format(Runtime.getRuntime().totalMemory() / (1024.0 * 1024.0)) + " MB"); 433 | 434 | Tpcc tpcc = new Tpcc(); 435 | 436 | int ret = 0; 437 | 438 | if (argv.length == 0) { 439 | 440 | System.out.println("Using the properties file for configuration."); 441 | tpcc.init(); 442 | ret = tpcc.runBenchmark(false, argv); 443 | 444 | } else { 445 | if ((argv.length % 2) == 0) { 446 | System.out.println("Using the command line arguments for configuration."); 447 | ret = tpcc.runBenchmark(true, argv); 448 | } else { 449 | System.out.println("Invalid number of arguments."); 450 | System.out.println("The possible arguments are as follows: "); 451 | System.out.println("-h [database host]"); 452 | System.out.println("-d [database name]"); 453 | System.out.println("-u [database username]"); 454 | System.out.println("-p [database password]"); 455 | System.out.println("-w [number of warehouses]"); 456 | System.out.println("-c [number of connections]"); 457 | System.out.println("-r [ramp up time]"); 458 | System.out.println("-t [duration of the benchmark (sec)]"); 459 | System.out.println("-j [java driver]"); 460 | System.out.println("-l [jdbc url]"); 461 | System.out.println("-h [jdbc fetch size]"); 462 | System.exit(-1); 463 | } 464 | 465 | } 466 | 467 | 468 | System.out.println("Terminating process now"); 469 | System.exit(ret); 470 | } 471 | 472 | 473 | } 474 | 475 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/TpccConstants.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | public interface TpccConstants { 4 | /* 5 | * correct values 6 | */ 7 | public static int TRANSACTION_COUNT = 5; 8 | public static int MAXITEMS = 100000; 9 | public static int CUST_PER_DIST = 3000; 10 | public static int DIST_PER_WARE = 10; 11 | public static int ORD_PER_DIST = 3000; 12 | 13 | public static int[] nums = new int[CUST_PER_DIST]; 14 | 15 | /* definitions for new order transaction */ 16 | public static int MAX_NUM_ITEMS = 15; 17 | public static int MAX_ITEM_LEN = 24; 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/TpccLoad.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.io.*; 4 | import java.sql.Connection; 5 | import java.sql.DriverManager; 6 | import java.sql.SQLException; 7 | import java.sql.Statement; 8 | import java.text.DecimalFormat; 9 | import java.util.Properties; 10 | 11 | import org.slf4j.LoggerFactory; 12 | import org.slf4j.Logger; 13 | 14 | 15 | public class TpccLoad implements TpccConstants { 16 | 17 | private String mode; 18 | private String outputDir; 19 | private String dbUser = null; 20 | private String dbPassword = null; 21 | private int shardCount = 0; 22 | private String jdbcUrl = null; 23 | private String javaDriver = null; 24 | private int shardId = -1; 25 | 26 | 27 | /* Global SQL Variables */ 28 | static int num_ware = 0; 29 | static int fd = 0; 30 | static int seed = 0; 31 | 32 | 33 | int particle_flg = 0; /* "1" means particle mode */ 34 | int part_no = 0; /* 1:items 2:warehouse 3:customer 4:orders */ 35 | long min_ware = 1; 36 | long max_ware; 37 | 38 | /* Global Variables */ 39 | static int i = 0; 40 | // static int is_local = 1; /* "1" mean local */ 41 | // static int DB_STRING_MAX = 51; 42 | static boolean option_debug = false; /* 1 if generating debug output */ 43 | 44 | private static final Logger logger = LoggerFactory.getLogger(Tpcc.class); 45 | 46 | private static final String MODE = "MODE"; 47 | private static final String OUTPUTDIR = "OUTPUTDIR"; 48 | private static final String DRIVER = "DRIVER"; 49 | private static final String WAREHOUSECOUNT = "WAREHOUSECOUNT"; 50 | private static final String USER = "USER"; 51 | private static final String PASSWORD = "PASSWORD"; 52 | private static final String SHARDCOUNT = "SHARDCOUNT"; 53 | private static final String JDBCURL = "JDBCURL"; 54 | private static final String SHARDID = "SHARDID"; 55 | 56 | private Properties properties; 57 | private InputStream inputStream; 58 | 59 | private static final String PROPERTIESFILE = "tpcc.properties"; 60 | 61 | public TpccLoad() { 62 | // Empty. 63 | } 64 | 65 | private void init() { 66 | 67 | logger.info("Loading properties from: " + PROPERTIESFILE); 68 | 69 | try { 70 | properties = new Properties(); 71 | inputStream = new FileInputStream(PROPERTIESFILE); 72 | properties.load(inputStream); 73 | } catch (IOException e) { 74 | throw new RuntimeException("Error loading properties file", e); 75 | } 76 | 77 | } 78 | 79 | 80 | private int runLoad(boolean overridePropertiesFile, String[] argv) { 81 | 82 | if (overridePropertiesFile) { 83 | for (int i = 0; i < argv.length; i = i + 2) { 84 | if (argv[i].equals("-m")) { 85 | mode = argv[i + 1]; 86 | } else if (argv[i].equals("-o")) { 87 | outputDir = argv[i + 1]; 88 | } else if (argv[i].equals("-u")) { 89 | dbUser = argv[i + 1]; 90 | } else if (argv[i].equals("-p")) { 91 | dbPassword = argv[i + 1]; 92 | } else if (argv[i].equals("-j")) { 93 | javaDriver = argv[i + 1]; 94 | } else if (argv[i].equals("-l")) { 95 | jdbcUrl = argv[i + 1]; 96 | } else if (argv[i].equals("-s")) { 97 | shardCount = Integer.parseInt(argv[i + 1]); 98 | } else if (argv[i].equals("-i")) { 99 | shardId = Integer.parseInt(argv[i + 1]); 100 | } else { 101 | System.out.println("Incorrect Argument: " + argv[i]); 102 | System.out.println("The possible arguments are as follows: "); 103 | System.out.println("-m [mode (FILE or JDBC)]"); 104 | System.out.println("-o [file output dir]"); 105 | System.out.println("-u [database username]"); 106 | System.out.println("-p [database password]"); 107 | System.out.println("-w [number of warehouses]"); 108 | System.out.println("-j [java driver]"); 109 | System.out.println("-l [jdbc url]"); 110 | System.out.println("-s [shard count]"); 111 | System.out.println("-i [shard id]"); 112 | System.exit(-1); 113 | 114 | } 115 | } 116 | } else { 117 | mode = properties.getProperty(MODE); 118 | outputDir = properties.getProperty(OUTPUTDIR); 119 | dbUser = properties.getProperty(USER); 120 | dbPassword = properties.getProperty(PASSWORD); 121 | num_ware = Integer.parseInt(properties.getProperty(WAREHOUSECOUNT)); 122 | shardCount = Integer.parseInt(properties.getProperty(SHARDCOUNT)); 123 | javaDriver = properties.getProperty(DRIVER); 124 | jdbcUrl = properties.getProperty(JDBCURL); 125 | shardId = Integer.parseInt(properties.getProperty(SHARDID)); 126 | } 127 | 128 | System.out.printf("*************************************\n"); 129 | System.out.printf("*** Java TPC-C Data Loader version " + Tpcc.VERSION + " ***\n"); 130 | System.out.printf("*************************************\n"); 131 | 132 | final long start = System.currentTimeMillis(); 133 | System.out.println("Execution time start: " + start); 134 | 135 | if (mode == null) { 136 | throw new RuntimeException("Mode is null."); 137 | } 138 | boolean jdbcMode = mode.equalsIgnoreCase("JDBC"); 139 | if (jdbcMode) { 140 | if (dbUser == null) { 141 | throw new RuntimeException("User is null."); 142 | } 143 | if (dbPassword == null) { 144 | throw new RuntimeException("Password is null."); 145 | } 146 | } else if (mode.equalsIgnoreCase("FILE")) { 147 | if (outputDir == null) { 148 | throw new RuntimeException("Output dir is null."); 149 | } 150 | } else { 151 | throw new RuntimeException("Invalid mode '" + mode + "': must be CSV or JDBC"); 152 | } 153 | 154 | if (num_ware < 1) { 155 | throw new RuntimeException("Warehouse count has to be greater than or equal to 1."); 156 | } 157 | if (javaDriver == null) { 158 | throw new RuntimeException("Java Driver is null."); 159 | } 160 | if (jdbcUrl == null) { 161 | throw new RuntimeException("JDBC Url is null."); 162 | } 163 | if (shardId == -1) { 164 | throw new RuntimeException("ShardId was not obtained"); 165 | } 166 | 167 | System.out.printf("\n"); 168 | 169 | if (jdbcMode) { 170 | System.out.printf(" [Driver]: %s\n", javaDriver); 171 | System.out.printf(" [URL]: %s\n", jdbcUrl); 172 | System.out.printf(" [user]: %s\n", dbUser); 173 | System.out.printf(" [pass]: %s\n", dbPassword); 174 | } else { 175 | System.out.printf(" [Output Dir]: %s\n", outputDir); 176 | } 177 | 178 | System.out.printf(" [warehouse]: %d\n", num_ware); 179 | System.out.printf(" [shardId]: %d\n", shardId); 180 | if (particle_flg == 1) { 181 | System.out.printf(" [part(1-4)]: %d\n", part_no); 182 | System.out.printf(" [MIN WH]: %d\n", min_ware); 183 | System.out.printf(" [MAX WH]: %d\n", max_ware); 184 | } 185 | 186 | //TODO: Pass the seed in as a variable. 187 | Util.setSeed(seed); 188 | 189 | TpccLoadConfig loadConfig = new TpccLoadConfig(); 190 | 191 | /* EXEC SQL WHENEVER SQLERROR GOTO Error_SqlCall; */ 192 | if (jdbcMode) { 193 | try { 194 | Class.forName(javaDriver); 195 | } catch (ClassNotFoundException e1) { 196 | throw new RuntimeException("Class for mysql error", e1); 197 | } 198 | 199 | Connection conn; 200 | 201 | try { 202 | //TODO: load from config 203 | Properties jdbcConnectProp = new Properties(); 204 | jdbcConnectProp.setProperty("user", dbUser); 205 | jdbcConnectProp.setProperty("password", dbPassword); 206 | jdbcConnectProp.setProperty("useServerPrepStmts", "true"); 207 | jdbcConnectProp.setProperty("cachePrepStmts", "true"); 208 | 209 | conn = DriverManager.getConnection(jdbcUrl, jdbcConnectProp); 210 | conn.setAutoCommit(false); 211 | 212 | } catch (SQLException e) { 213 | throw new RuntimeException("Connection error", e); 214 | } 215 | 216 | 217 | Statement stmt; 218 | try { 219 | stmt = conn.createStatement(); 220 | } catch (SQLException e) { 221 | throw new RuntimeException("Could not create statement", e); 222 | } 223 | try { 224 | stmt.execute("SET UNIQUE_CHECKS=0"); 225 | } catch (SQLException e) { 226 | throw new RuntimeException("Could not set unique checks error", e); 227 | } 228 | try { 229 | stmt.execute("SET FOREIGN_KEY_CHECKS=0"); 230 | stmt.close(); 231 | } catch (SQLException e) { 232 | throw new RuntimeException("Could not set foreign key checks error", e); 233 | } 234 | 235 | loadConfig.setLoadType(TpccLoadConfig.LoadType.JDBC_STATEMENT); 236 | loadConfig.setConn(conn); 237 | } else { 238 | File outputDir = new File(this.outputDir); 239 | if (outputDir.exists()) { 240 | String[] list = outputDir.list(new FilenameFilter() { 241 | public boolean accept(File dir, String name) { 242 | return name.endsWith(".txt"); 243 | } 244 | }); 245 | if (list.length > 0) { 246 | throw new RuntimeException("All text files must be deleted from " + outputDir + " before generating data"); 247 | } 248 | } else { 249 | if (!outputDir.mkdirs()) { 250 | throw new RuntimeException("Could not create dir: " + outputDir.getAbsolutePath()); 251 | } 252 | } 253 | loadConfig.setLoadType(TpccLoadConfig.LoadType.CSV); 254 | loadConfig.setOutputDir(outputDir); 255 | } 256 | 257 | System.out.printf("TPCC Data Load Started...\n"); 258 | 259 | try { 260 | max_ware = num_ware; 261 | if (particle_flg == 0) { 262 | System.out.printf("Particle flag: %d\n", particle_flg); 263 | Load.loadItems(loadConfig, option_debug); 264 | Load.loadWare(loadConfig, shardCount, (int) min_ware, (int) max_ware, option_debug, shardId); 265 | Load.loadCust(loadConfig, shardCount, (int) min_ware, (int) max_ware, shardId); 266 | Load.loadOrd(loadConfig, shardCount, (int) max_ware, shardId); 267 | } else if (particle_flg == 1) { 268 | switch (part_no) { 269 | case 1: 270 | Load.loadItems(loadConfig, option_debug); 271 | break; 272 | case 2: 273 | Load.loadWare(loadConfig, shardCount, (int) min_ware, (int) max_ware, option_debug, shardId); 274 | break; 275 | case 3: 276 | Load.loadCust(loadConfig, shardCount, (int) min_ware, (int) max_ware, shardId); 277 | break; 278 | case 4: 279 | Load.loadOrd(loadConfig, shardCount, (int) max_ware, shardId); 280 | break; 281 | default: 282 | System.out.printf("Unknown part_no\n"); 283 | System.out.printf("1:ITEMS 2:WAREHOUSE 3:CUSTOMER 4:ORDERS\n"); 284 | } 285 | } 286 | 287 | System.out.printf("\n...DATA LOADING COMPLETED SUCCESSFULLY.\n"); 288 | } catch (Exception e) { 289 | System.out.println("Error loading data"); 290 | e.printStackTrace(); 291 | } 292 | 293 | final long end = System.currentTimeMillis(); 294 | final long durationSeconds = (long) ((end - start) / 1000.0f); 295 | 296 | long seconds = durationSeconds % 60; 297 | long minutes = (durationSeconds - seconds) / 60; 298 | 299 | DecimalFormat df1 = new DecimalFormat("#,##0"); 300 | DecimalFormat df2 = new DecimalFormat("#,##0.000"); 301 | System.out.println("Total execution time: " 302 | + df1.format(minutes) + " minute(s), " 303 | + df1.format(seconds) + " second(s) (" 304 | + df2.format(durationSeconds / 60.0f) + " minutes)" 305 | ); 306 | 307 | return 0; 308 | } 309 | 310 | public static void main(String[] argv) { 311 | 312 | // dump information about the environment we are running in 313 | String sysProp[] = { 314 | "os.name", 315 | "os.arch", 316 | "os.version", 317 | "java.runtime.name", 318 | "java.vm.version", 319 | "java.library.path" 320 | }; 321 | 322 | for (String s : sysProp) { 323 | logger.info("System Property: " + s + " = " + System.getProperty(s)); 324 | } 325 | 326 | DecimalFormat df = new DecimalFormat("#,##0.0"); 327 | System.out.println("maxMemory = " + df.format(Runtime.getRuntime().totalMemory() / (1024.0 * 1024.0)) + " MB"); 328 | TpccLoad tpccLoad = new TpccLoad(); 329 | 330 | int ret = 0; 331 | if (argv.length == 0) { 332 | System.out.println("Using the tpcc.properties file for the load configuration."); 333 | tpccLoad.init(); 334 | ret = tpccLoad.runLoad(false, argv); 335 | } else { 336 | 337 | if ((argv.length % 2) == 0) { 338 | System.out.println("Using the command line arguments for the load configuration."); 339 | ret = tpccLoad.runLoad(true, argv); 340 | } else { 341 | System.out.println("Invalid number of arguments."); 342 | System.out.println("Incorrect Argument: " + argv[i]); 343 | System.out.println("The possible arguments are as follows: "); 344 | System.out.println("-h [database host]"); 345 | System.out.println("-d [database name]"); 346 | System.out.println("-u [database username]"); 347 | System.out.println("-p [database password]"); 348 | System.out.println("-w [number of warehouses]"); 349 | System.out.println("-j [java driver]"); 350 | System.out.println("-l [jdbc url]"); 351 | System.out.println("-s [shard count]"); 352 | System.out.println("-i [shard id]"); 353 | System.exit(-1); 354 | 355 | } 356 | } 357 | 358 | System.exit(ret); 359 | } 360 | 361 | 362 | } 363 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/TpccLoadConfig.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import com.codefutures.tpcc.load.FileLoader; 4 | import com.codefutures.tpcc.load.JdbcPreparedStatementLoader; 5 | import com.codefutures.tpcc.load.JdbcStatementLoader; 6 | import com.codefutures.tpcc.load.RecordLoader; 7 | 8 | import java.io.File; 9 | import java.io.IOException; 10 | import java.sql.Connection; 11 | 12 | /** 13 | * Copyright (C) 2011 CodeFutures Corporation. All rights reserved. 14 | */ 15 | public class TpccLoadConfig { 16 | 17 | enum LoadType { 18 | JDBC_STATEMENT, 19 | JDBC_PREPARED_STATEMENT, 20 | CSV 21 | } 22 | 23 | private LoadType loadType = LoadType.JDBC_PREPARED_STATEMENT; 24 | 25 | private Connection conn; 26 | 27 | private File outputDir; 28 | 29 | private boolean jdbcInsertIgnore = true; 30 | 31 | private int jdbcBatchSize = 100; 32 | 33 | public RecordLoader createLoader(String tableName, String columnName[]) throws IOException { 34 | switch (loadType) { 35 | case JDBC_STATEMENT: 36 | return new JdbcStatementLoader(conn, tableName, columnName, jdbcInsertIgnore, jdbcBatchSize); 37 | case JDBC_PREPARED_STATEMENT: 38 | return new JdbcPreparedStatementLoader(conn, tableName, columnName, jdbcInsertIgnore, jdbcBatchSize); 39 | case CSV: 40 | return new FileLoader(new File(outputDir, tableName + ".txt")); 41 | default: 42 | throw new IllegalStateException(); 43 | } 44 | } 45 | 46 | public void setOutputDir(File outputDir) { 47 | this.outputDir = outputDir; 48 | } 49 | 50 | public Connection getConn() { 51 | return conn; 52 | } 53 | 54 | public void setConn(Connection conn) { 55 | this.conn = conn; 56 | } 57 | 58 | public void setLoadType(LoadType loadType) { 59 | this.loadType = loadType; 60 | } 61 | 62 | public LoadType getLoadType() { 63 | return loadType; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/TpccStatements.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.sql.Connection; 7 | import java.sql.PreparedStatement; 8 | import java.sql.ResultSet; 9 | import java.sql.SQLException; 10 | 11 | public class TpccStatements { 12 | 13 | private static final Logger logger = LoggerFactory.getLogger(TpccStatements.class); 14 | 15 | public static final int STMT_COUNT = 37; 16 | 17 | private final Connection conn; 18 | 19 | private final PreparedStatement[] pStmts = new PreparedStatement[STMT_COUNT]; 20 | 21 | public TpccStatements(Connection conn, int fetchSize) throws Exception { 22 | this.conn = conn; 23 | 24 | // NewOrder statements. 25 | pStmts[0] = prepareStatement("SELECT c.c_discount, c.c_last, c.c_credit, w.w_tax FROM customer AS c JOIN warehouse AS w ON c.c_w_id = w_id AND w.w_id = ? AND c.c_w_id = ? AND c.c_d_id = ? AND c.c_id = ?"); 26 | pStmts[1] = prepareStatement("SELECT d_next_o_id, d_tax FROM district WHERE d_id = ? AND d_w_id = ? FOR UPDATE"); 27 | pStmts[2] = prepareStatement("UPDATE district SET d_next_o_id = ? + 1 WHERE d_id = ? AND d_w_id = ?"); 28 | pStmts[3] = prepareStatement("INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES(?, ?, ?, ?, ?, ?, ?)"); 29 | pStmts[4] = prepareStatement("INSERT INTO new_orders (no_o_id, no_d_id, no_w_id) VALUES (?,?,?)"); 30 | pStmts[5] = prepareStatement("SELECT i_price, i_name, i_data FROM item WHERE i_id = ?"); 31 | pStmts[6] = prepareStatement("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 stock WHERE s_i_id = ? AND s_w_id = ? FOR UPDATE"); 32 | pStmts[7] = prepareStatement("UPDATE stock SET s_quantity = ? WHERE s_i_id = ? AND s_w_id = ?"); 33 | pStmts[8] = prepareStatement("INSERT INTO order_line (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 (?, ?, ?, ?, ?, ?, ?, ?, ?)"); 34 | 35 | // Payment statements. 36 | pStmts[9] = prepareStatement("UPDATE warehouse SET w_ytd = w_ytd + ? WHERE w_id = ?"); 37 | pStmts[10] = prepareStatement("SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = ?"); 38 | pStmts[11] = prepareStatement("UPDATE district SET d_ytd = d_ytd + ? WHERE d_w_id = ? AND d_id = ?"); 39 | pStmts[12] = prepareStatement("SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = ? AND d_id = ?"); 40 | pStmts[13] = prepareStatement("SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?"); 41 | pStmts[14] = prepareStatement("SELECT c_id FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first"); 42 | pStmts[15] = prepareStatement("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_since FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ? FOR UPDATE"); 43 | pStmts[16] = prepareStatement("SELECT c_data FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?"); 44 | pStmts[17] = prepareStatement("UPDATE customer SET c_balance = ?, c_data = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?"); 45 | pStmts[18] = prepareStatement("UPDATE customer SET c_balance = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?"); 46 | pStmts[19] = prepareStatement("INSERT INTO history(h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); 47 | 48 | // OrderStat statements. 49 | pStmts[20] = prepareStatement("SELECT count(c_id) FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ?"); 50 | pStmts[21] = prepareStatement("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first"); 51 | pStmts[22] = prepareStatement("SELECT c_balance, c_first, c_middle, c_last FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?"); 52 | pStmts[23] = prepareStatement("SELECT o_id, o_entry_d, COALESCE(o_carrier_id,0) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? AND o_id = (SELECT MAX(o_id) FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ?)"); 53 | pStmts[24] = prepareStatement("SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id = ?"); 54 | 55 | // Delivery statements. 56 | pStmts[25] = prepareStatement("SELECT COALESCE(MIN(no_o_id),0) FROM new_orders WHERE no_d_id = ? AND no_w_id = ?"); 57 | pStmts[26] = prepareStatement("DELETE FROM new_orders WHERE no_o_id = ? AND no_d_id = ? AND no_w_id = ?"); 58 | pStmts[27] = prepareStatement("SELECT o_c_id FROM orders WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?"); 59 | pStmts[28] = prepareStatement("UPDATE orders SET o_carrier_id = ? WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?"); 60 | pStmts[29] = prepareStatement("UPDATE order_line SET ol_delivery_d = ? WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?"); 61 | pStmts[30] = prepareStatement("SELECT SUM(ol_amount) FROM order_line WHERE ol_o_id = ? AND ol_d_id = ? AND ol_w_id = ?"); 62 | pStmts[31] = prepareStatement("UPDATE customer SET c_balance = c_balance + ? , c_delivery_cnt = c_delivery_cnt + 1 WHERE c_id = ? AND c_d_id = ? AND c_w_id = ?"); 63 | 64 | // Slev statements. 65 | pStmts[32] = prepareStatement("SELECT d_next_o_id FROM district WHERE d_id = ? AND d_w_id = ?"); 66 | pStmts[33] = prepareStatement("SELECT DISTINCT ol_i_id FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id < ? AND ol_o_id >= (? - 20)"); 67 | pStmts[34] = prepareStatement("SELECT count(*) FROM stock WHERE s_w_id = ? AND s_i_id = ? AND s_quantity < ?"); 68 | 69 | // These are used in place of pStmts[0] in order to avoid joins 70 | pStmts[35] = prepareStatement("SELECT c_discount, c_last, c_credit FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?"); 71 | pStmts[36] = prepareStatement("SELECT w_tax FROM warehouse WHERE w_id = ?"); 72 | 73 | for (int i = 0; i < pStmts.length; i++) { 74 | pStmts[i].setFetchSize(fetchSize); 75 | } 76 | 77 | } 78 | 79 | private PreparedStatement prepareStatement(String sql) throws SQLException { 80 | if (sql.startsWith("SELECT")) { 81 | return conn.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); 82 | } else { 83 | return conn.prepareStatement(sql, PreparedStatement.NO_GENERATED_KEYS); 84 | } 85 | } 86 | 87 | public PreparedStatement getStatement(int idx) { 88 | return pStmts[idx]; 89 | } 90 | 91 | public void setAutoCommit(boolean b) throws SQLException { 92 | conn.setAutoCommit(b); 93 | } 94 | 95 | /** 96 | * Commit a transaction. 97 | */ 98 | public void commit() throws SQLException { 99 | logger.trace("COMMIT"); 100 | conn.commit(); 101 | } 102 | 103 | /** 104 | * Rollback a transaction. 105 | */ 106 | public void rollback() throws SQLException { 107 | logger.trace("ROLLBACK"); 108 | conn.rollback(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/TpccThread.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.sql.Connection; 7 | import java.sql.DriverManager; 8 | import java.sql.SQLException; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | import java.util.Set; 12 | 13 | import org.slf4j.LoggerFactory; 14 | import org.slf4j.Logger; 15 | 16 | public class TpccThread extends Thread { 17 | 18 | private static final Logger logger = LoggerFactory.getLogger(TpccThread.class); 19 | private static final boolean DEBUG = logger.isDebugEnabled(); 20 | 21 | /** 22 | * Dedicated JDBC connection for this thread. 23 | */ 24 | Connection conn; 25 | 26 | Driver driver; 27 | 28 | int number; 29 | int port; 30 | int is_local; 31 | int num_ware; 32 | int num_conn; 33 | String db_user; 34 | String db_password; 35 | String driverClassName; 36 | String jdbcUrl; 37 | int fetchSize; 38 | 39 | private int[] success; 40 | private int[] late; 41 | private int[] retry; 42 | private int[] failure; 43 | 44 | private int[][] success2; 45 | private int[][] late2; 46 | private int[][] retry2; 47 | private int[][] failure2; 48 | 49 | private boolean joins; 50 | 51 | //TpccStatements pStmts; 52 | 53 | public TpccThread(int number, int port, int is_local, String db_user, String db_password, 54 | int num_ware, int num_conn, String driverClassName, String dURL, int fetchSize, 55 | int[] success, int[] late, int[] retry, int[] failure, 56 | int[][] success2, int[][] late2, int[][] retry2, int[][] failure2, boolean joins) { 57 | 58 | this.number = number; 59 | this.port = port; 60 | this.db_password = db_password; 61 | this.db_user = db_user; 62 | this.is_local = is_local; 63 | this.num_conn = num_conn; 64 | this.num_ware = num_ware; 65 | this.driverClassName = driverClassName; 66 | this.jdbcUrl = dURL; 67 | this.fetchSize = fetchSize; 68 | 69 | this.success = success; 70 | this.late = late; 71 | this.retry = retry; 72 | this.failure = failure; 73 | 74 | this.success2 = success2; 75 | this.late2 = late2; 76 | this.retry2 = retry2; 77 | this.failure2 = failure2; 78 | this.joins = joins; 79 | 80 | connectToDatabase(); 81 | 82 | // Create a driver instance. 83 | driver = new Driver(conn, fetchSize, 84 | success, late, retry, failure, 85 | success2, late2, retry2, failure2, joins); 86 | 87 | } 88 | 89 | public void run() { 90 | 91 | try { 92 | if (DEBUG) { 93 | logger.debug("Starting driver with: number: " + number + " num_ware: " + num_ware + " num_conn: " + num_conn); 94 | } 95 | 96 | driver.runTransaction(number, num_ware, num_conn); 97 | 98 | } catch (Throwable e) { 99 | logger.error("Unhandled exception", e); 100 | } 101 | 102 | } 103 | 104 | private Connection connectToDatabase() { 105 | 106 | logger.info("Connection to database: driver: " + driverClassName + " url: " + jdbcUrl); 107 | try { 108 | Class.forName(driverClassName); 109 | } catch (ClassNotFoundException e1) { 110 | throw new RuntimeException("Failed to load JDBC driver class: " + driverClassName, e1); 111 | } 112 | 113 | try { 114 | 115 | Properties prop = new Properties(); 116 | File connPropFile = new File("conf/jdbc-connection.properties"); 117 | if (connPropFile.exists()) { 118 | logger.info("Loading JDBC connection properties from " + connPropFile.getAbsolutePath()); 119 | try { 120 | final FileInputStream is = new FileInputStream(connPropFile); 121 | prop.load(is); 122 | is.close(); 123 | 124 | if (logger.isDebugEnabled()) { 125 | logger.debug("Connection properties: {"); 126 | final Set> entries = prop.entrySet(); 127 | for (Map.Entry entry : entries) { 128 | logger.debug(entry.getKey() + " = " + entry.getValue()); 129 | } 130 | 131 | logger.debug("}"); 132 | } 133 | 134 | } catch (IOException e) { 135 | logger.error("", e); 136 | } 137 | } else { 138 | logger.warn(connPropFile.getAbsolutePath() + " does not exist! Using default connection properties"); 139 | } 140 | prop.put("user", db_user); 141 | prop.put("password", db_password); 142 | 143 | 144 | conn = DriverManager.getConnection(jdbcUrl, prop); 145 | conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ); 146 | conn.setAutoCommit(false); 147 | 148 | } catch (SQLException e) { 149 | throw new RuntimeException("Failed to connect to database", e); 150 | } 151 | return conn; 152 | } 153 | } 154 | 155 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/Util.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc; 2 | 3 | import java.util.Random; 4 | 5 | public class Util implements TpccConstants { 6 | 7 | //Weight Variables 8 | static int no; 9 | static int py; 10 | static int os; 11 | static int dl; 12 | static int sl; 13 | static int total = 0; 14 | 15 | private static int[] seq; 16 | private static int nextNum = 0; 17 | static Boolean first = true; 18 | 19 | static int permCount; 20 | private static Random generate = new Random(); 21 | 22 | private static final int C_255 = randomNumber(0, 255); 23 | private static final int C_1023 = randomNumber(0, 1023); 24 | private static final int C_8191 = randomNumber(0, 8191); 25 | 26 | //Member Functions 27 | public static void shuffle() { 28 | //Counters 29 | int i; 30 | int j; 31 | int tmp; 32 | int rmd; 33 | 34 | Random rnd = new Random(); 35 | 36 | for (i = 0, j = 0; i < no; i++, j++) { 37 | seq[j] = 0; 38 | } 39 | for (i = 0; i < py; i++, j++) { 40 | seq[j] = 1; 41 | } 42 | for (i = 0; i < os; i++, j++) { 43 | seq[j] = 2; 44 | } 45 | for (i = 0; i < dl; i++, j++) { 46 | seq[j] = 3; 47 | } 48 | for (i = 0; i < sl; i++, j++) { 49 | seq[j] = 4; 50 | } 51 | for (i = 0, j = total - 1; j > 0; i++, j--) { 52 | 53 | rmd = rnd.nextInt() % (j + 1); 54 | if (rmd < 0) { 55 | rmd = rmd * -1; 56 | } 57 | tmp = seq[rmd + i]; 58 | seq[rmd + i] = seq[i]; 59 | seq[i] = tmp; 60 | } 61 | 62 | 63 | } 64 | 65 | public static void seqInit(int n, int p, int o, int d, int s) { 66 | 67 | no = n; 68 | py = p; 69 | os = o; 70 | dl = d; 71 | sl = s; 72 | total = n + p + o + d + s; 73 | System.out.printf("TOTAL:%d", total); 74 | seq = new int[total]; 75 | shuffle(); 76 | nextNum = 0; 77 | 78 | 79 | } 80 | 81 | public synchronized static int seqGet() { 82 | if (nextNum >= total) { 83 | shuffle(); 84 | nextNum = 0; 85 | } 86 | return seq[nextNum++]; 87 | } 88 | 89 | public static void setSeed(int seed) { 90 | generate.setSeed(seed); 91 | } 92 | 93 | /* 94 | * return number uniformly distributed b/w min and max, inclusive 95 | */ 96 | public static int randomNumber(int min, int max) { 97 | int next = generate.nextInt(); 98 | int div = next % ((max - min) + 1); 99 | if (div < 0) { 100 | div = div * -1; 101 | } 102 | int value = min + div; 103 | 104 | /* 105 | if (value < min || value > max) { 106 | throw new IllegalStateException("next=" + next + ", div=" + div + ", min=" + min + ", max=" + max + ", value=" + value); 107 | } 108 | */ 109 | 110 | return value; 111 | } 112 | 113 | /* 114 | * 115 | * 116 | * the constant C depends on which value of A is passed, but the same 117 | * value of C should be used for all calls with the same value of 118 | * A. however, we know in advance which values of A will be used. 119 | */ 120 | public static int nuRand(int A, int x, int y) { 121 | int C = 0; 122 | 123 | switch (A) { 124 | case 255: 125 | C = C_255; 126 | break; 127 | case 1023: 128 | C = C_1023; 129 | break; 130 | case 8191: 131 | C = C_8191; 132 | break; 133 | default: 134 | throw new RuntimeException("NURand: unexpected value (%d) of A used\n" + A); 135 | } 136 | 137 | return ((((randomNumber(0, A) | randomNumber(x, y)) + C) % (y - x + 1)) + x); 138 | 139 | } 140 | 141 | /* 142 | * 143 | * make a ``random a-string'': a string of random alphanumeric 144 | * characters of a random length of minimum x, maximum y, and 145 | * mean (y+x)/2 146 | */ 147 | public static String makeAlphaString(int x, int y) { 148 | String str = null; 149 | String temp = "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"; 150 | char[] alphanum = temp.toCharArray(); 151 | int arrmax = 61; /* index of last array element */ 152 | int i; 153 | int len; 154 | len = randomNumber(x, y); 155 | 156 | for (i = 0; i < len; i++) 157 | if (str != null) { 158 | str = str + alphanum[randomNumber(0, arrmax)]; 159 | } else { 160 | str = "" + alphanum[randomNumber(0, arrmax)]; 161 | } 162 | 163 | return str; 164 | 165 | } 166 | 167 | /* 168 | * like MakeAlphaString, only numeric characters only 169 | */ 170 | public static String makeNumberString(int x, int y) { 171 | String str = null; 172 | char[] numeric = "0123456789".toCharArray(); 173 | int arrmax = 9; 174 | int i; 175 | int len; 176 | 177 | len = randomNumber(x, y); 178 | 179 | for (i = 0; i < len; i++) 180 | if (str != null) { 181 | str = str + numeric[randomNumber(0, arrmax)]; 182 | } else { 183 | str = "0"; 184 | } 185 | 186 | return str; 187 | } 188 | 189 | public static void initPermutation() { 190 | int i, j = 0; 191 | int[] tempNums = new int[CUST_PER_DIST]; 192 | 193 | permCount = 0; 194 | 195 | /* initialize with consecutive values [1..ORD_PER_DIST] */ 196 | // for (i = 0, cur = nums; i < ORD_PER_DIST; i++, cur++) { 197 | // *cur = i + 1; 198 | // } 199 | 200 | for (i = 0; i < ORD_PER_DIST; i++) { 201 | nums[i] = i + 1; 202 | tempNums[i] = i + 1; 203 | } 204 | 205 | /* now, shuffle */ 206 | // for (i = 0; i < ORD_PER_DIST-1; i++) { 207 | // j = (int)RandomNumber(i+1, ORD_PER_DIST-1); 208 | // swap_int(nums[i], nums[j]); 209 | // } 210 | // TODO: Why is it ORD_PER_DIST-1. Not shuffling the last one? 211 | for (i = 0; i < ORD_PER_DIST - 1; i++) { 212 | j = (int) randomNumber(i + 1, ORD_PER_DIST - 1); 213 | nums[j] = tempNums[i]; 214 | } 215 | } 216 | 217 | public static int getPermutation() { 218 | if (permCount >= ORD_PER_DIST) { 219 | throw new RuntimeException("GetPermutation: past end of list!\n"); 220 | } 221 | return nums[permCount++]; 222 | } 223 | 224 | static String lastName(int num) { 225 | String name = null; 226 | String[] n = 227 | {"BAR", "OUGHT", "ABLE", "PRI", "PRES", 228 | "ESE", "ANTI", "CALLY", "ATION", "EING"}; 229 | 230 | name = n[num / 100]; 231 | name = name + n[(num / 10) % 10]; 232 | name = name + n[num % 10]; 233 | 234 | return name; 235 | } 236 | 237 | } 238 | 239 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/load/FileLoader.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc.load; 2 | 3 | import java.io.BufferedOutputStream; 4 | import java.io.File; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.text.DateFormat; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | /** 12 | * Copyright (C) 2011 CodeFutures Corporation. All rights reserved. 13 | */ 14 | public class FileLoader implements RecordLoader { 15 | 16 | protected static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); 17 | 18 | protected static final DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 19 | 20 | protected BufferedOutputStream os; 21 | 22 | protected final StringBuilder b = new StringBuilder(); 23 | 24 | public FileLoader(File file) throws IOException { 25 | this.os = new BufferedOutputStream(new FileOutputStream(file, true)); 26 | } 27 | 28 | public void load(Record r) throws Exception { 29 | b.setLength(0); 30 | final Object[] field = r.getField(); 31 | for (int i = 0; i < field.length; i++) { 32 | if (i > 0) { 33 | b.append('\t'); 34 | } 35 | if (field[i] == null) { 36 | b.append("\\N"); 37 | } else if (field[i] instanceof Date) { 38 | b.append(dateTimeFormat.format((Date) field[i])); 39 | } else { 40 | b.append(field[i]); 41 | } 42 | } 43 | os.write(b.toString().getBytes()); 44 | os.write("\n".getBytes()); 45 | } 46 | 47 | public void commit() throws Exception { 48 | // ignore 49 | } 50 | 51 | public void close() throws Exception { 52 | os.close(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/load/JdbcPreparedStatementLoader.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc.load; 2 | 3 | import java.sql.Connection; 4 | import java.sql.PreparedStatement; 5 | import java.sql.SQLException; 6 | 7 | /** 8 | * Data loader using prepared statements and batches. This is slower than the JdbcStatementLoader which uses 9 | * bulk inserts. 10 | */ 11 | public class JdbcPreparedStatementLoader implements RecordLoader { 12 | 13 | Connection conn; 14 | 15 | PreparedStatement pstmt; 16 | 17 | String tableName; 18 | 19 | String columnName[]; 20 | 21 | boolean ignore; 22 | 23 | int maxBatchSize; 24 | 25 | int currentBatchSize; 26 | 27 | public JdbcPreparedStatementLoader(Connection conn, String tableName, String columnName[], boolean ignore, int maxBatchSize) { 28 | this.conn = conn; 29 | this.tableName = tableName; 30 | this.columnName = columnName; 31 | this.ignore = ignore; 32 | this.maxBatchSize = maxBatchSize; 33 | 34 | StringBuilder b = new StringBuilder(); 35 | b.append("INSERT "); 36 | if (ignore) { 37 | b.append("IGNORE "); 38 | } 39 | b.append("INTO `").append(tableName).append("` ("); 40 | for (int i = 0; i < columnName.length; i++) { 41 | if (i > 0) { 42 | b.append(','); 43 | } 44 | b.append(columnName[i].trim()); 45 | } 46 | b.append(") VALUES ("); 47 | for (int i = 0; i < columnName.length; i++) { 48 | if (i > 0) { 49 | b.append(','); 50 | } 51 | b.append('?'); 52 | } 53 | b.append(')'); 54 | final String sql = b.toString(); 55 | 56 | try { 57 | this.conn.setAutoCommit(false); 58 | this.pstmt = conn.prepareStatement(sql); 59 | } catch (SQLException e) { 60 | throw new RuntimeException("Failed to prepare: " + sql, e); 61 | } 62 | } 63 | 64 | public void load(Record r) throws Exception { 65 | for (int i = 0; i < columnName.length; i++) { 66 | pstmt.setObject(i + 1, r.getField(i)); 67 | } 68 | pstmt.addBatch(); 69 | if (++currentBatchSize == maxBatchSize) { 70 | executeCurrentBatch(); 71 | } 72 | } 73 | 74 | private void executeCurrentBatch() throws Exception { 75 | pstmt.executeBatch(); 76 | currentBatchSize = 0; 77 | } 78 | 79 | public void commit() throws Exception { 80 | conn.commit(); 81 | } 82 | 83 | public void close() throws Exception { 84 | executeCurrentBatch(); 85 | pstmt.close(); 86 | conn.commit(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/load/JdbcStatementLoader.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc.load; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import java.sql.Statement; 6 | import java.util.Date; 7 | 8 | /** 9 | * Copyright (C) 2011 CodeFutures Corporation. All rights reserved. 10 | */ 11 | public class JdbcStatementLoader implements RecordLoader { 12 | 13 | Connection conn; 14 | 15 | Statement stmt; 16 | 17 | String tableName; 18 | 19 | String columnName[]; 20 | 21 | boolean ignore; 22 | 23 | int maxBatchSize; 24 | 25 | int currentBatchSize; 26 | 27 | StringBuilder b = new StringBuilder(); 28 | 29 | public JdbcStatementLoader(Connection conn, String tableName, String columnName[], boolean ignore, int maxBatchSize) { 30 | this.conn = conn; 31 | this.tableName = tableName; 32 | this.columnName = columnName; 33 | this.ignore = ignore; 34 | this.maxBatchSize = maxBatchSize; 35 | } 36 | 37 | public void load(Record r) throws Exception { 38 | if (currentBatchSize == 0) { 39 | b.append("INSERT "); 40 | if (ignore) { 41 | b.append("IGNORE "); 42 | } 43 | b.append("INTO `").append(tableName).append("` ("); 44 | for (int i = 0; i < columnName.length; i++) { 45 | if (i > 0) { 46 | b.append(','); 47 | } 48 | b.append(columnName[i].trim()); 49 | } 50 | b.append(") VALUES "); 51 | } else { 52 | b.append(','); 53 | } 54 | b.append('('); 55 | write(b, r, ","); 56 | b.append(')'); 57 | 58 | if (++currentBatchSize == maxBatchSize) { 59 | executeBulkInsert(); 60 | } 61 | } 62 | 63 | private void executeBulkInsert() throws SQLException { 64 | if (stmt == null) { 65 | stmt = conn.createStatement(); 66 | } 67 | final String sql = b.toString(); 68 | b.setLength(0); 69 | try { 70 | stmt.execute(sql); 71 | } catch (SQLException e) { 72 | throw new RuntimeException("Error loading into table '" + tableName + "' with SQL: " + sql, e); 73 | } 74 | currentBatchSize = 0; 75 | } 76 | 77 | public void write(StringBuilder b, Record r, String delim) throws Exception { 78 | final Object[] field = r.getField(); 79 | for (int i = 0; i < field.length; i++) { 80 | if (i > 0) { 81 | b.append(delim); 82 | } 83 | 84 | final Object fieldValue = field[i]; 85 | 86 | if (fieldValue instanceof Date) { 87 | // b.append("'").append(dateTimeFormat.format((Date)field[i])).append("'"); 88 | b.append("'").append((Date) fieldValue).append("'"); 89 | } else if (fieldValue instanceof String) { 90 | b.append("'").append(fieldValue).append("'"); 91 | } else { 92 | b.append(fieldValue); 93 | } 94 | } 95 | } 96 | 97 | public void commit() throws Exception { 98 | if (!conn.getAutoCommit()) { 99 | conn.commit(); 100 | } 101 | } 102 | 103 | public void close() throws Exception { 104 | if (currentBatchSize > 0) { 105 | executeBulkInsert(); 106 | } 107 | stmt.close(); 108 | if (!conn.getAutoCommit()) { 109 | conn.commit(); 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/load/Record.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc.load; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Simple object to represent a single row of data being loaded to the database (or written to a CSV file). 7 | */ 8 | public class Record { 9 | 10 | /** 11 | * Column values. 12 | */ 13 | private final Object field[]; 14 | 15 | /** 16 | * Index of next column to write value to. 17 | */ 18 | private int index; 19 | 20 | /** 21 | * Re-usable buffer for building string representations of the row. 22 | */ 23 | private final StringBuilder toStringBuilder = new StringBuilder(); 24 | 25 | public Record(int columnCount) { 26 | this.field = new Object[columnCount]; 27 | } 28 | 29 | public void reset() { 30 | index = 0; 31 | } 32 | 33 | public void add(Object value) { 34 | field[index++] = value; 35 | } 36 | 37 | public Object getField(int i) { 38 | return field[i]; 39 | } 40 | 41 | public Object[] getField() { 42 | return field; 43 | } 44 | 45 | public int getColumnCount() { 46 | return field.length; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return Arrays.toString(field); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/codefutures/tpcc/load/RecordLoader.java: -------------------------------------------------------------------------------- 1 | package com.codefutures.tpcc.load; 2 | 3 | /** 4 | * Copyright (C) 2011 CodeFutures Corporation. All rights reserved. 5 | */ 6 | public interface RecordLoader { 7 | 8 | void load(Record r) throws Exception; 9 | 10 | void commit() throws Exception; 11 | 12 | void close() throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tpcc.properties: -------------------------------------------------------------------------------- 1 | # TPC-C configuration properties 2 | # 3 | # See the README.txt first! 4 | # 5 | 6 | ############################################################ 7 | ## Number of warehouses (used both for data loading and ## 8 | ## running the benchmark). ## 9 | ############################################################ 10 | 11 | WAREHOUSECOUNT=1 12 | 13 | ############################################################ 14 | ## Data generation / loading properties ## 15 | ############################################################ 16 | 17 | # Data can be generated to tab delimited text files 18 | # suitable for loading into MySQL with LOAD DATA INFILE 19 | # or can be loaded directly via JDBC 20 | #MODE=FILE 21 | MODE=JDBC 22 | 23 | # For FILE mode, specify the output directory for the files. 24 | # Typically it is easiest to generate directly to the MySQL 25 | # database directory 26 | OUTPUTDIR=output 27 | 28 | # Specify which shard to load data for and the total number 29 | # of shards. Data is sharded based on warehouse ID. 30 | SHARDID=1 31 | SHARDCOUNT=1 32 | 33 | ############################################################ 34 | ## Database connection details used for loading data in ## 35 | ## JDBC mode and also used for running the benchmarks. ## 36 | ############################################################ 37 | 38 | # MySQL 39 | DRIVER=com.mysql.jdbc.Driver 40 | JDBCURL=jdbc:mysql://127.0.0.1:3306/tpcc?useSSL=false&serverTimezone=UTC&autoReconnect=true 41 | JDBCFETCHSIZE=-2147483648 42 | 43 | # dbShards 44 | #DRIVER=com.dbshards.jdbc.Driver 45 | #JDBCURL=jdbc:dbshards://tpcc/client 46 | 47 | # Credentials 48 | USER=root 49 | PASSWORD= 50 | 51 | ############################################################ 52 | # Settings used for Tpcc benchmark only 53 | ############################################################ 54 | CONNECTIONS=30 55 | RAMPUPTIME=45 56 | DURATION=60 57 | 58 | --------------------------------------------------------------------------------