Package org.voltdb.benchmark.tpcc

Source Code of org.voltdb.benchmark.tpcc.TPCCClient$NewOrderCallback

/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.voltdb.benchmark.tpcc;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.voltdb.VoltProcedure;
import org.voltdb.VoltTable;
import org.voltdb.VoltType;
import org.voltdb.benchmark.BlockingClient;
import org.voltdb.benchmark.Clock;
import org.voltdb.benchmark.Verification;
import org.voltdb.benchmark.Verification.Expression;
import org.voltdb.benchmark.tpcc.procedures.ResetWarehouse;
import org.voltdb.benchmark.tpcc.procedures.delivery;
import org.voltdb.benchmark.tpcc.procedures.neworder;
import org.voltdb.benchmark.tpcc.procedures.ostatByCustomerId;
import org.voltdb.benchmark.tpcc.procedures.ostatByCustomerName;
import org.voltdb.benchmark.tpcc.procedures.paymentByCustomerId;
import org.voltdb.benchmark.tpcc.procedures.paymentByCustomerName;
import org.voltdb.benchmark.tpcc.procedures.slev;
import org.voltdb.client.Client;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.ProcedureCallback;
import org.voltdb.types.ExpressionType;
import org.voltdb.types.TimestampType;

import edu.brown.api.BenchmarkComponent;
import edu.brown.hstore.conf.HStoreConf;
import edu.brown.rand.RandomDistribution.FlatHistogram;
import edu.brown.statistics.ObjectHistogram;
import edu.brown.utils.StringUtil;

public class TPCCClient extends BenchmarkComponent implements TPCCSimulation.ProcCaller {
    private static final Logger LOG = Logger.getLogger(TPCCClient.class);
   
    final TPCCSimulation m_tpccSim;
    final ScaleParameters m_scaleParams;
    final TPCCConfig m_tpccConfig;
    FlatHistogram<Transaction> txnWeights;

    private final boolean crash_on_error = false;

    // type used by at least VoltDBClient and JDBCClient
    @SuppressWarnings("unchecked")
    public enum Transaction {
        STOCK_LEVEL(TPCCConstants.FREQUENCY_STOCK_LEVEL, slev.class),
        DELIVERY(TPCCConstants.FREQUENCY_DELIVERY, delivery.class),
        ORDER_STATUS(TPCCConstants.FREQUENCY_ORDER_STATUS, ostatByCustomerId.class, ostatByCustomerName.class),
        PAYMENT(TPCCConstants.FREQUENCY_PAYMENT, paymentByCustomerId.class, paymentByCustomerName.class),
        NEW_ORDER(TPCCConstants.FREQUENCY_NEW_ORDER, neworder.class),
        RESET_WAREHOUSE(0, ResetWarehouse.class);
   
        private Transaction(int weight, Class<? extends VoltProcedure>...procClasses) {
            this.displayName = StringUtil.title(this.name().replace("_", " ").toLowerCase());
            this.weight = weight;
            this.procClasses = procClasses;
        }
        public final String displayName;
        public final int weight;
        public final Class<? extends VoltProcedure> procClasses[];
    }
   
   
    private static class ForeignKeyConstraints implements Expression {
        private final String m_table;

        private static final Set<Short> m_warehouse = new HashSet<Short>();
        private static final Set<List<Number>> m_district = new HashSet<List<Number>>();
        private static final Set<List<Number>> m_customer = new HashSet<List<Number>>();
        private static final Set<List<Number>> m_orders = new HashSet<List<Number>>();
        private static final Set<List<Number>> m_stock = new HashSet<List<Number>>();
        private static final Set<Integer> m_item = new HashSet<Integer>();

        public ForeignKeyConstraints(String table) {
            m_table = table;
        }

