Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

TpcbExample.java

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 1997-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: TpcbExample.java,v 12.4 2005/09/22 03:53:49 mjc Exp $
00008  */
00009 
00010 package db;
00011 
00012 import com.sleepycat.db.*;
00013 
00014 import java.io.File;
00015 import java.io.FileNotFoundException;
00016 import java.math.BigDecimal;
00017 import java.util.Calendar;
00018 import java.util.Date;
00019 import java.util.Random;
00020 import java.util.GregorianCalendar;
00021 
00022 //
00023 // This program implements a basic TPC/B driver program.  To create the
00024 // TPC/B database, run with the -i (init) flag.  The number of records
00025 // with which to populate the account, history, branch, and teller tables
00026 // is specified by the a, s, b, and t flags respectively.  To run a TPC/B
00027 // test, use the n flag to indicate a number of transactions to run in
00028 // each thread and -T to specify the number of threads.
00029 //
00030 class TpcbExample {
00031     public static final int TELLERS_PER_BRANCH = 10;
00032     public static final int ACCOUNTS_PER_TELLER = 10000;
00033     public static final int HISTORY_PER_BRANCH = 2592000;
00034 
00035     //
00036     // The default configuration that adheres to TPCB scaling rules requires
00037     // nearly 3 GB of space.  To avoid requiring that much space for testing,
00038     // we set the parameters much lower.  If you want to run a valid 10 TPS
00039     // configuration, uncomment the VALID_SCALING configuration
00040     //
00041 
00042     // VALID_SCALING configuration
00043     /*
00044       public static final int ACCOUNTS = 1000000;
00045       public static final int BRANCHES = 10;
00046       public static final int TELLERS = 100;
00047       public static final int HISTORY = 25920000;
00048     */
00049 
00050     // TINY configuration
00051     /*
00052       public static final int ACCOUNTS = 1000;
00053       public static final int BRANCHES = 10;
00054       public static final int TELLERS = 100;
00055       public static final int HISTORY = 10000;
00056     */
00057 
00058     // Default configuration
00059     public static final int ACCOUNTS = 100000;
00060     public static final int BRANCHES = 10;
00061     public static final int TELLERS = 100;
00062     public static final int HISTORY = 259200;
00063 
00064     public static final int HISTORY_LEN = 100;
00065     public static final int RECLEN = 100;
00066     public static final int BEGID = 1000000;
00067 
00068     // used by random_id()
00069     public static final int ACCOUNT = 0;
00070     public static final int BRANCH = 1;
00071     public static final int TELLER = 2;
00072 
00073     public static boolean verbose = false;
00074     public static final String progname = "TpcbExample";    // Program name.
00075 
00076     Environment dbenv;
00077     int accounts, branches, tellers, history;
00078 
00079     public TpcbExample(File home,
00080                        int accounts, int branches, int tellers, int history,
00081                        int cachesize, boolean noSync)
00082         throws DatabaseException, FileNotFoundException {
00083 
00084         this.accounts = accounts;
00085         this.branches = branches;
00086         this.tellers = tellers;
00087         this.history = history;
00088 
00089         EnvironmentConfig config = new EnvironmentConfig();
00090         config.setErrorStream(System.err);
00091         config.setErrorPrefix(progname);
00092         config.setCacheSize(cachesize == 0 ? 4 * 1024 * 1024 : cachesize);
00093         config.setTxnNoSync(noSync);
00094         config.setLockDetectMode(LockDetectMode.DEFAULT);
00095         config.setAllowCreate(true);
00096 
00097         config.setInitializeCache(true);
00098         config.setTransactional(true);
00099         config.setInitializeLocking(true);
00100         config.setInitializeLogging(true);
00101 
00102         dbenv = new Environment(home, config);
00103     }
00104 
00105     public void close()
00106         throws DatabaseException {
00107 
00108         try {
00109             if (dbenv != null)
00110                 dbenv.close();
00111         } finally {
00112             dbenv = null;
00113         }
00114     }
00115 
00116     //
00117     // Initialize the database to the number of accounts, branches,
00118     // history records, and tellers given to the constructor.
00119     //
00120     public void populate() {
00121         Database dbp = null;
00122 
00123         int err;
00124         int balance, idnum;
00125         int end_anum, end_bnum, end_tnum;
00126         int start_anum, start_bnum, start_tnum;
00127         int h_nelem;
00128 
00129         idnum = BEGID;
00130         balance = 500000;
00131 
00132         h_nelem = accounts;
00133 
00134         try {
00135             DatabaseConfig config = new DatabaseConfig();
00136             config.setType(DatabaseType.HASH);
00137             config.setHashNumElements(h_nelem);
00138             config.setAllowCreate(true);
00139             dbp = dbenv.openDatabase(null, "account", null, config);
00140         } catch (Exception e1) {
00141             // can be DatabaseException or FileNotFoundException
00142             errExit(e1, "Open of account file failed");
00143         }
00144 
00145         start_anum = idnum;
00146         populateTable(dbp, idnum, balance, h_nelem, "account");
00147         idnum += h_nelem;
00148         end_anum = idnum - 1;
00149         try {
00150             dbp.close();
00151         } catch (DatabaseException e2) {
00152             errExit(e2, "Account file close failed");
00153         }
00154 
00155         if (verbose)
00156             System.out.println("Populated accounts: " +
00157                                String.valueOf(start_anum) + " - " +
00158                                String.valueOf(end_anum));
00159 
00160         //
00161         // Since the number of branches is very small, we want to use very
00162         // small pages and only 1 key per page.  This is the poor-man's way
00163         // of getting key locking instead of page locking.
00164         //
00165         h_nelem = (int)branches;
00166 
00167         try {
00168             DatabaseConfig config = new DatabaseConfig();
00169             config.setType(DatabaseType.HASH);
00170             config.setHashNumElements(h_nelem);
00171             config.setHashFillFactor(1);
00172             config.setPageSize(512);
00173             config.setAllowCreate(true);
00174             dbp = dbenv.openDatabase(null, "branch", null, config);
00175         } catch (Exception e3) {
00176             // can be DatabaseException or FileNotFoundException
00177             errExit(e3, "Branch file create failed");
00178         }
00179 
00180         start_bnum = idnum;
00181         populateTable(dbp, idnum, balance, h_nelem, "branch");
00182         idnum += h_nelem;
00183         end_bnum = idnum - 1;
00184 
00185         try {
00186             dbp.close();
00187         } catch (DatabaseException dbe4) {
00188             errExit(dbe4, "Close of branch file failed");
00189         }
00190 
00191         if (verbose)
00192             System.out.println("Populated branches: " +
00193                                String.valueOf(start_bnum) + " - " +
00194                                String.valueOf(end_bnum));
00195 
00196         //
00197         // In the case of tellers, we also want small pages, but we'll let
00198         // the fill factor dynamically adjust itself.
00199         //
00200         h_nelem = (int)tellers;
00201 
00202         try {
00203             DatabaseConfig config = new DatabaseConfig();
00204             config.setType(DatabaseType.HASH);
00205             config.setHashNumElements(h_nelem);
00206             config.setHashFillFactor(0);
00207             config.setPageSize(512);
00208             config.setAllowCreate(true);
00209             dbp = dbenv.openDatabase(null, "teller", null, config);
00210         } catch (Exception e5) {
00211             // can be DatabaseException or FileNotFoundException
00212             errExit(e5, "Teller file create failed");
00213         }
00214 
00215         start_tnum = idnum;
00216         populateTable(dbp, idnum, balance, h_nelem, "teller");
00217         idnum += h_nelem;
00218         end_tnum = idnum - 1;
00219 
00220         try {
00221             dbp.close();
00222         } catch (DatabaseException e6) {
00223             errExit(e6, "Close of teller file failed");
00224         }
00225 
00226         if (verbose)
00227             System.out.println("Populated tellers: " +
00228                                String.valueOf(start_tnum) + " - " +
00229                                String.valueOf(end_tnum));
00230 
00231         try {
00232             DatabaseConfig config = new DatabaseConfig();
00233             config.setType(DatabaseType.RECNO);
00234             config.setRecordLength(HISTORY_LEN);
00235             config.setAllowCreate(true);
00236             dbp = dbenv.openDatabase(null, "history", null, config);
00237         } catch (Exception e7) {
00238             // can be DatabaseException or FileNotFoundException
00239             errExit(e7, "Create of history file failed");
00240         }
00241 
00242         populateHistory(dbp);
00243 
00244         try {
00245             dbp.close();
00246         } catch (DatabaseException e8) {
00247             errExit(e8, "Close of history file failed");
00248         }
00249     }
00250 
00251     public void populateTable(Database dbp,
00252                               int start_id, int balance, int nrecs, String msg) {
00253         Defrec drec = new Defrec();
00254 
00255         DatabaseEntry kdbt = new DatabaseEntry(drec.data);
00256         kdbt.setSize(4);                  // sizeof(int)
00257         DatabaseEntry ddbt = new DatabaseEntry(drec.data);
00258         ddbt.setSize(drec.data.length);   // uses whole array
00259 
00260         try {
00261             for (int i = 0; i < nrecs; i++) {
00262                 kdbt.setRecordNumber(start_id + (int)i);
00263                 drec.set_balance(balance);
00264                 dbp.putNoOverwrite(null, kdbt, ddbt);
00265             }
00266         } catch (DatabaseException dbe) {
00267             System.err.println("Failure initializing " + msg + " file: " +
00268                                dbe.toString());
00269             System.exit(1);
00270         }
00271     }
00272 
00273     public void populateHistory(Database dbp) {
00274         Histrec hrec = new Histrec();
00275         hrec.set_amount(10);
00276 
00277         byte[] arr = new byte[4];                  // sizeof(int)
00278         int i;
00279         DatabaseEntry kdbt = new DatabaseEntry(arr);
00280         kdbt.setSize(arr.length);
00281         DatabaseEntry ddbt = new DatabaseEntry(hrec.data);
00282         ddbt.setSize(hrec.data.length);
00283 
00284         try {
00285             for (i = 1; i <= history; i++) {
00286                 kdbt.setRecordNumber(i);
00287 
00288                 hrec.set_aid(random_id(ACCOUNT));
00289                 hrec.set_bid(random_id(BRANCH));
00290                 hrec.set_tid(random_id(TELLER));
00291 
00292                 dbp.append(null, kdbt, ddbt);
00293             }
00294         } catch (DatabaseException dbe) {
00295             errExit(dbe, "Failure initializing history file");
00296         }
00297     }
00298 
00299     static Random rand = new Random();
00300     public static int random_int(int lo, int hi) {
00301         int t = rand.nextInt();
00302         if (t < 0)
00303             t = -t;
00304         int ret = (int)(((double)t / ((double)(Integer.MAX_VALUE) + 1)) *
00305             (hi - lo + 1));
00306         ret += lo;
00307         return (ret);
00308     }
00309 
00310     public int random_id(int type) {
00311         int min, max, num;
00312 
00313         max = min = BEGID;
00314         num = accounts;
00315         switch(type) {
00316         case TELLER:
00317             min += branches;
00318             num = tellers;
00319             // Fallthrough
00320         case BRANCH:
00321             if (type == BRANCH)
00322                 num = branches;
00323             min += accounts;
00324             // Fallthrough
00325         case ACCOUNT:
00326             max = min + num - 1;
00327         }
00328         return (random_int(min, max));
00329     }
00330 
00331     // The byte order is our choice.
00332     //
00333     static long get_int_in_array(byte[] array, int offset) {
00334         return
00335             ((0xff & array[offset + 0]) << 0)  |
00336             ((0xff & array[offset + 1]) << 8)  |
00337             ((0xff & array[offset + 2]) << 16) |
00338             ((0xff & array[offset + 3]) << 24);
00339     }
00340 
00341     // Note: Value needs to be long to avoid sign extension
00342     static void set_int_in_array(byte[] array, int offset, long value) {
00343         array[offset + 0] = (byte)((value >> 0) & 0xff);
00344         array[offset + 1] = (byte)((value >> 8) & 0xff);
00345         array[offset + 2] = (byte)((value >> 16) & 0xff);
00346         array[offset + 3] = (byte)((value >> 24) & 0xff);
00347     }
00348 
00349     // round 'd' to 'scale' digits, and return result as string
00350     static String showRounded(double d, int scale) {
00351         return new BigDecimal(d).
00352             setScale(scale, BigDecimal.ROUND_HALF_DOWN).toString();
00353     }
00354 
00355     public void run(int ntxns, int threads) {
00356         double gtps;
00357         int txns, failed;
00358         long curtime, starttime;
00359         TxnThread[] txnList = new TxnThread[threads];
00360         for (int i = 0; i < threads; i++)
00361             txnList[i] = new TxnThread("Thread " + String.valueOf(i), ntxns);
00362 
00363         starttime = (new Date()).getTime();
00364         for (int i = 0; i < threads; i++)
00365             txnList[i].start();
00366         for (int i = 0; i < threads; i++)
00367             try {
00368                 txnList[i].join();
00369             } catch (Exception e1) {
00370                 errExit(e1, "join failed");
00371             }
00372 
00373         curtime = (new Date()).getTime();
00374         txns = failed = 0;
00375         for (int i = 0; i < threads; i++) {
00376             txns += txnList[i].txns;
00377             failed += txnList[i].failed;
00378         }
00379         gtps = (double)(txns - failed) /
00380             ((curtime - starttime) / 1000.0);
00381         System.out.print("\nTotal: " +
00382                          String.valueOf(txns) + " txns " +
00383                          String.valueOf(failed) + " failed ");
00384         System.out.println(showRounded(gtps, 2) + " TPS");
00385     }
00386 
00387     class TxnThread extends Thread {
00388         private int ntxns;       /* Number of txns we were asked to run. */
00389         public int txns, failed; /* Number that succeeded / failed. */
00390         private Database adb, bdb, hdb, tdb;
00391 
00392         public TxnThread(String name, int ntxns) {
00393             super(name);
00394             this.ntxns = ntxns;
00395         }
00396 
00397         public void run() {
00398             double gtps, itps;
00399             int n, ret;
00400             long start_time, end_time;
00401 
00402             //
00403             // Open the database files.
00404             //
00405             int err;
00406             try {
00407                 DatabaseConfig config = new DatabaseConfig();
00408                 config.setTransactional(true);
00409                 adb = dbenv.openDatabase(null, "account", null, config);
00410                 bdb = dbenv.openDatabase(null, "branch", null, config);
00411                 tdb = dbenv.openDatabase(null, "teller", null, config);
00412                 hdb = dbenv.openDatabase(null, "history", null, config);
00413             } catch (DatabaseException dbe) {
00414                 TpcbExample.errExit(dbe, "Open of db files failed");
00415             } catch (FileNotFoundException fnfe) {
00416                 TpcbExample.errExit(fnfe, "Open of db files failed, missing file");
00417             }
00418 
00419             start_time = (new Date()).getTime();
00420             for (txns = n = ntxns, failed = 0; n-- > 0;)
00421                 if ((ret = txn()) != 0)
00422                     failed++;
00423             end_time = (new Date()).getTime();
00424             if (end_time == start_time)
00425                 end_time++;
00426 
00427             System.out.println(getName() + ": " + (long)txns + " txns: " +
00428                 failed + " failed, " + TpcbExample.showRounded(
00429                 (txns - failed) / (double)(end_time - start_time), 2) + " TPS");
00430 
00431             try {
00432                 adb.close();
00433                 bdb.close();
00434                 tdb.close();
00435                 hdb.close();
00436             } catch (DatabaseException dbe2) {
00437                 TpcbExample.errExit(dbe2, "Close of db files failed");
00438             }
00439         }
00440 
00441         //
00442         // XXX Figure out the appropriate way to pick out IDs.
00443         //
00444         int txn() {
00445             Cursor acurs = null;
00446             Cursor bcurs = null;
00447             Cursor hcurs = null;
00448             Cursor tcurs = null;
00449             Transaction t = null;
00450 
00451             Defrec rec = new Defrec();
00452             Histrec hrec = new Histrec();
00453             int account, branch, teller;
00454 
00455             DatabaseEntry d_dbt = new DatabaseEntry();
00456             DatabaseEntry d_histdbt = new DatabaseEntry();
00457             DatabaseEntry k_dbt = new DatabaseEntry();
00458             DatabaseEntry k_histdbt = new DatabaseEntry();
00459 
00460             account = TpcbExample.this.random_id(TpcbExample.ACCOUNT);
00461             branch = TpcbExample.this.random_id(TpcbExample.BRANCH);
00462             teller = TpcbExample.this.random_id(TpcbExample.TELLER);
00463 
00464             // The history key will not actually be retrieved,
00465             // but it does need to be set to something.
00466             byte[] hist_key = new byte[4];
00467             k_histdbt.setData(hist_key);
00468             k_histdbt.setSize(4 /* == sizeof(int)*/);
00469 
00470             byte[] key_bytes = new byte[4];
00471             k_dbt.setData(key_bytes);
00472             k_dbt.setSize(4 /* == sizeof(int)*/);
00473 
00474             d_dbt.setData(rec.data);
00475             d_dbt.setUserBuffer(rec.length(), true);
00476 
00477             hrec.set_aid(account);
00478             hrec.set_bid(branch);
00479             hrec.set_tid(teller);
00480             hrec.set_amount(10);
00481             // Request 0 bytes since we're just positioning.
00482             d_histdbt.setPartial(0, 0, true);
00483 
00484             // START PER-TRANSACTION TIMING.
00485             // 
00486             // Technically, TPCB requires a limit on response time, you only
00487             // get to count transactions that complete within 2 seconds.
00488             // That's not an issue for this sample application -- regardless,
00489             // here's where the transaction begins.
00490             try {
00491                 t = dbenv.beginTransaction(null, null);
00492 
00493                 acurs = adb.openCursor(t, null);
00494                 bcurs = bdb.openCursor(t, null);
00495                 tcurs = tdb.openCursor(t, null);
00496                 hcurs = hdb.openCursor(t, null);
00497 
00498                 // Account record
00499                 k_dbt.setRecordNumber(account);
00500                 if (acurs.getSearchKey(k_dbt, d_dbt, null) != OperationStatus.SUCCESS)
00501                     throw new Exception("acurs get failed");
00502                 rec.set_balance(rec.get_balance() + 10);
00503                 acurs.putCurrent(d_dbt);
00504 
00505                 // Branch record
00506                 k_dbt.setRecordNumber(branch);
00507                 if (bcurs.getSearchKey(k_dbt, d_dbt, null) != OperationStatus.SUCCESS)
00508                     throw new Exception("bcurs get failed");
00509                 rec.set_balance(rec.get_balance() + 10);
00510                 bcurs.putCurrent(d_dbt);
00511 
00512                 // Teller record
00513                 k_dbt.setRecordNumber(teller);
00514                 if (tcurs.getSearchKey(k_dbt, d_dbt, null) != OperationStatus.SUCCESS)
00515                     throw new Exception("ccurs get failed");
00516                 rec.set_balance(rec.get_balance() + 10);
00517                 tcurs.putCurrent(d_dbt);
00518 
00519                 // History record
00520                 d_histdbt.setPartial(0, 0, false);
00521                 d_histdbt.setData(hrec.data);
00522                 d_histdbt.setUserBuffer(hrec.length(), true);
00523                 if (hdb.append(t, k_histdbt, d_histdbt) != OperationStatus.SUCCESS)
00524                     throw new DatabaseException("put failed");
00525 
00526                 acurs.close();
00527                 acurs = null;
00528                 bcurs.close();
00529                 bcurs = null;
00530                 tcurs.close();
00531                 tcurs = null;
00532                 hcurs.close();
00533                 hcurs = null;
00534 
00535                 // null out t in advance; if the commit fails,
00536                 // we don't want to abort it in the catch clause.
00537                 Transaction tmptxn = t;
00538                 t = null;
00539                 tmptxn.commit();
00540 
00541                 // END TIMING
00542                 return (0);
00543             } catch (Exception e) {
00544                 try {
00545                     if (acurs != null)
00546                         acurs.close();
00547                     if (bcurs != null)
00548                         bcurs.close();
00549                     if (tcurs != null)
00550                         tcurs.close();
00551                     if (hcurs != null)
00552                         hcurs.close();
00553                     if (t != null)
00554                         t.abort();
00555                 } catch (DatabaseException dbe) {
00556                     // not much we can do here.
00557                 }
00558 
00559                 if (TpcbExample.this.verbose) {
00560                     System.out.println("Transaction A=" + String.valueOf(account) +
00561                                        " B=" + String.valueOf(branch) +
00562                                        " T=" + String.valueOf(teller) +
00563                                        " failed");
00564                     System.out.println("Reason: " + e.toString());
00565                 }
00566                 return (-1);
00567             }
00568         }
00569     }
00570 
00571     private static void usage() {
00572         System.err.println(
00573                "usage: TpcbExample [-fiv] [-a accounts] [-b branches]\n" +
00574                "                   [-c cachesize] [-h home] [-n transactions]\n" +
00575                "                   [-T threads] [-S seed] [-s history] [-t tellers]");
00576         System.exit(1);
00577     }
00578 
00579     private static void invarg(String str) {
00580         System.err.println("TpcbExample: invalid argument: " + str);
00581         System.exit(1);
00582     }
00583 
00584     public static void errExit(Exception err, String s) {
00585         System.err.print(progname + ": ");
00586         if (s != null) {
00587             System.err.print(s + ": ");
00588         }
00589         System.err.println(err.toString());
00590         System.exit(1);
00591     }
00592 
00593     public static void main(String[] argv) throws java.io.IOException {
00594         File home = new File("TESTDIR");
00595         int accounts = ACCOUNTS;
00596         int branches = BRANCHES;
00597         int tellers = TELLERS;
00598         int history = HISTORY;
00599         int threads = 1;
00600         int mpool = 0;
00601         int ntxns = 0;
00602         boolean iflag = false;
00603         boolean txn_no_sync = false;
00604         long seed = (new GregorianCalendar()).get(Calendar.SECOND);
00605 
00606         for (int i = 0; i < argv.length; ++i) {
00607             if (argv[i].equals("-a")) {
00608                 // Number of account records
00609                 if ((accounts = Integer.parseInt(argv[++i])) <= 0)
00610                     invarg(argv[i]);
00611             } else if (argv[i].equals("-b")) {
00612                 // Number of branch records
00613                 if ((branches = Integer.parseInt(argv[++i])) <= 0)
00614                     invarg(argv[i]);
00615             } else if (argv[i].equals("-c")) {
00616                 // Cachesize in bytes
00617                 if ((mpool = Integer.parseInt(argv[++i])) <= 0)
00618                     invarg(argv[i]);
00619             } else if (argv[i].equals("-f")) {
00620                 // Fast mode: no txn sync.
00621                 txn_no_sync = true;
00622             } else if (argv[i].equals("-h")) {
00623                 // DB  home.
00624                 home = new File(argv[++i]);
00625             } else if (argv[i].equals("-i")) {
00626                 // Initialize the test.
00627                 iflag = true;
00628             } else if (argv[i].equals("-n")) {
00629                 // Number of transactions
00630                 if ((ntxns = Integer.parseInt(argv[++i])) <= 0)
00631                     invarg(argv[i]);
00632             } else if (argv[i].equals("-S")) {
00633                 // Random number seed.
00634                 seed = Long.parseLong(argv[++i]);
00635                 if (seed <= 0)
00636                     invarg(argv[i]);
00637             } else if (argv[i].equals("-s")) {
00638                 // Number of history records
00639                 if ((history = Integer.parseInt(argv[++i])) <= 0)
00640                     invarg(argv[i]);
00641             } else if (argv[i].equals("-T")) {
00642                 // Number of threads
00643                 if ((threads = Integer.parseInt(argv[++i])) <= 0)
00644                     invarg(argv[i]);
00645             } else if (argv[i].equals("-t")) {
00646                 // Number of teller records
00647                 if ((tellers = Integer.parseInt(argv[++i])) <= 0)
00648                     invarg(argv[i]);
00649             } else if (argv[i].equals("-v")) {
00650                 // Verbose option.
00651                 verbose = true;
00652             } else {
00653                 usage();
00654             }
00655         }
00656 
00657         rand.setSeed((int)seed);
00658 
00659         // Initialize the database environment.
00660         // Must be done in within a try block.
00661         //
00662         TpcbExample app = null;
00663         try {
00664             app = new TpcbExample(home, accounts, branches, tellers, history,
00665                                   mpool, txn_no_sync);
00666         } catch (Exception e1) {
00667             errExit(e1, "initializing environment failed");
00668         }
00669 
00670         if (verbose)
00671             System.out.println((long)accounts + " Accounts, " +
00672                                String.valueOf(branches) + " Branches, " +
00673                                String.valueOf(tellers) + " Tellers, " +
00674                                String.valueOf(history) + " History");
00675 
00676         if (iflag) {
00677             if (ntxns != 0)
00678                 usage();
00679             app.populate();
00680         } else {
00681             if (ntxns == 0)
00682                 usage();
00683             app.run(ntxns, threads);
00684         }
00685 
00686         // Shut down the application.
00687 
00688         try {
00689             app.close();
00690         } catch (DatabaseException dbe2) {
00691             errExit(dbe2, "appexit failed");
00692         }
00693 
00694         System.exit(0);
00695     }
00696 };
00697 
00698 // Simulate the following C struct:
00699 // struct Defrec {
00700 //     u_int32_t   id;
00701 //     u_int32_t   balance;
00702 //     u_int8_t    pad[RECLEN - sizeof(int) - sizeof(int)];
00703 // };
00704 
00705 class Defrec {
00706     public Defrec() {
00707         data = new byte[TpcbExample.RECLEN];
00708     }
00709 
00710     public int length() {
00711         return TpcbExample.RECLEN;
00712     }
00713 
00714     public long get_id() {
00715         return TpcbExample.get_int_in_array(data, 0);
00716     }
00717 
00718     public void set_id(long value) {
00719         TpcbExample.set_int_in_array(data, 0, value);
00720     }
00721 
00722     public long get_balance() {
00723         return TpcbExample.get_int_in_array(data, 4);
00724     }
00725 
00726     public void set_balance(long value) {
00727         TpcbExample.set_int_in_array(data, 4, value);
00728     }
00729 
00730     static {
00731         Defrec d = new Defrec();
00732         d.set_balance(500000);
00733     }
00734 
00735     public byte[] data;
00736 }
00737 
00738 // Simulate the following C struct:
00739 // struct Histrec {
00740 //     u_int32_t   aid;
00741 //     u_int32_t   bid;
00742 //     u_int32_t   tid;
00743 //     u_int32_t   amount;
00744 //     u_int8_t    pad[RECLEN - 4 * sizeof(u_int32_t)];
00745 // };
00746 
00747 class Histrec {
00748     public Histrec() {
00749         data = new byte[TpcbExample.RECLEN];
00750     }
00751 
00752     public int length() {
00753         return TpcbExample.RECLEN;
00754     }
00755 
00756     public long get_aid() {
00757         return TpcbExample.get_int_in_array(data, 0);
00758     }
00759 
00760     public void set_aid(long value) {
00761         TpcbExample.set_int_in_array(data, 0, value);
00762     }
00763 
00764     public long get_bid() {
00765         return TpcbExample.get_int_in_array(data, 4);
00766     }
00767 
00768     public void set_bid(long value) {
00769         TpcbExample.set_int_in_array(data, 4, value);
00770     }
00771 
00772     public long get_tid() {
00773         return TpcbExample.get_int_in_array(data, 8);
00774     }
00775 
00776     public void set_tid(long value) {
00777         TpcbExample.set_int_in_array(data, 8, value);
00778     }
00779 
00780     public long get_amount() {
00781         return TpcbExample.get_int_in_array(data, 12);
00782     }
00783 
00784     public void set_amount(long value) {
00785         TpcbExample.set_int_in_array(data, 12, value);
00786     }
00787 
00788     public byte[] data;
00789 }

Generated on Sun Dec 25 12:14:27 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2