public void populateHistory(Database dbp) {
    Histrec hrec = new Histrec();
    hrec.set_amount(10);

    byte[] arr = new byte[4]; // sizeof(int)
    int i;
    DatabaseEntry kdbt = new DatabaseEntry(arr);
    kdbt.setSize(arr.length);
    DatabaseEntry ddbt = new DatabaseEntry(hrec.data);
    ddbt.setSize(hrec.data.length);

    try {
      for (i = 1; i <= history; i++) {
        kdbt.setRecordNumber(i);

        hrec.set_aid(random_id(ACCOUNT));
        hrec.set_bid(random_id(BRANCH));
        hrec.set_tid(random_id(TELLER));

        dbp.append(null, kdbt, ddbt);
      }
    } catch (DatabaseException dbe) {
      errExit(dbe, "Failure initializing history file");
    }
  }
  public void run(int ntxns, int threads) {
    double gtps;
    int txns, failed;
    long curtime, starttime;
    TxnThread[] txnList = new TxnThread[threads];
    for (int i = 0; i < threads; i++)
      txnList[i] = new TxnThread("Thread " + String.valueOf(i), ntxns);

    starttime = (new Date()).getTime();
    for (int i = 0; i < threads; i++) txnList[i].start();
    for (int i = 0; i < threads; i++)
      try {
        txnList[i].join();
      } catch (Exception e1) {
        errExit(e1, "join failed");
      }

    curtime = (new Date()).getTime();
    txns = failed = 0;
    for (int i = 0; i < threads; i++) {
      txns += txnList[i].txns;
      failed += txnList[i].failed;
    }
    gtps = (double) (txns - failed) / ((curtime - starttime) / 1000.0);
    System.out.print(
        "\nTotal: " + String.valueOf(txns) + " txns " + String.valueOf(failed) + " failed ");
    System.out.println(showRounded(gtps, 2) + " TPS");
  }
    public void run() {
      double gtps, itps;
      int n, ret;
      long start_time, end_time;

      //
      // Open the database files.
      //
      int err;
      try {
        DatabaseConfig config = new DatabaseConfig();
        config.setTransactional(true);
        adb = dbenv.openDatabase(null, "account", null, config);
        bdb = dbenv.openDatabase(null, "branch", null, config);
        tdb = dbenv.openDatabase(null, "teller", null, config);
        hdb = dbenv.openDatabase(null, "history", null, config);
      } catch (DatabaseException dbe) {
        TpcbExample.errExit(dbe, "Open of db files failed");
      } catch (FileNotFoundException fnfe) {
        TpcbExample.errExit(fnfe, "Open of db files failed, missing file");
      }

      start_time = (new Date()).getTime();
      for (txns = n = ntxns, failed = 0; n-- > 0; ) if ((ret = txn()) != 0) failed++;
      end_time = (new Date()).getTime();
      if (end_time == start_time) end_time++;

      System.out.println(
          getName()
              + ": "
              + (long) txns
              + " txns: "
              + failed
              + " failed, "
              + TpcbExample.showRounded((txns - failed) / (double) (end_time - start_time), 2)
              + " TPS");

      try {
        adb.close();
        bdb.close();
        tdb.close();
        hdb.close();
      } catch (DatabaseException dbe2) {
        TpcbExample.errExit(dbe2, "Close of db files failed");
      }
    }
  public static void main(String[] argv) throws java.io.IOException {
    File home = new File("TESTDIR");
    int accounts = ACCOUNTS;
    int branches = BRANCHES;
    int tellers = TELLERS;
    int history = HISTORY;
    int threads = 1;
    int mpool = 0;
    int ntxns = 0;
    boolean iflag = false;
    boolean txn_no_sync = false;
    long seed = (new GregorianCalendar()).get(Calendar.SECOND);

    for (int i = 0; i < argv.length; ++i) {
      if (argv[i].equals("-a")) {
        // Number of account records
        if ((accounts = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-b")) {
        // Number of branch records
        if ((branches = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-c")) {
        // Cachesize in bytes
        if ((mpool = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-f")) {
        // Fast mode: no txn sync.
        txn_no_sync = true;
      } else if (argv[i].equals("-h")) {
        // DB  home.
        home = new File(argv[++i]);
      } else if (argv[i].equals("-i")) {
        // Initialize the test.
        iflag = true;
      } else if (argv[i].equals("-n")) {
        // Number of transactions
        if ((ntxns = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-S")) {
        // Random number seed.
        seed = Long.parseLong(argv[++i]);
        if (seed <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-s")) {
        // Number of history records
        if ((history = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-T")) {
        // Number of threads
        if ((threads = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-t")) {
        // Number of teller records
        if ((tellers = Integer.parseInt(argv[++i])) <= 0) invarg(argv[i]);
      } else if (argv[i].equals("-v")) {
        // Verbose option.
        verbose = true;
      } else {
        usage();
      }
    }

    rand.setSeed((int) seed);

    // Initialize the database environment.
    // Must be done in within a try block.
    //
    TpcbExample app = null;
    try {
      app =
          new TpcbExample(home, accounts, branches, tellers, history, mpool, iflag || txn_no_sync);
    } catch (Exception e1) {
      errExit(e1, "initializing environment failed");
    }

    if (verbose)
      System.out.println(
          (long) accounts
              + " Accounts, "
              + String.valueOf(branches)
              + " Branches, "
              + String.valueOf(tellers)
              + " Tellers, "
              + String.valueOf(history)
              + " History");

    if (iflag) {
      if (ntxns != 0) usage();
      app.populate();
    } else {
      if (ntxns == 0) usage();
      app.run(ntxns, threads);
    }

    // Shut down the application.

    try {
      app.close();
    } catch (DatabaseException dbe2) {
      errExit(dbe2, "appexit failed");
    }

    System.exit(0);
  }
  //
  // Initialize the database to the number of accounts, branches,
  // history records, and tellers given to the constructor.
  //
  public void populate() {
    Database dbp = null;

    int err;
    int balance, idnum;
    int end_anum, end_bnum, end_tnum;
    int start_anum, start_bnum, start_tnum;
    int h_nelem;

    idnum = BEGID;
    balance = 500000;

    h_nelem = accounts;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "account", null, config);
    } catch (Exception e1) {
      // can be DatabaseException or FileNotFoundException
      errExit(e1, "Open of account file failed");
    }

    start_anum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "account");
    idnum += h_nelem;
    end_anum = idnum - 1;
    try {
      dbp.close();
    } catch (DatabaseException e2) {
      errExit(e2, "Account file close failed");
    }

    if (verbose)
      System.out.println(
          "Populated accounts: " + String.valueOf(start_anum) + " - " + String.valueOf(end_anum));

    //
    // Since the number of branches is very small, we want to use very
    // small pages and only 1 key per page.  This is the poor-man's way
    // of getting key locking instead of page locking.
    //
    h_nelem = (int) branches;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(1);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "branch", null, config);
    } catch (Exception e3) {
      // can be DatabaseException or FileNotFoundException
      errExit(e3, "Branch file create failed");
    }

    start_bnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "branch");
    idnum += h_nelem;
    end_bnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException dbe4) {
      errExit(dbe4, "Close of branch file failed");
    }

    if (verbose)
      System.out.println(
          "Populated branches: " + String.valueOf(start_bnum) + " - " + String.valueOf(end_bnum));

    //
    // In the case of tellers, we also want small pages, but we'll let
    // the fill factor dynamically adjust itself.
    //
    h_nelem = (int) tellers;

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.HASH);
      config.setHashNumElements(h_nelem);
      config.setHashFillFactor(0);
      config.setPageSize(512);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "teller", null, config);
    } catch (Exception e5) {
      // can be DatabaseException or FileNotFoundException
      errExit(e5, "Teller file create failed");
    }

    start_tnum = idnum;
    populateTable(dbp, idnum, balance, h_nelem, "teller");
    idnum += h_nelem;
    end_tnum = idnum - 1;

    try {
      dbp.close();
    } catch (DatabaseException e6) {
      errExit(e6, "Close of teller file failed");
    }

    if (verbose)
      System.out.println(
          "Populated tellers: " + String.valueOf(start_tnum) + " - " + String.valueOf(end_tnum));

    try {
      DatabaseConfig config = new DatabaseConfig();
      config.setType(DatabaseType.RECNO);
      config.setRecordLength(HISTORY_LEN);
      config.setAllowCreate(true);
      dbp = dbenv.openDatabase(null, "history", null, config);
    } catch (Exception e7) {
      // can be DatabaseException or FileNotFoundException
      errExit(e7, "Create of history file failed");
    }

    populateHistory(dbp);

    try {
      dbp.close();
    } catch (DatabaseException e8) {
      errExit(e8, "Close of history file failed");
    }
  }