        @Override
        public <T> Object evaluate(T tuple) {
            VoltTable row = (VoltTable) tuple;

            if (m_table.equalsIgnoreCase("warehouse")) {
                getKey(row, "W_ID", m_warehouse);
            } else if (m_table.equalsIgnoreCase("district")) {
                getKeys(row, new String[] {"D_W_ID", "D_ID"},
                        m_district);

                short d_w_id = (short) row.getLong("D_W_ID");
                return m_warehouse.contains(d_w_id);
            } else if (m_table.equalsIgnoreCase("customer")) {
                getKeys(row, new String[] {"C_W_ID", "C_D_ID", "C_ID"},
                        m_customer);

                short c_w_id = (short) row.getLong("C_W_ID");
                byte c_d_id = (byte) row.getLong("C_D_ID");
                List<Number> key = new ArrayList<Number>(2);
                key.add(c_w_id);
                key.add(c_d_id);
                return m_district.contains(key);
            } else if (m_table.equalsIgnoreCase("history")) {
                short h_w_id = (short) row.getLong("H_W_ID");
                byte h_d_id = (byte) row.getLong("H_D_ID");
                if (row.wasNull()) {
                    System.err.println("row was null 1");
                    return false;
                }
                List<Number> districtKey = new ArrayList<Number>(2);
                districtKey.add(h_w_id);
                districtKey.add(h_d_id);

                short h_c_w_id = (short) row.getLong("H_C_W_ID");
                if (row.wasNull()) {
                    System.err.println("row was null 2");
                    return false;
                }
                byte h_c_d_id = (byte) row.getLong("H_C_D_ID");
                if (row.wasNull()) {
                    System.err.println("row was null 3");
                    return false;
                }
                int h_c_id = (int) row.getLong("H_C_ID");
                if (row.wasNull()) {
                    System.err.println("row was null 4");
                    return false;
                }
                List<Number> customerKey = new ArrayList<Number>(3);
                customerKey.add(h_c_w_id);
                customerKey.add(h_c_d_id);
                customerKey.add(h_c_id);
                return (m_district.contains(districtKey)
                        && m_customer.contains(customerKey));
            } else if (m_table.equalsIgnoreCase("new_order")) {
                short no_w_id = (short) row.getLong("NO_W_ID");
                byte no_d_id = (byte) row.getLong("NO_D_ID");
                int no_o_id = (int) row.getLong("NO_O_ID");
                List<Number> key = new ArrayList<Number>(3);
                key.add(no_w_id);
                key.add(no_d_id);
                key.add(no_o_id);
                return m_orders.contains(key);
            } else if (m_table.equalsIgnoreCase("orders")) {
                getKeys(row, new String[] {"O_W_ID", "O_D_ID", "O_ID"},
                        m_orders);

                short o_w_id = (short) row.getLong("O_W_ID");
                byte o_d_id = (byte) row.getLong("O_D_ID");
                int o_c_id = (int) row.getLong("O_C_ID");
                if (row.wasNull())
                    return false;
                List<Number> key = new ArrayList<Number>(3);
                key.add(o_w_id);
                key.add(o_d_id);
                key.add(o_c_id);
                return m_customer.contains(key);
            } else if (m_table.equalsIgnoreCase("order_line")) {
                short ol_supply_w_id = (short) row.getLong("OL_SUPPLY_W_ID");
                if (row.wasNull())
                    return false;
                int ol_i_id = (int) row.getLong("OL_I_ID");
                if (row.wasNull())
                    return false;
                List<Number> stockKey = new ArrayList<Number>(2);
                stockKey.add(ol_supply_w_id);
                stockKey.add(ol_i_id);

                short ol_w_id = (short) row.getLong("OL_W_ID");
                byte ol_d_id = (byte) row.getLong("OL_D_ID");
                int ol_o_id = (int) row.getLong("OL_O_ID");
                List<Number> ordersKey = new ArrayList<Number>(3);
                ordersKey.add(ol_w_id);
                ordersKey.add(ol_d_id);
                ordersKey.add(ol_o_id);
                return (m_stock.contains(stockKey)
                        && m_orders.contains(ordersKey));
            } else if (m_table.equalsIgnoreCase("item")) {
                getKey(row, "I_ID", m_item);
            } else if (m_table.equalsIgnoreCase("stock")) {
                getKeys(row, new String[] {"S_W_ID", "S_I_ID"}, m_stock);

                short s_w_id = (short) row.getLong("S_W_ID");
                int s_i_id = (int) row.getLong("S_I_ID");
                return (m_warehouse.contains(s_w_id)
                        && m_item.contains(s_i_id));
            }

            return true;
        }

        @SuppressWarnings("unchecked")
        private static <T> void getKey(VoltTable tuple, String columnName,
                                       Set<T> keySet) {
            final int index = tuple.getColumnIndex(columnName);
            final VoltType type = tuple.getColumnType(index);
            keySet.add((T) tuple.get(index, type));
        }

        private static <T> void getKeys(VoltTable tuple, String[] columnNames,
                                        Set<List<Number>> keySet) {
            final List<Number> key = new ArrayList<Number>(columnNames.length);
            for (String name : columnNames) {
                final int index = tuple.getColumnIndex(name);
                final VoltType type = tuple.getColumnType(index);
                key.add((Number) tuple.get(index, type));
            }
            keySet.add(key);
        }

        @Override
        public <T> String toString(T tuple) {
            return ("foreight key check on " + m_table);
        }
    }

    /** Complies with our benchmark client remote controller scheme */
    public static void main(String args[]) {
        edu.brown.api.BenchmarkComponent.main(TPCCClient.class, args, false);
    }

    public TPCCClient(
            Client client,
            RandomGenerator generator,
            Clock clock,
            ScaleParameters params,
            TPCCConfig config)
    {
        super(client);
        m_scaleParams = params;
        m_tpccConfig = config;
        m_tpccSim = new TPCCSimulation(this, generator, clock, m_scaleParams, m_tpccConfig, 1.0, this.getCatalogContext());
//        m_tpccSim2 = new TPCCSimulation(this, generator, clock, m_scaleParams, m_tpccConfig, 1.0);
        this.initTransactionWeights();
    }

