You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by dj...@apache.org on 2007/01/18 05:28:33 UTC

svn commit: r497297 - in /db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe: client/Load.java load/ load/SimpleInsert.java run/Load.java run/Populate.java test/LoadTester.java test/OETest.java util/ util/OERandom.java

Author: djd
Date: Wed Jan 17 20:28:32 2007
New Revision: 497297

URL: http://svn.apache.org/viewvc?view=rev&rev=497297
Log:
DERBY-2095 patch for the load(population) phase for the Order Entry benchmark.

0)Add interface for Load (oe\client\Load.java) so that the load framework is extensible to have different load

implementations.
1)Add the implementation to do the database population using simple insert sql statements per TPC-C specification
Note, this implementation is single threaded. But in future we can add support for multiple worker threads to do the

load phase. (oe\load\SimpleInsert.java)
2) Add cardinality checks for all the tables
3) Add driver that includes performance tests for load phase. (oe\run\Load.java)
4) Add the framework to test the load for a scale of 1 to use it as a functional test. (oe\test\OETest and LoadTester)
5) Remove the earlier skeleton class that loaded only the schema (Load.java is deleted) and instead
Populate.java takes care of providing that functionality.

Contributed by Sunitha Kambhampati - ksunithaghm@gmail.com

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java   (with props)
Removed:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Load.java
Modified:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/OETest.java

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java?view=auto&rev=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java Wed Jan 17 20:28:32 2007
@@ -0,0 +1,158 @@
+/*
+ *
+ * Derby - Class org.apache.derbyTesting.system.oe.client.Load
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, 
+ * software distributed under the License is distributed on an 
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
+ * either express or implied. See the License for the specific 
+ * language governing permissions and limitations under the License.
+ */
+package org.apache.derbyTesting.system.oe.client;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Interface for a client to populate the database. Various implementations can
+ * be provided, e.g. via SQL, via VTI, via import etc
+ * An implementation for Load must be able to do the following
+ * <OL>
+ * <LI> Use the setupLoad to perform any necessary initialization for the load
+ * phase
+ * <LI> Load data into the tables 
+ * <LI> Provide information about cardinality of rows in each table.
+ * </OL>
+ * <P>
+ * DECIMAL values are represented as String objects to allow Order Entry to be
+ * run on J2ME/CDC/Foundation which does not support BigDecimal.
+ */
+public interface Load {
+
+    /**
+     * Cardinality constants 
+     * These numbers are factored by W, the number of Warehouses,
+     * to illustrate the database scaling.
+     * 
+     * see section 1.2.1 of TPC-C specification
+     */
+    public static final short DISTRICT_COUNT_W = 10;
+
+    public static final int CUSTOMER_COUNT_W = 3000 * DISTRICT_COUNT_W;
+
+    public static final int ITEM_COUNT = 100000;
+
+    public static final int NEWORDERS_COUNT_W = (CUSTOMER_COUNT_W * 9) / 30;
+
+    // 1 per customer initially
+    public static final int HISTORY_COUNT_W = CUSTOMER_COUNT_W; 
+
+    public static final int STOCK_COUNT_W = ITEM_COUNT;
+
+    public static final int ORDERS_COUNT_W = CUSTOMER_COUNT_W;
+
+    //  5 to 15 , per order. so average 10
+    public static final int ORDERLINE_COUNT_WV = ORDERS_COUNT_W * 10; 
+
+    public static final int NEWORDERS_BREAKPOINT = 
+        (ORDERS_COUNT_W - NEWORDERS_COUNT_W)/ DISTRICT_COUNT_W;
+
+    /**
+     * Return the warehouse scale factor of the database. 
+     * @return
+     */
+    public short getScale();
+
+    /**
+     * Perform the necessary setup before database population.
+     * @param conn - database connection 
+     * @param scale - scale of the database.  The WAREHOUSE table is 
+     * used as the base unit of scaling. 
+     * @throws Exception
+     */
+    public void setupLoad(Connection conn, short scale) throws Exception;
+
+    /**
+     * Follow the initial database population requirements in Section 4.3.3 
+     * and populate all the required tables.
+     * @throws SQLException
+     */
+    public void populateAllTables() throws SQLException;
+
+    /**
+     * Return the number of rows in the table. 
+     * A simple select count(*) from tableName 
+     * @param tableName - name of the table
+     * @throws SQLException
+     */
+    public int rowsInTable(String tableName) throws SQLException;
+
+    /**
+     * Populate the ITEM table 
+     * See population requirements in section 4.3.3.1
+     * <BR>
+     * @param itemStart insert item information starting from this Item id (ITEM.I_ID) 
+     * @param itemEnd  last Item id (ITEM.I_ID) for inserting information for
+     * @throws SQLException
+     */
+    public void itemTable(int itemStart, int itemEnd) throws SQLException;
+
+    /**
+     * Populate the WAREHOUSE table for a given warehouse.
+     * See population requirements in section 4.3.3.1
+     * @param w WAREHOUSE ID (W_ID)
+     * @throws SQLException
+     */
+    public void warehouseTable(short w) throws SQLException;
+
+    /**
+     * Populate the STOCK table for a given warehouse.
+     * See population requirements in section 4.3.3.1
+     * <BR>
+     * @param itemStart insert stocks of items from this Item id (ITEM.I_ID) 
+     * @param itemEnd  last Item id (ITEM.I_ID) to insert stocks of times for.
+     * @param w WAREHOUSE id (W_ID) for which the stock is populated.
+     * @throws SQLException
+     */
+    public void stockTable(int itemStart, int itemEnd, short w)
+    throws SQLException;
+
+    /**
+     * Populate the DISTRICT table for a given warehouse.
+     * See population requirements in section 4.3.3.1
+     * <BR>
+     * @param w - WAREHOUSE id (W_ID)
+     * @param d - DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void districtTable(short w, short d) throws SQLException;
+
+    /**
+     * Populate the CUSTOMER table for a given district for a specific warehouse.
+     * See population requirements in section 4.3.3.1
+     * <BR>
+     * @param w - WAREHOUSE id (W_ID)
+     * @param d - DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void customerTable(short w, short d) throws SQLException;
+
+    /**
+     * Populate the ORDER table 
+     * See population requirements in section 4.3.3.1
+     * @param w - WAREHOUSE id (W_ID)
+     * @param d - DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void orderTable(short w, short d) throws SQLException;
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/client/Load.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java?view=auto&rev=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java Wed Jan 17 20:28:32 2007
@@ -0,0 +1,440 @@
+/*
+ *
+ * Derby - Class org.apache.derbyTesting.system.oe.load.SimpleInsert
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, 
+ * software distributed under the License is distributed on an 
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
+ * either express or implied. See the License for the specific 
+ * language governing permissions and limitations under the License.
+ */
+package org.apache.derbyTesting.system.oe.load;
+
+import java.sql.*;
+
+import org.apache.derbyTesting.system.oe.client.Load;
+import org.apache.derbyTesting.system.oe.util.OERandom;
+
+/**
+ * Implement the initial database population according to the TPC-C database
+ * population requirements in Clause 4.3 using simple Insert sql statements
+ */
+public class SimpleInsert implements Load {
+
+    /**
+     * database connection
+     */
+    Connection conn = null;
+
+    /**
+     * warehouse scale factor, default to 1.
+     */
+    short scale = 1;
+
+    /**
+     * Utility to generate random data per the TPC-C requirements
+     */
+    OERandom random;
+
+    /**
+     * Create an instance of this implementation. Connection will be set to non
+     * auto commit mode and SERIALIZABLE isolation.
+     */
+    public SimpleInsert(Connection conn, short scale) throws SQLException {
+        this.conn = conn;
+        conn.setAutoCommit(false);
+        conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
+        setupLoad(conn, scale);
+    }
+
+    /**
+     * return the warehouse scale factor
+     * 
+     * @see org.apache.derbyTesting.system.oe.client.Load#getScale()
+     */
+    public short getScale() {
+        return scale;
+    }
+
+    /**
+     * Perform the necessary setup before database population.
+     * 
+     * @param conn -
+     *            database connection
+     * @param scale -
+     *            scale of the database. The WAREHOUSE table is used as the base
+     *            unit of scaling.
+     * @throws Exception
+     */
+    public void setupLoad(Connection conn, short scale) throws SQLException {
+        Statement s = conn.createStatement();
+        try {
+            s.execute("DROP TABLE C");
+        } catch (SQLException sqle) {
+            // ignore
+        }
+        conn.commit();
+        s.execute("CREATE TABLE C(CLOAD INT, CLAST INT, CID INT, CITEM INT)");
+        conn.commit();
+
+        random = new OERandom(-1, -1, -1);
+
+        // Section 2.1.6.1 of TPC-C spec
+        int loadRandomFactor = random.randomInt(0, 255);
+        s.execute("INSERT INTO C VALUES(" + loadRandomFactor + ", -1, -1, -1)");
+        random = new OERandom(loadRandomFactor, -1, -1);
+        conn.commit();
+
+        this.scale = scale;
+    }
+
+    /**
+     * Follow the initial database population requirements in Section 4.3.3 and
+     * populate all the required tables.
+     * 
+     * @throws SQLException
+     */
+    public void populateAllTables() throws SQLException {
+        // load item table
+        itemTable(1, Load.ITEM_COUNT);
+
+        // for each row in warehouse table, load the stock,
+        // district table. For each row in district table, load
+        // the customer table. for each row in customer table, load
+        // the history, and order table.
+
+        for (short w = 0; w < scale; w++) {
+            warehouseTable(w);
+            // for each warehouse: load the stock table
+            stockTable(1, Load.STOCK_COUNT_W, w);
+            for (short d = 0; d < Load.DISTRICT_COUNT_W; d++) {
+                districtTable(w, d);
+                customerTable(w, d);
+                orderTable(w, d);
+            }
+        }
+
+    }
+
+    /**
+     * Return the number of rows in the table. A simple select count(*) from
+     * tableName
+     * 
+     * @param tableName -
+     *            name of the table
+     * @throws SQLException
+     */
+    public int rowsInTable(String table) throws SQLException {
+        Statement stmt = conn.createStatement();
+        ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM " + table);
+        rs.next();
+        int count = rs.getInt(1);
+        rs.close();
+        stmt.close();
+
+        return count;
+    }
+
+    /**
+     * Populate the ITEM table. See population requirements in section 4.3.3.1
+     * <BR>
+     * 
+     * @param itemStart
+     *            insert item information starting from this Item id (ITEM.I_ID)
+     * @param itemEnd
+     *            last Item id (ITEM.I_ID) for inserting information for
+     * @throws SQLException
+     */
+    public void itemTable(int itemStart, int itemEnd) throws SQLException {
+        PreparedStatement ps = conn
+                .prepareStatement("INSERT INTO ITEM(I_ID,I_IM_ID,I_NAME,I_PRICE,I_DATA)"
+                        + " VALUES (?, ?, ?, ?, ?)");
+
+        String price;
+
+        for (int i = itemStart; i <= itemEnd; i++) {
+            ps.setInt(1, i);
+            ps.setInt(2, random.randomInt(1, 10000));
+            ps.setString(3, random.randomAString14_24());
+            price = random.randomDecimalString(100, 9999, 2);
+            ps.setString(4, price);
+            ps.setString(5, random.randomData());
+            ps.executeUpdate();
+
+            if ((i % (1000)) == 0) {
+                conn.commit();
+            }
+        }
+        conn.commit();
+        ps.close();
+    }
+
+    /**
+     * Populate the WAREHOUSE table for a given warehouse. See population
+     * requirements in section 4.3.3.1
+     * 
+     * @param w
+     *            WAREHOUSE ID (W_ID) to insert data for.
+     * @throws SQLException
+     */
+    public void warehouseTable(short w) throws SQLException {
+        PreparedStatement ps = conn.prepareStatement("INSERT INTO WAREHOUSE "
+                + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, 300000.00)");
+
+        ps.setShort(1, w);
+        ps.setString(2, random.randomAString(6, 10));
+        ps.setString(3, random.randomAString10_20());
+        ps.setString(4, random.randomAString10_20());
+        ps.setString(5, random.randomAString10_20());
+        ps.setString(6, random.randomState());
+        ps.setString(7, random.randomZIP());
+        ps.setString(8, random.randomDecimalString(0, 2000, 4));
+
+        ps.executeUpdate();
+        conn.commit();
+        ps.close();
+    }
+
+    /**
+     * Populate the STOCK table for a given warehouse. See population
+     * requirements in section 4.3.3.1 <BR>
+     * 
+     * @param itemStart
+     *            insert stocks of items from this Item id (ITEM.I_ID)
+     * @param itemEnd
+     *            last Item id (ITEM.I_ID) to insert stocks of times for.
+     * @param w
+     *            WAREHOUSE id (W_ID) for which the stock is populated.
+     * @throws SQLException
+     */
+    public void stockTable(int itemStart, int itemEnd, short w)
+            throws SQLException {
+        PreparedStatement ps = conn.prepareStatement("INSERT INTO STOCK "
+                + "(S_I_ID, S_W_ID, S_QUANTITY,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,"
+                + "S_ORDER_CNT, S_REMOTE_CNT, S_YTD, S_DATA ) VALUES "
+                + "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, 0, 0, ?)");
+
+        ps.setShort(2, w);
+
+        for (int i = itemStart; i <= itemEnd; i++) {
+            ps.setInt(1, i);
+            ps.setInt(3, random.randomInt(10, 100));
+            ps.setString(4, random.randomAString24());
+            ps.setString(5, random.randomAString24());
+            ps.setString(6, random.randomAString24());
+            ps.setString(7, random.randomAString24());
+            ps.setString(8, random.randomAString24());
+            ps.setString(9, random.randomAString24());
+            ps.setString(10, random.randomAString24());
+            ps.setString(11, random.randomAString24());
+            ps.setString(12, random.randomAString24());
+            ps.setString(13, random.randomAString24());
+
+            ps.setString(14, random.randomData());
+            ps.executeUpdate();
+
+            if ((i % 1000) == 0) {
+                conn.commit();
+            }
+        }
+        conn.commit();
+        ps.close();
+    }
+
+    /**
+     * Populate the DISTRICT table for a given warehouse. See population
+     * requirements in section 4.3.3.1 <BR>
+     * 
+     * @param w -
+     *            WAREHOUSE id (W_ID)
+     * @param d -
+     *            DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void districtTable(short w, short d) throws SQLException {
+        PreparedStatement ps = conn.prepareStatement("INSERT INTO DISTRICT"
+                + " (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) "
+                + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, 30000.00, 3001)");
+
+        ps.setShort(1, d);
+        ps.setShort(2, w);
+        ps.setString(3, random.randomAString(6, 10));
+        ps.setString(4, random.randomAString10_20());
+        ps.setString(5, random.randomAString10_20());
+        ps.setString(6, random.randomAString10_20());
+        ps.setString(7, random.randomState());
+        ps.setString(8, random.randomZIP());
+        ps.setString(9, random.randomDecimalString(0, 2000, 4));
+        ps.executeUpdate();
+        conn.commit();
+        ps.close();
+
+    }
+
+    /**
+     * Populate the CUSTOMER table for a given district for a specific
+     * warehouse. See population requirements in section 4.3.3.1 <BR>
+     * 
+     * @param w -
+     *            WAREHOUSE id (W_ID)
+     * @param d -
+     *            DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void customerTable(short w, short d) throws SQLException {
+        PreparedStatement psC = conn.prepareStatement("INSERT INTO CUSTOMER"
+                + " (C_ID, C_D_ID, C_W_ID, C_FIRST, C_MIDDLE, C_LAST,"
+                + " C_STREET_1, C_STREET_2,  C_CITY, C_STATE, C_ZIP, "
+                + "C_PHONE, C_SINCE, C_CREDIT, C_CREDIT_LIM,"
+                + " C_DISCOUNT, C_BALANCE, C_YTD_PAYMENT, "
+                + "C_PAYMENT_CNT, C_DELIVERY_CNT, C_DATA)  "
+                + "VALUES (?, ?, ?, ?, 'OE', ?, ?, ?, ?, ?, ?, ?, "
+                + " CURRENT TIMESTAMP ,?, 50000.00, ?, -10.0, 10.0,"
+                + " 1, 0, ?)");
+
+        PreparedStatement psH = conn
+                .prepareStatement("INSERT INTO HISTORY (H_C_ID, H_C_D_ID, H_C_W_ID, H_D_ID, H_W_ID, H_DATE, H_AMOUNT, H_DATA) VALUES (?, ?, ?, ?, ?, CURRENT TIMESTAMP, 10.00, ?)");
+
+        psC.setShort(2, d); // c_d_id
+        psC.setShort(3, w); // c_w_id
+        psH.setShort(2, d);
+        psH.setShort(3, w);
+        psH.setShort(4, d);
+        psH.setShort(5, w);
+        for (int c = 1; c <= Load.CUSTOMER_COUNT_W / Load.DISTRICT_COUNT_W; c++) {
+            psC.setInt(1, c); // c_id
+            psC.setString(4, random.randomAString8_16()); // c_first
+
+            psC.setString(5, random.randomCLastPopulate(c)); // c_last
+            psC.setString(6, random.randomAString10_20()); // c_street_1
+            psC.setString(7, random.randomAString10_20()); // c_street_2
+            psC.setString(8, random.randomAString10_20()); // c_city
+            psC.setString(9, random.randomState()); // c_state
+            psC.setString(10, random.randomZIP()); // c_zip
+            psC.setString(11, random.randomNString(16, 16)); // c_phone
+
+            psC.setString(12, Math.random() < 0.10 ? "BC" : "GC"); // c_credit
+
+            psC.setString(13, random.randomDecimalString(0, 5000, 4)); // c_discount
+
+            String str = random.randomAString300_500();
+            if (str.length() > 255)
+                str = str.substring(255);
+            psC.setString(14, str); // c_data
+
+            psC.executeUpdate();
+
+            psH.setInt(1, c);
+            psH.setString(6, random.randomAString(12, 24));
+            psH.executeUpdate();
+
+            if ((c % 1000) == 0) {
+                conn.commit();
+            }
+
+        }
+        conn.commit();
+
+        psC.close();
+        psH.close();
+    }
+
+    /**
+     * Populate the ORDER table See population requirements in section 4.3.3.1
+     * 
+     * @param w -
+     *            WAREHOUSE id (W_ID)
+     * @param d -
+     *            DISTRICT id (D_ID)
+     * @throws SQLException
+     */
+    public void orderTable(short w, short d) throws SQLException {
+
+        PreparedStatement psO = conn
+                .prepareStatement("INSERT INTO ORDERS (O_ID, O_D_ID, O_W_ID, O_C_ID, O_ENTRY_D, O_CARRIER_ID, O_OL_CNT, O_ALL_LOCAL) VALUES (?, ?, ?, ?, ?, ?, ?, 1)");
+
+        PreparedStatement psOL = conn
+                .prepareStatement("INSERT INTO ORDERLINE (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)  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
+
+        PreparedStatement psNO = conn
+                .prepareStatement("INSERT INTO NEWORDERS (NO_O_ID, NO_D_ID, NO_W_ID) VALUES (?, ?, ?)");
+
+        psO.setShort(2, d);
+        psO.setShort(3, w);
+        
+        // Section 4.3.3.1 of TPC-C specification revision 5.8.0
+        // O_C_ID selected sequentially from a random permutation 
+        // of [1 .. 3,000]
+        int[] cid = random.randomIntPerm(Load.CUSTOMER_COUNT_W
+                / Load.DISTRICT_COUNT_W);
+        
+        for (int o_id = 0; o_id < cid.length; o_id++) {
+            psO.setInt(1, o_id);
+            psO.setInt(4, cid[o_id]);
+
+            Timestamp o_entry_d = new Timestamp(System.currentTimeMillis());
+
+            psO.setTimestamp(5, o_entry_d);
+
+            if (o_id < Load.NEWORDERS_BREAKPOINT)
+                psO.setShort(6, (short) random.randomInt(1, 10));
+            else
+                psO.setNull(6, Types.SMALLINT);
+
+            int o_ol_cnt = random.randomInt(5, 15);
+            psO.setInt(7, o_ol_cnt);
+
+            psO.executeUpdate();
+
+            psOL.setShort(2, d);
+            psOL.setShort(3, w);
+            psNO.setShort(2, d);
+            psNO.setShort(3, w);
+            for (int ol_number = 0; ol_number < o_ol_cnt; ol_number++) {
+
+                psOL.setInt(1, o_id);
+                psOL.setInt(4, ol_number);
+
+                // OL_I_ID random within [1 .. 100,000]
+                psOL.setInt(5, random.randomInt(1, Load.ITEM_COUNT));
+                psOL.setShort(6, w);
+                if (o_id < Load.NEWORDERS_BREAKPOINT) {
+                    psOL.setTimestamp(7, o_entry_d);
+                    psOL.setString(9, "0.00");
+                } else {
+                    psOL.setNull(7, Types.TIMESTAMP);
+                    psOL.setString(9, random.randomDecimalString(1, 999999, 2));
+                }
+                psOL.setInt(8, 5);
+                psOL.setString(10, random.randomAString24());
+                psOL.executeUpdate();
+            }
+            if (o_id >= Load.NEWORDERS_BREAKPOINT) {
+                psNO.setInt(1, o_id);
+                psNO.executeUpdate();
+            }
+            if ((o_id % 1000) == 0) {
+                conn.commit();
+            }
+
+        }
+        conn.commit();
+
+        psOL.close();
+        psO.close();
+        psNO.close();
+    }
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/load/SimpleInsert.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java?view=auto&rev=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java Wed Jan 17 20:28:32 2007
@@ -0,0 +1,386 @@
+/*
+ * 
+ * Derby - Class org.apache.derbyTesting.system.oe.run.Populate
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.derbyTesting.system.oe.run;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.PrivilegedActionException;
+import java.sql.SQLException;
+
+import junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.apache.derbyTesting.junit.JDBCPerfTestCase;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+import org.apache.derbyTesting.system.oe.client.Load;
+import org.apache.derbyTesting.system.oe.load.SimpleInsert;
+
+
+/**
+ * Driver to do the load phase for the Order Entry benchmark.
+ * 
+ * This class takes in following arguments currently:
+ * Usage: java org.apache.derbyTesting.system.oe.run.Populate options
+ * Options:
+ * <OL>
+ * <LI>-scale warehouse scaling factor. Takes a short value. If not specified defaults to 1
+ * <LI>-createConstraintsBeforeLoad create constraints before initial load of data, takes a boolean value. If not specified, defaults to true
+ * <LI>-doChecks check consistency of data, takes a boolean value. If not specified, defaults to true
+ * <LI>-help prints usage
+ * </OL>
+ * 
+ * To load database with scale of 2, to load constraints after the population, 
+ * and to not do any checks, the command to run the test is as follows:
+ * <BR>
+ * java org.apache.derbyTesting.system.oe.run.Populate -scale 2 -doChecks false -createConstraintsBeforeLoad false
+ * <BR>
+ * This class uses the junit performance framework in Derby and 
+ * the tests the performance of the following operations. 
+ * 
+ * <OL>
+ * <LI> create schema with or without constraints (configurable)
+ * <LI> populate the schema
+ * <LI> Check the cardinality of the tables.
+ * </OL>
+ */
+public class Populate extends JDBCPerfTestCase {
+
+    /**
+     * Warehouse scale factor
+     */
+    private static short scale = 1;
+
+    /**
+     * flag to indicate if we should create constraints before loading data
+     */
+    private static boolean createConstraintsBeforeLoad = true;
+    
+    /**
+     * flag to indicate if we should perform consistency, cardinality checks
+     * after the load
+     */
+    private static boolean doChecks = true;
+    
+    /**
+     * Load implementation used to populate the database
+     */
+    private Load loader;
+
+    /**
+     * Create a test case with the given name.
+     * 
+     * @param name
+     *            of the test case.
+     */
+    public Populate(String name) {
+        super(name);
+    }
+
+
+    /**
+     * Do the initial setup required Initialize the appropriate implementation
+     * for the Load phase.
+     */
+    public void setUp() throws Exception {
+        // Use simple insert statements to insert data.
+        // currently only this form of load is present, once we have 
+        // different implementations, the loading mechanism will need
+        // to be configurable taking an option from the command line
+        // arguments.
+       loader = new SimpleInsert(getConnection(), scale);
+    }
+
+    /**
+     * Run OE load
+     * @param args supply arguments for benchmark.
+     * @throws Exception
+     */
+    public static void main(String[] args) throws Exception
+    {
+        parseArgs(args);
+        String[] tmp= {"org.apache.derbyTesting.system.oe.run.Populate"};
+        
+        // run the tests.
+        junit.textui.TestRunner.main(tmp);
+    }
+    
+    /**
+     * parse arguments.
+     * @param args arguments to parse
+     */
+    private static void parseArgs(String[] args) {
+        for (int i = 0; i < args.length; i++) {
+            String arg = args[i];
+            if (arg.equals("-scale")) {
+                scale = Short.parseShort(args[++i]);
+            } else if (arg.equals("-createConstraintsBeforeLoad")) {
+                createConstraintsBeforeLoad = (args[++i].equals("false")? false:true);
+            } else if (arg.equals("-doChecks")) {
+                doChecks = (args[++i].equals("false")? false:true);
+            } else if (arg.equals("-help")) {
+                printUsage();
+                System.exit(0);
+            } else {
+                System.err.println("Invalid option: " + args[i]);
+                System.exit(1);
+            }
+        }
+        
+    }
+
+    private static void printUsage() {
+        System.out.println("Usage: java org.apache.derbyTesting.system.oe.run.Populate options");
+        System.out.println();
+        System.out.println("Options:");
+        System.out.println("  -scale warehouse scaling factor. Takes a short value. If not specified defaults to 1");
+        System.out.println("  -createConstraintsBeforeLoad create constraints before initial load of data, takes a boolean value. If not specified, defaults to true)");
+        System.out.println("  -doChecks check consistency of data, takes a boolean value. If not specified, defaults to true)");
+        System.out.println("  -help prints usage");
+        System.out.println();
+    }
+
+    /**
+     * junit tests to do the OE load.
+     * 
+     * @return the tests to run
+     */
+    public static Test suite() throws Exception {
+        TestSuite suite = new TestSuite("Order Entry");
+
+        // Create Schema
+        suite.addTest(new Populate("testSchema"));
+        if (createConstraintsBeforeLoad)
+            addConstraints(suite);
+        // this will populate db
+        suite.addTest(new Populate("testLoad"));
+
+        if (!createConstraintsBeforeLoad)
+            addConstraints(suite);
+
+        if (doChecks)
+        {
+            //check if cardinality of rows are OK after
+            //population phase.
+            suite.addTest(new Populate("testWarehouseRows"));
+            suite.addTest(new Populate("testStockRows"));
+            suite.addTest(new Populate("testItemRows"));
+            suite.addTest(new Populate("testCustomerRows"));
+            suite.addTest(new Populate("testDistrictRows"));
+            suite.addTest(new Populate("testOrdersRows"));
+            suite.addTest(new Populate("testNewOrdersRows"));
+            suite.addTest(new Populate("testOrderLineRows"));
+            suite.addTest(new Populate("testHistoryRows"));
+        }
+        
+        return suite;
+    }
+
+    /**
+     * Add constraint tests to suite.
+     * 
+     * @param suite
+     */
+    private static void addConstraints(TestSuite suite) {
+        suite.addTest(new Populate("testPrimaryKey"));
+        suite.addTest(new Populate("testForeignKey"));
+        suite.addTest(new Populate("testIndex"));
+
+    }
+
+    /**
+     * Test setting up the base tables.
+     */
+    public void testSchema() throws UnsupportedEncodingException, SQLException,
+    PrivilegedActionException, IOException {
+        script("schema.sql");
+    }
+
+    /**
+     * Test setting up the primary keys.
+     */
+    public void testPrimaryKey() throws UnsupportedEncodingException,
+    SQLException, PrivilegedActionException, IOException {
+        script("primarykey.sql");
+    }
+
+    /**
+     * Test setting up the foreign keys.
+     */
+    public void testForeignKey() throws UnsupportedEncodingException,
+    SQLException, PrivilegedActionException, IOException {
+        script("foreignkey.sql");
+    }
+
+    /**
+     * Test setting up the remaining indexes.
+     */
+    public void testIndex() throws UnsupportedEncodingException, SQLException,
+    PrivilegedActionException, IOException {
+        script("index.sql");
+    }
+
+    /**
+     * test the initial database load
+     * 
+     * @throws Exception
+     */
+    public void testLoad() throws Exception {
+        loader.populateAllTables();
+
+        // Way to populate data is extensible. Any other implementation
+        // of org.apache.derbyTesting.system.oe.client.Load can be used
+        // to load data. configurable using the oe.load.insert property
+        // that is defined in oe.properties
+        // One extension would be to have an implementation that 
+        // uses bulkinsert vti to load data.
+
+    }
+
+    /**
+     * Test cardinality of WAREHOUSE table
+     * 
+     * @throws Exception
+     */
+    public void testWarehouseRows() throws Exception {
+        checkCountStar("WAREHOUSE", loader.getScale());
+    }
+
+    /**
+     * Test cardinality of STOCK table
+     * 
+     * @throws Exception
+     */
+    public void testStockRows() throws Exception {
+        checkCountStar("STOCK", Load.STOCK_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of ORDERS table
+     * 
+     * @throws Exception
+     */
+    public void testOrdersRows() throws Exception {
+        checkCountStar("ORDERS", Load.ORDERS_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of DISTRICT table
+     * 
+     * @throws Exception
+     */
+    public void testDistrictRows() throws Exception {
+        checkCountStar("DISTRICT", Load.DISTRICT_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of CUSTOMER table
+     * 
+     * @throws Exception
+     */
+    public void testCustomerRows() throws Exception {
+        checkCountStar("CUSTOMER", Load.CUSTOMER_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of ITEM table
+     * 
+     * @throws Exception
+     */
+    public void testItemRows() throws Exception {
+        checkCountStar("ITEM", Load.ITEM_COUNT);
+    }
+
+    /**
+     * Test cardinality of NEWORDERS table
+     * 
+     * @throws Exception
+     */
+    public void testNewOrdersRows() throws Exception {
+        checkCountStar("NEWORDERS", Load.NEWORDERS_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of HISTORY table
+     * 
+     * @throws Exception
+     */
+    public void testHistoryRows() throws Exception {
+        checkCountStar("HISTORY", Load.HISTORY_COUNT_W * loader.getScale());
+    }
+
+    /**
+     * Test cardinality of ORDERLINE table
+     * 
+     * @throws Exception
+     */
+    public void testOrderLineRows() throws Exception {
+        checkWithinOnePercent("ORDERLINE", Load.ORDERLINE_COUNT_WV
+                * loader.getScale());
+    }
+
+    /**
+     * Check if number of rows in table is as expected
+     * 
+     * @param table -
+     *            table on which to execute the query
+     * @param expected -
+     *            expected number of rows
+     * @throws Exception
+     */
+    private void checkCountStar(String table, int expected) throws Exception {
+        Assert.assertEquals("Number of rows loaded for " + table
+                + " not correct", expected, loader.rowsInTable(table));
+    }
+
+    /**
+     * Check if number of rows in table is within one percent of expected value
+     * 
+     * @param table -
+     *            table on which to execute the query
+     * @param expected -
+     *            expected number of rows
+     * @throws Exception
+     */
+    private void checkWithinOnePercent(String tableName, int expected)
+    throws Exception {
+
+        double count = loader.rowsInTable(tableName);
+
+        double low = ((double) expected) * 0.99;
+        double high = ((double) expected) * 1.01;
+
+        Assert.assertEquals("Initial rows" + count + " in " + tableName
+                + " is out of range.[" + low + "-" + high + "]", false,
+                ((count < low) || (count > high)));
+
+    }
+
+    /**
+     * Run a Order Entry script.
+     */
+    private void script(String name) throws UnsupportedEncodingException,
+    SQLException, PrivilegedActionException, IOException {
+
+        String script = "org/apache/derbyTesting/system/oe/schema/" + name;
+        int errorCount = runScript(script, "US-ASCII");
+        assertEquals("Errors in script ", 0, errorCount);
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/run/Populate.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java?view=auto&rev=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java Wed Jan 17 20:28:32 2007
@@ -0,0 +1,104 @@
+/*
+ *
+ * Derby - Class org.apache.derbyTesting.system.oe.test.LoadTester
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, 
+ * software distributed under the License is distributed on an 
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
+ * either express or implied. See the License for the specific 
+ * language governing permissions and limitations under the License.
+ */
+package org.apache.derbyTesting.system.oe.test;
+
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import junit.framework.Assert;
+import org.apache.derbyTesting.system.oe.client.Load;
+/**
+ * Test an implementation of Load.
+ */
+class LoadTester  {
+
+    private final Load load;
+
+    LoadTester(Load load) {
+        this.load = load;
+    }
+
+    /**
+     * test the population of database
+     * @throws Exception
+     */
+    void test() throws Exception
+    {
+        load.populateAllTables();
+    }
+
+    public void testWarehouseRows() throws Exception
+    {
+        checkCountStar("WAREHOUSE",load.getScale());
+    }
+
+    public void testStockRows() throws Exception
+    {
+        checkCountStar("STOCK",Load.STOCK_COUNT_W*load.getScale());
+    }
+
+    public void testOrdersRows() throws Exception
+    {
+        checkCountStar("ORDERS",Load.ORDERS_COUNT_W*load.getScale());
+    }
+    public void testDistrictRows() throws Exception
+    {
+        checkCountStar("DISTRICT",Load.DISTRICT_COUNT_W*load.getScale());
+    }
+    public void testCustomerRows() throws Exception
+    {
+        checkCountStar("CUSTOMER",Load.CUSTOMER_COUNT_W*load.getScale());
+    }
+    public void testItemRows() throws Exception
+    {
+        checkCountStar("ITEM",Load.ITEM_COUNT);
+    }
+    public void testNewOrdersRows() throws Exception
+    {
+        checkCountStar("NEWORDERS",Load.NEWORDERS_COUNT_W*load.getScale());
+    }
+    public void testHistoryRows() throws Exception
+    {
+        checkCountStar("HISTORY",Load.HISTORY_COUNT_W*load.getScale());
+    }
+
+    public void testOrderLineRows() throws Exception
+    {
+        checkWithinOnePercent("ORDERLINE",Load.ORDERLINE_COUNT_WV*load.getScale());
+    }
+
+    void checkCountStar(String table, int expected) throws Exception
+    {
+        Assert.assertEquals("Number of rows loaded for "+ table +" not correct",expected, load.rowsInTable(table));
+    }    
+
+    void checkWithinOnePercent(String tableName, int expected)
+    throws Exception {
+
+        double count = load.rowsInTable(tableName);
+
+        double low =  ((double) expected) * 0.99;
+        double high =  ((double) expected) * 1.01;
+
+        Assert.assertEquals("Initial rows"+count+" in "+tableName+" is out of range.["+low+"-"+high+"]", false, ((count < low) || (count > high)));
+
+    }
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/LoadTester.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/OETest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/OETest.java?view=diff&rev=497297&r1=497296&r2=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/OETest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/test/OETest.java Wed Jan 17 20:28:32 2007
@@ -29,8 +29,10 @@
 
 import org.apache.derbyTesting.junit.BaseJDBCTestCase;
 import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
-import org.apache.derbyTesting.system.oe.client.Operations;
 import org.apache.derbyTesting.system.oe.direct.Standard;
+import org.apache.derbyTesting.system.oe.client.Operations;
+import org.apache.derbyTesting.system.oe.load.SimpleInsert;
+import org.apache.derbyTesting.system.oe.client.Load;
 
 /**
  * Test the basic functionality of the Order Entry test
@@ -40,10 +42,20 @@
  */
 public class OETest extends BaseJDBCTestCase {
 
+	short scale = 1;
+   	LoadTester tester;
+   	
     public OETest(String name) {
         super(name);
     }
     
+    public OETest(String name, short scale)
+    {
+    	super(name);
+    	this.scale=scale;
+ 
+    }
+    
     public static Test suite() {
         TestSuite suite = new TestSuite("Order Entry");
         
@@ -52,6 +64,20 @@
         suite.addTest(new OETest("testForeignKey"));
         suite.addTest(new OETest("testIndex"));
         
+        // Test load part and the cardinality after the
+        // population.
+        suite.addTest(new OETest("testInsertStmtLoad",(short)1));
+        suite.addTest(new OETest("testWarehouseRows"));
+        suite.addTest(new OETest("testStockRows"));
+        suite.addTest(new OETest("testItemRows"));
+        suite.addTest(new OETest("testCustomerRows"));
+        suite.addTest(new OETest("testDistrictRows"));
+        suite.addTest(new OETest("testOrdersRows"));
+        suite.addTest(new OETest("testNewOrdersRows"));
+        suite.addTest(new OETest("testOrderLineRows"));
+        suite.addTest(new OETest("testHistoryRows"));
+        
+        
         suite.addTest(new OETest("testStandardOperations"));
         
         return new CleanDatabaseTestSetup(suite);
@@ -87,6 +113,119 @@
     }
     
     /**
+     * Test the Simple Load 
+     */
+    public void testInsertStmtLoad() throws Exception
+    {
+       loadTest(new SimpleInsert(getConnection(),scale));
+    }
+    
+    /**
+     * Test load part. 
+     * Includes 
+     * 1) populating the tables
+     * 2) Check if the cardinality of all tables is per the 
+     * TPC-C requirement as expected.
+     * @param p  - Implementation of the Load to use for populating the database
+     * @throws Exception
+     */
+    public void loadTest(Load p) throws Exception
+    {
+    	LoadTester tester = new LoadTester(p);
+    	tester.test();
+    }
+    
+    /**
+     * Test cardinality of WAREHOUSE table
+     * 
+     * @throws Exception
+     */
+    public void testWarehouseRows() throws Exception
+    {
+    	getLoadTester().testWarehouseRows();
+    }
+
+    /**
+     * Test cardinality of CUSTOMER table
+     * 
+     * @throws Exception
+     */
+    public void testCustomerRows() throws Exception
+    {
+    	getLoadTester().testCustomerRows();
+    }
+
+    /**
+     * Test cardinality of DISTRICT table
+     * 
+     * @throws Exception
+     */
+    public void testDistrictRows() throws Exception
+    {
+    	getLoadTester().testDistrictRows();
+    }
+    
+    /**
+     * Test cardinality of HISTORY table
+     * 
+     * @throws Exception
+     */
+    public void testHistoryRows() throws Exception
+    {
+    	getLoadTester().testHistoryRows();
+    }
+
+    /**
+     * Test cardinality of ITEM table
+     * 
+     * @throws Exception
+     */
+    public void testItemRows() throws Exception
+    {
+    	getLoadTester().testItemRows();
+    }
+    
+    /**
+     * Test cardinality of NEWORDERS table
+     * 
+     * @throws Exception
+     */
+    public void testNewOrdersRows() throws Exception
+    {
+    	getLoadTester().testNewOrdersRows();
+    }
+    
+    /**
+     * Test cardinality of ORDERLINE table
+     * 
+     * @throws Exception
+     */
+    public void testOrderLineRows() throws Exception
+    {
+    	getLoadTester().testOrderLineRows();
+    }
+    
+    /**
+     * Test cardinality of STOCK table
+     * 
+     * @throws Exception
+     */
+    public void testStockRows() throws Exception
+    {
+    	getLoadTester().testStockRows();
+    }
+
+    /**
+     * Test cardinality of ORDERS table
+     * 
+     * @throws Exception
+     */
+    public void testOrdersRows() throws Exception
+    {
+    	getLoadTester().testOrdersRows();
+    }
+    
+    /**
      * Test the Standard implementations of the business transactions.
      */
     public void testStandardOperations() throws Exception
@@ -111,5 +250,20 @@
         String script = "org/apache/derbyTesting/system/oe/schema/" + name;
         int errorCount = runScript(script,"US-ASCII");
         assertEquals("Errors in script ",0, errorCount);
+    }
+    
+    /**
+     * 
+     * @return LoadTester to test the load part.
+     * @throws SQLException
+     */
+    private LoadTester getLoadTester()
+        throws SQLException
+    {
+    	if (tester != null)
+    		return tester;
+    	
+    	tester = new LoadTester(new SimpleInsert(getConnection(),(short)1));
+    	return tester;
     }
 }

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java?view=auto&rev=497297
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java Wed Jan 17 20:28:32 2007
@@ -0,0 +1,441 @@
+/*
+ *
+ * Derby - Class OERandom
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, 
+ * software distributed under the License is distributed on an 
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
+ * either express or implied. See the License for the specific 
+ * language governing permissions and limitations under the License.
+ */
+package org.apache.derbyTesting.system.oe.util;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Random;
+
+import org.apache.derbyTesting.system.oe.client.Load;
+
+/**
+ * Methods to implement the random database population types
+ * for the Order Entry Benchmark. The rules for generating 
+ * the random data is per the TPC-C specification.
+ */
+public class OERandom {
+
+    final Random rand;
+
+    protected final int Clast;
+
+    protected final int Cid;
+
+    protected final int Citem;
+
+    public OERandom(int last, int id, int item, long seed) {
+
+        Clast = last;
+        Cid = id;
+        Citem = item;
+        rand = new Random(seed);
+        initAStrings();
+    }
+
+    public OERandom(int last, int id, int item) {
+        this(last, id, item, System.currentTimeMillis());
+    }
+
+    private static int[] RESCALE = { 0, 10, 100, 1000, 10000, 100000, 1000000 };
+
+    private StringBuffer decimalString = new StringBuffer(12);
+
+    public String randomDecimalString(int start, int end, int scale) {
+
+        int val = randomInt(start, end);
+
+        int whole = val / RESCALE[scale];
+
+        int part = val % RESCALE[scale];
+
+        decimalString.setLength(0);
+        decimalString.append(whole);
+        decimalString.append('.');
+
+        int pos = decimalString.length();
+
+        decimalString.append(part);
+
+        int tempScale = decimalString.length() - pos;
+        if (tempScale < scale) {
+            for (int i = 0; i < (scale - tempScale); i++)
+                decimalString.insert(pos, '0');
+        }
+
+        return decimalString.toString();
+    }
+
+    public BigDecimal randomDecimal(int start, int end, int scale) {
+        BigInteger bi = BigInteger.valueOf(randomInt(start, end));
+        return new BigDecimal(bi, scale);
+    }
+
+    /**
+     * tpcc 4.3.2.5 Implements random within [x .. y ] for int
+     */
+    public int randomInt(int start, int end) {
+        double drand = rand.nextDouble();
+
+        double rrand = (drand * (end - start)) + 0.5;
+
+        return ((int) rrand) + start;
+    }
+
+    /**
+     * tpcc 4.3.2.2 (random a string)
+     */
+    public String randomAString(int min, int max) {
+        int len = randomInt(min, max);
+        char[] c = new char[len];
+        for (int i = 0; i < len; i++) {
+
+            double drand = rand.nextDouble();
+
+            if (i == 0) {
+                if (drand < 2.0)
+                    c[0] = (char) randomInt((int) 'A', (int) 'Z');
+                else {
+                    switch (randomInt(1, 10)) {
+                    case 1:
+                        c[0] = '\u00c0';
+                        break;
+                    case 2:
+                        c[0] = '\u00c1';
+                        break;
+                    case 3:
+                        c[0] = '\u00c2';
+                        break;
+                    case 4:
+                        c[0] = '\u00ca';
+                        break;
+                    case 5:
+                        c[0] = '\u00cb';
+                        break;
+                    case 6:
+                        c[0] = '\u00d4';
+                        break;
+                    case 7:
+                        c[0] = '\u00d8';
+                        break;
+                    case 8:
+                        c[0] = '\u00d1';
+                        break;
+                    case 9:
+                        c[0] = '\u00cd';
+                        break;
+                    default:
+                        c[0] = '\u00dc';
+                        break;
+                    }
+                }
+
+                continue;
+            }
+
+            if (drand < 2.0)
+                c[i] = (char) randomInt((int) 'a', (int) 'z');
+            else {
+                switch (randomInt(1, 10)) {
+                case 1:
+                    c[i] = '\u00e2';
+                    break;
+                case 2:
+                    c[i] = '\u00e4';
+                    break;
+                case 3:
+                    c[i] = '\u00e7';
+                    break;
+                case 4:
+                    c[i] = '\u00e8';
+                    break;
+                case 5:
+                    c[i] = '\u00ec';
+                    break;
+                case 6:
+                    c[i] = '\u00ef';
+                    break;
+                case 7:
+                    c[i] = '\u00f6';
+                    break;
+                case 8:
+                    c[i] = '\u00f9';
+                    break;
+                case 9:
+                    c[i] = '\u00fc';
+                    break;
+                default:
+                    c[i] = '\u00e5';
+                    break;
+                }
+            }
+        }
+
+        return new String(c);
+    }
+
+    /**
+     * tpcc 4.3.2.2 (random n string)
+     */
+    public String randomNString(int min, int max) {
+        int len = randomInt(min, max);
+        char[] c = new char[len];
+        for (int i = 0; i < len; i++) {
+            c[i] = (char) randomInt((int) '0', (int) '9');
+        }
+
+        return new String(c);
+    }
+
+    /**
+     * tpcc 4.3.2.3
+     */
+    private final String[] SYLLABLES = { "BAR", "OUGHT", "ABLE", "PRI", "PRES",
+            "ESE", "ANTI", "CALLY", "ATION", "EING" };
+
+    protected String randomCLast(int n) {
+
+        return SYLLABLES[n / 100] + SYLLABLES[(n / 10) % 10]
+                + SYLLABLES[n % 10];
+    }
+
+    /**
+     * Generate the zipcode value
+     * return zipcode value according to the requirements specified in 
+     * Clause 4.3.2.7 of TPC-C spec
+     */
+    public String randomZIP() {
+        return randomNString(4, 4) + "11111";
+    }
+
+    /**
+     * Section 2.1.6 of TPC-C specification, for OL_I_ID NURand(A, x, y) =
+     * (((random(0, A) | random(x, y)) + C) % (y - x + 1)) + x C is a run-time
+     * constant randomly chosen within [0 .. A] NURand(8191, 1,100000)
+     * 
+     * @return nonuniform random number
+     */
+    public int NURand8191() {
+        int l = randomInt(0, 8191);
+        int r = randomInt(1, Load.ITEM_COUNT);
+        int C = randomInt(0, 8191);
+        return ((l | r) + C) % (Load.ITEM_COUNT - 1 + 1) + 1;
+    }
+
+    /**
+     * Section 2.1.6 of TPC-C specification for CID NURand(A, x, y) =
+     * (((random(0, A) | random(x, y)) + C) % (y - x + 1)) + x NURand(1023,
+     * 1,3000)
+     * 
+     * @return nonuniform random number
+     */
+    public int NURand1023() {
+        int l = randomInt(0, 1023);
+        int r = randomInt(1, (Load.CUSTOMER_COUNT_W / Load.DISTRICT_COUNT_W));
+        int C = randomInt(0, 1023);
+        return ((l | r) + C)
+                % ((Load.CUSTOMER_COUNT_W / Load.DISTRICT_COUNT_W) - 1 + 1) + 1;
+    }
+
+    /**
+     * Section 2.1.6 of TPC-C specification, for C_LAST NURand(A, x, y) =
+     * (((random(0, A) | random(x, y)) + C) % (y - x + 1)) + x NURand(255,0,999)
+     * 
+     * @return nonuniform random number
+     */
+    public int NURand255() {
+        int l = randomInt(0, 255);
+        int r = randomInt(0, 999);
+        int C = randomInt(0, 255);
+        return ((l | r) + C) % (999 - 0 + 1) + 0;
+    }
+
+    public String randomState() {
+        StringBuffer s = new StringBuffer(2);
+        for (int i = 0; i < 2; i++) {
+            s.append((char) randomInt((int) 'A', (int) 'Z'));
+        }
+
+        return s.toString();
+    }
+
+    /**
+     * Clause 4.3.2.3 of the TPC-C specification
+     * @param cid - customer id.
+     * @return the generated Customer's last name per the requirements
+     * in the TPC-C spec. 
+     */
+    public String randomCLastPopulate(int cid) {
+        if (cid < 1000)
+            return randomCLast(cid); // range 0 - 999
+
+        return randomCLast(NURand255());
+    }
+
+    public String randomCLast() {
+        return randomCLast(NURand255());
+    }
+
+    /**
+     * Clause 4.3.3.1 of TPC-C spec. random a-string [26 .. 50]. For 10%
+     * of the rows, selected at random, the string "ORIGINAL" must be held by 8
+     * consecutive characters starting at a random position within the string
+     * 
+     * @return string data per the TPC-C requirements
+     */
+    public String randomData() {
+        String s = randomAString26_50();
+        if (rand.nextDouble() < 0.9)
+            return s;
+
+        int pos = randomInt(0, s.length() - 9);
+
+        if (pos == 0)
+            return "ORIGINAL" + s.substring(8);
+
+        if (pos == (s.length() - 9))
+            return s.substring(0, s.length() - 9) + "ORIGINAL";
+
+        return s.substring(0, pos) + "ORIGINAL"
+                + s.substring(pos + 8, s.length());
+    }
+
+    public int[] randomIntPerm(int count) {
+        int[] data = new int[count];
+
+        for (int i = 0; i < count; i++) {
+            data[i] = i + 1;
+        }
+
+        for (int j = 0; j < (count * 4); j++) {
+
+            int a = randomInt(0, count - 1);
+            int b = randomInt(0, count - 1);
+
+            int val = data[a];
+            data[a] = data[b];
+            data[b] = val;
+        }
+        return data;
+    }
+
+    private final static String[] left24 = new String[10];
+
+    private final static String[] left300 = new String[10];
+
+    private final static String[] right200 = new String[10];
+
+    private final static String[] left10 = new String[10];
+
+    private final static String[] right10 = new String[10];
+
+    private final static String[] left14 = new String[10];
+
+    private final static String[] left26 = new String[10];
+
+    private final static String[] right24 = new String[10];
+
+    private final static String[] left8 = new String[10];
+
+    private final static String[] right8 = new String[10];
+
+    private static boolean doneInit;
+
+    private void initAStrings() {
+
+        synchronized (left24) {
+            if (doneInit)
+                return;
+
+            for (int i = 0; i < 10; i++) {
+                // 24..24
+                left24[i] = randomAString(24, 24);
+
+                // 300...500
+                left300[i] = randomAString(300, 300);
+                right200[i] = randomAString(0, 200);
+
+                // 10...20
+                left10[i] = randomAString(10, 10);
+                right10[i] = randomAString(0, 10);
+
+                // 14 .. 24
+                left14[i] = randomAString(10, 10);
+
+                // 26 .. 50
+                left26[i] = randomAString(26, 26);
+                right24[i] = randomAString(0, 24);
+
+                // 8 .. 16
+                left8[i] = randomAString(8, 8);
+                right8[i] = randomAString(0, 8);
+
+            }
+            doneInit = true;
+        }
+    }
+
+    public String randomAString24() {
+        return left24[randomInt(0, 9)];
+    }
+
+    /**
+     * Section 4.3.2.2(and comments 1 and 2).
+     * The notation random a-string [x .. y] (respectively,
+     * n-string [x ..y]) represents a string of random alphanumeric (respectively, 
+     * numeric)characters of a random length of minimum x, maximum y, and mean (y+x)/2.
+     * 
+     * @return string value.
+     */
+    public String randomAString300_500() {
+        String l = left300[randomInt(0, 9)];
+        String r = right200[randomInt(0, 9)];
+
+        return l.concat(r);
+    }
+
+    public String randomAString10_20() {
+        String l = left10[randomInt(0, 9)];
+        String r = right10[randomInt(0, 9)];
+
+        return l.concat(r);
+    }
+
+    public String randomAString14_24() {
+        String l = left14[randomInt(0, 9)];
+        String r = right10[randomInt(0, 9)];
+
+        return l.concat(r);
+    }
+
+    public String randomAString26_50() {
+        String l = left26[randomInt(0, 9)];
+        String r = right24[randomInt(0, 9)];
+
+        return l.concat(r);
+    }
+
+    public String randomAString8_16() {
+        String l = left8[randomInt(0, 9)];
+        String r = right8[randomInt(0, 9)];
+
+        return l.concat(r);
+    }
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/system/oe/util/OERandom.java
------------------------------------------------------------------------------
    svn:eol-style = native