    /** Complies with our benchmark client remote controller scheme */
    public TPCCClient(String args[]) {
        super(args);

        m_tpccConfig = TPCCConfig.createConfig(this.getCatalogContext(), m_extraParams);
        if (LOG.isDebugEnabled()) LOG.debug("TPC-C Client Configuration:\n" + m_tpccConfig);

        // makeForRun requires the value cLast from the load generator in
        // order to produce a valid generator for the run. Thus the sort
        // of weird eat-your-own ctor pattern.
        RandomGenerator.NURandC base_loadC = new RandomGenerator.NURandC(0,0,0);
        RandomGenerator.NURandC base_runC = RandomGenerator.NURandC.makeForRun(
                new RandomGenerator.Implementation(0), base_loadC);
        RandomGenerator rng = new RandomGenerator.Implementation(0);
        rng.setC(base_runC);

        RandomGenerator.NURandC base_loadC2 = new RandomGenerator.NURandC(0,0,0);
        RandomGenerator.NURandC base_runC2 = RandomGenerator.NURandC.makeForRun(
                new RandomGenerator.Implementation(0), base_loadC2);
//        RandomGenerator rng2 = new RandomGenerator.Implementation(0);
        rng.setC(base_runC2);

        HStoreConf hstore_conf = this.getHStoreConf();
        m_scaleParams = ScaleParameters.makeWithScaleFactor(m_tpccConfig, hstore_conf.client.scalefactor);
        m_tpccSim = new TPCCSimulation(this, rng, new Clock.RealTime(), m_scaleParams, m_tpccConfig, hstore_conf.client.skewfactor, this.getCatalogContext());
//        m_tpccSim2 = new TPCCSimulation(this, rng2, new Clock.RealTime(), m_scaleParams, m_tpccConfig, hstore_conf.client.skewfactor);

        // Set up checking
        buildConstraints();
       
        // Initialize the sampling table
        this.initTransactionWeights();
       
        // Disable all distributed transaction requests for this client thread
        if (this.isSinglePartitionOnly()) m_tpccConfig.disableDistributedTransactions();
       
        //m_sampler = new VoltSampler(20, "tpcc-cliet-sampling");
    }
   
    /**
     * Initialize the sampling table
     */
    private void initTransactionWeights() {
        ObjectHistogram<Transaction> txns = new ObjectHistogram<Transaction>(true);
        for (Transaction t : Transaction.values()) {
            Integer weight = null;
           
            // HACK: Because there are multiple stored procedures for payment and order_status,
            // we will try to match on their weights on either the class names or enum names
            for (Class<? extends VoltProcedure> procClass : t.procClasses) {
                weight = this.getTransactionWeight(procClass.getSimpleName());
                if (weight != null) break;
            } // FOR
            if (weight == null) weight = this.getTransactionWeight(t.name());
            if (weight == null) weight = t.weight;
            if (weight > 0) txns.put(t, weight);
        } // FOR
        assert(txns.getSampleCount() == 100) : txns;
        this.txnWeights = new FlatHistogram<Transaction>(m_tpccSim.rng(), txns);
        if (LOG.isDebugEnabled()) LOG.debug("Transaction Weights:\n" + txns);
    }

    protected TPCCConfig getTPCCConfig() {
        return (m_tpccConfig);
    }
    protected ScaleParameters getScaleParameters() {
        return (m_scaleParams);
    }
    protected TPCCSimulation getTPCCSimulation() {
        return (m_tpccSim);
    }
   
    @Override
    protected boolean useHeavyweightClient() {
        return true;
    }

    protected void buildConstraints() {
        Expression constraint = null;

        // WAREHOUSE table
        Expression w_id = Verification.inRange("W_ID", (short) m_scaleParams.starting_warehouse,
                                               (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression w_tax = Verification.inRange("W_TAX", TPCCConstants.MIN_TAX,
                                                TPCCConstants.MAX_TAX);
        Expression w_fk = new ForeignKeyConstraints("WAREHOUSE");
        Expression warehouse = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                        w_id, w_tax, w_fk);

        // DISTRICT table
        Expression d_id = Verification.inRange("D_ID", (byte) 1,
                                               (byte) m_scaleParams.districtsPerWarehouse);
        Expression d_w_id = Verification.inRange("D_W_ID", (short) m_scaleParams.starting_warehouse,
                                                 (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression d_next_o_id = Verification.inRange("D_NEXT_O_ID", 1, 10000000);
        Expression d_tax = Verification.inRange("D_TAX", TPCCConstants.MIN_TAX,
                                                TPCCConstants.MAX_TAX);
        Expression d_fk = new ForeignKeyConstraints("DISTRICT");
        Expression district = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                       d_id, d_w_id, d_next_o_id, d_tax,
                                                       d_fk);

        // CUSTOMER table
        Expression c_id = Verification.inRange("C_ID", 1,
                                               m_scaleParams.customersPerDistrict);
        Expression c_d_id = Verification.inRange("C_D_ID", (byte) 1,
                                                 (byte) m_scaleParams.districtsPerWarehouse);
        Expression c_w_id = Verification.inRange("C_W_ID", (short) m_scaleParams.starting_warehouse,
                                                 (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression c_discount = Verification.inRange("C_DISCOUNT", TPCCConstants.MIN_DISCOUNT,
                                                     TPCCConstants.MAX_DISCOUNT);
        Expression c_credit =
            Verification.conjunction(ExpressionType.CONJUNCTION_OR,
                                     Verification.compareWithConstant(ExpressionType.COMPARE_EQUAL,
                                                                      "C_CREDIT",
                                                                      TPCCConstants.GOOD_CREDIT),
                                     Verification.compareWithConstant(ExpressionType.COMPARE_EQUAL,
                                                                      "C_CREDIT",
                                                                      TPCCConstants.BAD_CREDIT));
        Expression c_fk = new ForeignKeyConstraints("CUSTOMER");
        Expression customer = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                       c_id, c_d_id, c_w_id, c_discount, c_credit,
                                                       c_fk);

        // HISTORY table
        Expression h_c_id = Verification.inRange("H_C_ID", 1,
                                                 m_scaleParams.customersPerDistrict);
        Expression h_c_d_id = Verification.inRange("H_C_D_ID", (byte) 1,
                                                   (byte) m_scaleParams.districtsPerWarehouse);
        Expression h_c_w_id = Verification.inRange("H_C_W_ID", (short) m_scaleParams.starting_warehouse,
                                                   (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression h_d_id = Verification.inRange("H_D_ID", (byte) 1,
                                                 (byte) m_scaleParams.districtsPerWarehouse);
        Expression h_w_id = Verification.inRange("H_W_ID", (short) m_scaleParams.starting_warehouse,
                                                 (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression h_fk = new ForeignKeyConstraints("HISTORY");
        Expression history = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                      h_c_id, h_c_d_id, h_c_w_id, h_d_id, h_w_id,
                                                      h_fk);

        // NEW_ORDER table
        Expression no_o_id = Verification.inRange("NO_O_ID", 1, 10000000);
        Expression no_d_id = Verification.inRange("NO_D_ID", (byte) 1,
                                                  (byte) m_scaleParams.districtsPerWarehouse);
        Expression no_w_id = Verification.inRange("NO_W_ID", (short) m_scaleParams.starting_warehouse,
                                                  (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression no_fk = new ForeignKeyConstraints("NEW_ORDER");
        Expression new_order = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                        no_o_id, no_d_id, no_w_id, no_fk);

        // ORDERS table
        Expression o_id = Verification.inRange("O_ID", 1, 10000000);
        Expression o_c_id = Verification.inRange("O_C_ID", 1,
                                                 m_scaleParams.customersPerDistrict);
        Expression o_d_id = Verification.inRange("O_D_ID", (byte) 1,
                                                 (byte) m_scaleParams.districtsPerWarehouse);
        Expression o_w_id = Verification.inRange("O_W_ID", (short) m_scaleParams.starting_warehouse,
                                                 (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression o_carrier_id =
            Verification.conjunction(ExpressionType.CONJUNCTION_OR,
                                     Verification.compareWithConstant(ExpressionType.COMPARE_EQUAL,
                                                                      "O_CARRIER_ID",
                                                                      (int) TPCCConstants.NULL_CARRIER_ID),
                                     Verification.inRange("O_CARRIER_ID",
                                                          TPCCConstants.MIN_CARRIER_ID,
                                                          TPCCConstants.MAX_CARRIER_ID));
        Expression o_fk = new ForeignKeyConstraints("ORDERS");
        Expression orders = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                     o_id, o_c_id, o_d_id, o_w_id, o_carrier_id,
                                                     o_fk);

        // ORDER_LINE table
        Expression ol_o_id = Verification.inRange("OL_O_ID", 1, 10000000);
        Expression ol_d_id = Verification.inRange("OL_D_ID", (byte) 1,
                                                  (byte) m_scaleParams.districtsPerWarehouse);
        Expression ol_w_id = Verification.inRange("OL_W_ID", (short) m_scaleParams.starting_warehouse,
                                                  (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression ol_number = Verification.inRange("OL_NUMBER", 1,
                                                    TPCCConstants.MAX_OL_CNT);
        Expression ol_i_id = Verification.inRange("OL_I_ID", 1, m_scaleParams.num_items);
        Expression ol_supply_w_id = Verification.inRange("OL_SUPPLY_W_ID", (short) m_scaleParams.starting_warehouse,
                                                         (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression ol_quantity = Verification.inRange("OL_QUANTITY", 0,
                                                      TPCCConstants.MAX_OL_QUANTITY);
        Expression ol_amount = Verification.inRange("OL_AMOUNT",
                                                    0.0,
                                                    TPCCConstants.MAX_PRICE * TPCCConstants.MAX_OL_QUANTITY);
        Expression ol_fk = new ForeignKeyConstraints("ORDER_LINE");
        Expression order_line = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                         ol_o_id, ol_d_id, ol_w_id, ol_number,
                                                         ol_i_id, ol_supply_w_id, ol_quantity,
                                                         ol_amount, ol_fk);

        // ITEM table
        Expression i_id = Verification.inRange("I_ID", 1, m_scaleParams.num_items);
        Expression i_im_id = Verification.inRange("I_IM_ID", TPCCConstants.MIN_IM,
                                                  TPCCConstants.MAX_IM);
        Expression i_price = Verification.inRange("I_PRICE", TPCCConstants.MIN_PRICE,
                                                  TPCCConstants.MAX_PRICE);
        Expression i_fk = new ForeignKeyConstraints("ITEM");
        Expression item = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                   i_id, i_im_id, i_price, i_fk);

        // STOCK table
        Expression s_i_id = Verification.inRange("S_I_ID", 1, m_scaleParams.num_items);
        Expression s_w_id = Verification.inRange("S_W_ID", (short) m_scaleParams.starting_warehouse,
                                                 (short) (m_scaleParams.warehouses * 2) + m_scaleParams.starting_warehouse);
        Expression s_quantity = Verification.inRange("S_QUANTITY", TPCCConstants.MIN_QUANTITY,
                                                     TPCCConstants.MAX_QUANTITY);
        Expression s_fk = new ForeignKeyConstraints("STOCK");
        Expression stock = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                                    s_i_id, s_w_id, s_quantity, s_fk);

        // Delivery (no need to check 'd_id', it's systematically generated)
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              d_id, o_id);
        addConstraint(TPCCConstants.DELIVERY, 0, constraint);

        // New Order table 0
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              c_discount, c_credit);
        addConstraint(TPCCConstants.NEWORDER, 0, constraint);
        // New Order table 1
        constraint =
            Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                     d_next_o_id,
                                     w_tax, d_tax,
                                     Verification.compareWithConstant(ExpressionType.COMPARE_GREATERTHAN,
                                                                      "total", 0.0));
        addConstraint(TPCCConstants.NEWORDER, 1, constraint);
        // New Order table 2
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              s_quantity,
                                              i_price,
                                              ol_amount);
        addConstraint(TPCCConstants.NEWORDER, 2, constraint);

        // Order Status table 0
        addConstraint(TPCCConstants.ORDER_STATUS_BY_ID, 0, c_id);
        addConstraint(TPCCConstants.ORDER_STATUS_BY_NAME, 0, c_id);
        // Order Status table 1
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              o_id, o_carrier_id);
        addConstraint(TPCCConstants.ORDER_STATUS_BY_ID, 1, constraint);
        addConstraint(TPCCConstants.ORDER_STATUS_BY_NAME, 1, constraint);
        // Order Status table 2
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              ol_supply_w_id, ol_i_id,
                                              ol_quantity, ol_amount);
        addConstraint(TPCCConstants.ORDER_STATUS_BY_ID, 2, constraint);
        addConstraint(TPCCConstants.ORDER_STATUS_BY_NAME, 2, constraint);

        // Payment
        constraint = Verification.conjunction(ExpressionType.CONJUNCTION_AND,
                                              c_id, c_discount);
        addConstraint(TPCCConstants.PAYMENT_BY_ID, 2, constraint);
//        addConstraint(TPCCConstants.PAYMENT_BY_ID_C, 0, constraint);
        addConstraint(TPCCConstants.PAYMENT_BY_NAME, 2, constraint);
//        addConstraint(TPCCConstants.PAYMENT_BY_NAME_C, 0, constraint);

        // slev
        constraint = Verification.compareWithConstant(ExpressionType.COMPARE_GREATERTHANOREQUALTO,
                                                      "C1",
                                                      0L);
        addConstraint(TPCCConstants.STOCK_LEVEL, 0, constraint);

        // Full table checks (The order of adding them MATTERS!)
        addTableConstraint("WAREHOUSE", warehouse);
        addTableConstraint("DISTRICT", district);
        addTableConstraint("CUSTOMER", customer);
        addTableConstraint("HISTORY", history);
        addTableConstraint("ORDERS", orders);
        addTableConstraint("NEW_ORDER", new_order);
        addTableConstraint("ITEM", item);
        addTableConstraint("STOCK", stock);
        addTableConstraint("ORDER_LINE", order_line);
    }

    /**
     * Whether a message was queued when attempting the last invocation.
     */
    private boolean m_queuedMessage = false;

    /*
     * callXXX methods should spin on backpressure barrier until they successfully queue rather then
     * setting m_queuedMessage and returning immediately.
     */
    private boolean m_blockOnBackpressure = true;

    /**
     * Hint used when constructing the Client to control the size of buffers allocated for message
     * serialization
     * Set to 512 because neworder tops out around that size
     * @return
     */
    @Override
    protected int getExpectedOutgoingMessageSize() {
        return 256;
    }

    @Override
    public boolean runOnce() throws NoConnectionsException {
        m_blockOnBackpressure = false;
        // will send procedures to first connection w/o backpressure
        // if all connections have backpressure, will round robin across
        // busy servers (but the loop will spend more time running the
        // network below.)
        try {
            m_tpccSim.doOne(txnWeights.nextValue());
            return m_queuedMessage;
        } catch (IOException e) {
            throw (NoConnectionsException)e;
        }
    }
   
    @Override
    public void runLoop() throws NoConnectionsException {
        m_blockOnBackpressure = true;
//        if (Runtime.getRuntime().availableProcessors() > 4) {
//            new Thread() {
//                @Override
//                public void run() {
//                    try {
//                        while (true) {
//                            m_tpccSim2.doOne();
//                        }
//                    } catch (IOException e) {
//                    }
//                }
//            }.start();
//        }
        try {
            while (true) {
                // will send procedures to first connection w/o backpressure
                // if all connections have backpressure, will round robin across
                // busy servers (but the loop will spend more time running the
                // network below.)
                m_tpccSim.doOne(txnWeights.nextValue());
            }
        } catch (IOException e) {
            throw (NoConnectionsException)e;
        }
    }
   
   

    // Delivery
    class DeliveryCallback implements ProcedureCallback {
        @Override
        public void clientCallback(ClientResponse clientResponse) {
            if (crash_on_error) {
                boolean status = checkTransaction(TPCCConstants.DELIVERY, clientResponse, false, false);
                assert status;
                if (status && clientResponse.getResults()[0].getRowCount()
                        != m_scaleParams.districtsPerWarehouse) {
                        /* FIXME
                    System.err.println(
                            "Only delivered from "
                            + clientResponse.getResults()[0].getRowCount()
                            + " districts.");
                        */
                }
            }
            incrementTransactionCounter(clientResponse, TPCCClient.Transaction.DELIVERY.ordinal());
        }
    }

    @Override
    public void callDelivery(short w_id, int carrier, TimestampType date) throws IOException {
        if (m_blockOnBackpressure) {
            final DeliveryCallback cb = new DeliveryCallback();
            while (!this.getClientHandle().callProcedure(cb,
                TPCCConstants.DELIVERY, w_id, carrier, date)) {
                try {
                    this.getClientHandle().backpressureBarrier();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            m_queuedMessage = this.getClientHandle().callProcedure(new DeliveryCallback(),
                    TPCCConstants.DELIVERY, w_id, carrier, date);
        }
    }


    // NewOrder

    class NewOrderCallback implements ProcedureCallback {

        public NewOrderCallback(boolean rollback) {
            super();
            this.cbRollback = rollback;
        }

        @Override
        public void clientCallback(ClientResponse clientResponse) {
            if (LOG.isDebugEnabled()) LOG.debug("NewOrder clientResponse.getStatus() = " + clientResponse.getStatus());
           
            if (crash_on_error) {
                boolean status = checkTransaction(TPCCConstants.NEWORDER, clientResponse, cbRollback, false);
                assert (this.cbRollback || status) : "Rollback=" + this.cbRollback + ", Status=" + clientResponse.getStatus();
            }
            incrementTransactionCounter(clientResponse, TPCCClient.Transaction.NEW_ORDER.ordinal());
        }

        private boolean cbRollback;
    }

    int randomIndex = 0;
    @Override
    public void callNewOrder(boolean rollback, boolean noop, Object... paramlist) throws IOException {
        final String proc_name = (noop ? TPCCConstants.NOOP : TPCCConstants.NEWORDER);
        final NewOrderCallback cb = new NewOrderCallback(rollback);
       
        if (m_blockOnBackpressure) {
            while (!this.getClientHandle().callProcedure(cb, proc_name, paramlist)) {
                try {
                    this.getClientHandle().backpressureBarrier();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            m_queuedMessage = this.getClientHandle().callProcedure(cb, proc_name, paramlist);
        }
    }

    // Order status

    class VerifyBasicCallback implements ProcedureCallback {
        private final TPCCClient.Transaction m_transactionType;
        private final String m_procedureName;

        /**
         * A generic callback that does not credit a transaction. Some transactions
         * use two procedure calls - this counts as one transaction not two.
         */
        VerifyBasicCallback() {
            m_transactionType = null;
            m_procedureName = null;
        }

        /** A generic callback that credits for the transaction type passed. */
        VerifyBasicCallback(TPCCClient.Transaction transaction, String procName) {
            m_transactionType = transaction;
            m_procedureName = procName;
        }

        @Override
        public void clientCallback(ClientResponse clientResponse) {
            boolean abortExpected = false;
            if (m_procedureName != null && (m_procedureName.equals(TPCCConstants.ORDER_STATUS_BY_NAME)
                || m_procedureName.equals(TPCCConstants.ORDER_STATUS_BY_ID)))
                abortExpected = true;
            if (crash_on_error) {
                boolean status = checkTransaction(m_procedureName,
                                                  clientResponse,
                                                  abortExpected,
                                                  false);
                assert status;
            }
            if (m_transactionType != null) {
                incrementTransactionCounter(clientResponse, m_transactionType.ordinal());
            }
        }
    }

    @Override
    public void callOrderStatus(String proc, Object... paramlist) throws IOException {
        if (m_blockOnBackpressure) {
            final VerifyBasicCallback cb = new VerifyBasicCallback(TPCCClient.Transaction.ORDER_STATUS,
                    proc);
            while (!this.getClientHandle().callProcedure( cb,
                                                                             proc, paramlist)) {
                try {
                    this.getClientHandle().backpressureBarrier();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        } else {
            m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCClient.Transaction.ORDER_STATUS,
                                                                             proc),
                proc, paramlist);
        }
    }


    // Payment


    @Override
    public void callPaymentById(short w_id, byte d_id, double h_amount,
                                short c_w_id, byte c_d_id, int c_id, TimestampType now) throws IOException {
       
        m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCClient.Transaction.PAYMENT, TPCCConstants.PAYMENT_BY_ID),
                                                     TPCCConstants.PAYMENT_BY_ID,
                                                     w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now);
//       
//        if (m_blockOnBackpressure) {
//            if (m_scaleParams.warehouses > 1) {
//                final VerifyBasicCallback cb = new VerifyBasicCallback();
//                while (!this.getClientHandle().callProcedure(cb, Constants.PAYMENT_BY_ID_W,
//                                                   w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//                final VerifyBasicCallback cb2 = new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT, Constants.PAYMENT_BY_ID_C);
//                while (!this.getClientHandle().callProcedure(cb2, Constants.PAYMENT_BY_ID_C,
//                                                   w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//            } else {
//                final VerifyBasicCallback cb = new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT, Constants.PAYMENT_BY_ID);
//                while (!this.getClientHandle().callProcedure(cb, Constants.PAYMENT_BY_ID,
//                                                   w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        } else {
//            if (m_scaleParams.warehouses > 1) {
//                this.getClientHandle().callProcedure(new VerifyBasicCallback(), Constants.PAYMENT_BY_ID_W, w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now);
//                m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT, Constants.PAYMENT_BY_ID_C), Constants.PAYMENT_BY_ID_C,
//                                                                                     w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now);
//           } else {
//               m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT, Constants.PAYMENT_BY_ID), Constants.PAYMENT_BY_ID,
//                                                                                    w_id, d_id, h_amount, c_w_id, c_d_id, c_id, now);
//           }
//        }
    }

    @Override
    public void callPaymentByName(short w_id, byte d_id, double h_amount,
            short c_w_id, byte c_d_id, String c_last, TimestampType now) throws IOException {
       
        m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCClient.Transaction.PAYMENT, TPCCConstants.PAYMENT_BY_NAME),
                                                     TPCCConstants.PAYMENT_BY_NAME,
                                                     w_id, d_id, h_amount, c_w_id, c_d_id, c_last, now);

       
//        if (m_blockOnBackpressure) {
//            if ((m_scaleParams.warehouses > 1) || (c_last != null)) {
//                final VerifyBasicCallback cb = new VerifyBasicCallback();
//                while(!this.getClientHandle().callProcedure(cb,
//                        Constants.PAYMENT_BY_NAME_W, w_id, d_id, h_amount,
//                        c_w_id, c_d_id, c_last, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//                final VerifyBasicCallback cb2 = new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT,
//                        Constants.PAYMENT_BY_NAME_C);
//                while(!this.getClientHandle().callProcedure( cb2,
//                        Constants.PAYMENT_BY_NAME_C, w_id, d_id, h_amount,
//                        c_w_id, c_d_id, c_last, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//            else {
//                final VerifyBasicCallback cb = new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT,
//                        Constants.PAYMENT_BY_ID);
//                while(!this.getClientHandle().callProcedure( cb,
//                        Constants.PAYMENT_BY_ID, w_id,
//                        d_id, h_amount, c_w_id, c_d_id, c_last, now)) {
//                    try {
//                        this.getClientHandle().backpressureBarrier();
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//            }
//        } else {
//            if ((m_scaleParams.warehouses > 1) || (c_last != null)) {
//                this.getClientHandle().callProcedure(new VerifyBasicCallback(),
//                        Constants.PAYMENT_BY_NAME_W, w_id, d_id, h_amount,
//                        c_w_id, c_d_id, c_last, now);
//                m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT,
//                                                                                     Constants.PAYMENT_BY_NAME_C),
//                        Constants.PAYMENT_BY_NAME_C, w_id, d_id, h_amount,
//                        c_w_id, c_d_id, c_last, now);
//            }
//            else {
//                m_queuedMessage = this.getClientHandle().callProcedure(new VerifyBasicCallback(TPCCSimulation.Transaction.PAYMENT,
//                                                                                     Constants.PAYMENT_BY_ID),
//                        Constants.PAYMENT_BY_ID, w_id,
//                        d_id, h_amount, c_w_id, c_d_id, c_last, now);
//            }
//        }
    }


    // StockLevel
    class StockLevelCallback implements ProcedureCallback {
        @Override
        public void clientCallback(ClientResponse clientResponse) {
            if (crash_on_error) {
                boolean status = checkTransaction(TPCCConstants.STOCK_LEVEL,
                                                  clientResponse,
                                                  false,
                                                  false);
                assert status;
            }
            incrementTransactionCounter(clientResponse, TPCCClient.Transaction.STOCK_LEVEL.ordinal());
        }
      }

    @Override
    public void callStockLevel(short w_id, byte d_id, int threshold) throws IOException {
        final StockLevelCallback cb = new StockLevelCallback();
        while (!this.getClientHandle().callProcedure( cb, TPCCConstants.STOCK_LEVEL,
                w_id, d_id, threshold)) {
            try {
                this.getClientHandle().backpressureBarrier();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

    class DumpStatisticsCallback implements ProcedureCallback {
        @Override
        public void clientCallback(ClientResponse clientResponse) {
            if (checkTransaction(null, clientResponse, false, false))
                System.err.println(clientResponse.getResults()[0]);
        }
    }

    public void dumpStatistics() throws IOException {
        m_queuedMessage = this.getClientHandle().callProcedure(new DumpStatisticsCallback(),
                "@Statistics", "procedure");
    }

    class ResetWarehouseCallback implements ProcedureCallback {
        @Override
        public void clientCallback(ClientResponse clientResponse) {
            if (checkTransaction(null, clientResponse, false, false))
                incrementTransactionCounter(clientResponse, TPCCClient.Transaction.RESET_WAREHOUSE.ordinal());
        }
    }

    @Override
    public void callResetWarehouse(long w_id, long districtsPerWarehouse,
            long customersPerDistrict, long newOrdersPerDistrict)
    throws IOException {
        Client client = this.getClientHandle();
        // HACK
        if (client instanceof BlockingClient) {
            client = ((BlockingClient)client).getClient();
        }
        m_queuedMessage = client.callProcedure(new ResetWarehouseCallback(),
              TPCCConstants.RESET_WAREHOUSE, w_id, districtsPerWarehouse,
              customersPerDistrict, newOrdersPerDistrict);
    }

    @Override
    public void tickCallback(int counter) {
        m_tpccSim.tick(counter);
        LOG.debug("TICK: " + counter);
    }
   
    @Override
    public void clearCallback() {
        if (m_tpccConfig.reset_on_clear && this.getClientId() == 0) {
            LOG.info("Reseting WAREHOUSE data");
            for (int w_id = m_tpccConfig.first_warehouse; w_id < m_tpccConfig.num_warehouses; w_id++) {
                try {
                    this.callResetWarehouse(w_id,
                                            m_tpccSim.parameters.districtsPerWarehouse,
                                            m_tpccSim.parameters.customersPerDistrict,
                                            m_tpccSim.parameters.newOrdersPerDistrict);
                } catch (IOException ex) {
                    throw new RuntimeException("Failed to reset warehouse #" + w_id, ex);
                }
            } // FOR
        }
    }
   
    @Override
    public void stopCallback() {
        if (m_tpccConfig.neworder_skew_warehouse) {
            LOG.info("WAREHOUSE DISTRIBUTION:\n" + m_tpccSim.getWarehouseZipf().getHistory());
        }
    }
   
    @Override
    public String[] getTransactionDisplayNames() {
        String countDisplayNames[] = new String[TPCCClient.Transaction.values().length];
        for (int ii = 0; ii < TPCCClient.Transaction.values().length; ii++) {
            countDisplayNames[ii] = TPCCClient.Transaction.values()[ii].displayName;
        }
        return countDisplayNames;
    }
}
TOP

Related Classes of org.voltdb.benchmark.tpcc.TPCCClient$NewOrderCallback

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.