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

client.c

00001 #include <sys/types.h>
00002 #include <sys/time.h>
00003 
00004 #include <ctype.h>
00005 #include <stdio.h>
00006 #include <stdlib.h>
00007 #include <string.h>
00008 #include <unistd.h>
00009 
00010 #include <tx.h>
00011 #include <atmi.h>
00012 #include <fml32.h>
00013 #include <fml1632.h>
00014 
00015 #include <db.h>
00016 
00017 #include "datafml.h"
00018 #include "hdbrec.h"
00019 #include "hcommonxa.h"
00020 #include "htimestampxa.h"
00021 
00022 #define HOME    "../data"
00023 #define TABLE1  "../data/table1.db"
00024 #define TABLE3  "../data/table3.db"
00025 
00026 #ifdef VERBOSE
00027 static int verbose = 1;                         /* Debugging output. */
00028 #else
00029 static int verbose = 0;
00030 #endif
00031 
00032 DB_ENV *dbenv;
00033 char *progname;                                 /* Client run-time name. */
00034 
00035 int   check_data(DB *);
00036 char *db_buf(DBT *);
00037 int   usage(void);
00038 
00039 int
00040 main(int argc, char* argv[])
00041 {
00042         DB *dbp3;
00043         DBT key, data;
00044         FBFR *buf, *replyBuf;
00045         HDbRec rec;
00046         TPINIT *initBuf;
00047         long len, replyLen, seqNo;
00048         int ch, cnt, cnt_abort, cnt_commit, cnt_server1, i, ret;
00049         char *target;
00050 
00051         progname = argv[0];
00052 
00053         buf = replyBuf = NULL;
00054         initBuf = NULL;
00055         cnt = 1000;
00056         cnt_abort = cnt_commit = cnt_server1 = 0;
00057 
00058         while ((ch = getopt(argc, argv, "n:v")) != EOF)
00059                 switch (ch) {
00060                 case 'n':
00061                         cnt = atoi(optarg);
00062                         break;
00063                 case 'v':
00064                         verbose = 1;
00065                         break;
00066                 case '?':
00067                 default:
00068                         return (usage());
00069                 }
00070         argc -= optind;
00071         argv += optind;
00072 
00073         if (verbose)
00074                 printf("%s: called\n", progname);
00075 
00076         /* Seed random number generator. */
00077         srand((u_int)(time(NULL) | getpid()));
00078 
00079         if (tpinit((TPINIT *)NULL) == -1)
00080                 goto tuxedo_err;
00081         if (verbose)
00082                 printf("%s: tpinit() OK\n", progname);
00083 
00084         /* Allocate init buffer */
00085         if((initBuf = (TPINIT *)tpalloc("TPINIT", NULL, TPINITNEED(0))) == 0)
00086                 goto tuxedo_err;
00087         if (verbose)
00088                 printf("%s: tpalloc(\"TPINIT\") OK\n", progname);
00089 
00090         /* Join the DB environment. */
00091         if ((ret = db_env_create(&dbenv, 0)) != 0 ||
00092             (ret = dbenv->open(dbenv, HOME, DB_JOINENV, 0)) != 0) {
00093                 fprintf(stderr,
00094                     "%s: %s: %s\n", progname, HOME, db_strerror(ret));
00095                 goto err;
00096         }
00097         dbenv->set_errfile(dbenv, stderr);
00098         if (verbose)
00099                 printf("%s: opened %s OK\n", progname, HOME);
00100 
00101         /* Open table #3 -- truncate it for each new run. */
00102         if ((ret = db_create(&dbp3, dbenv, 0)) != 0 ||
00103             (ret = dbp3->open(dbp3,
00104             NULL, TABLE3, NULL, DB_BTREE, DB_CREATE, 0660)) != 0) {
00105                 fprintf(stderr,
00106                     "%s: %s %s\n", progname, TABLE3, db_strerror(ret));
00107                 goto err;
00108         }
00109         if (verbose)
00110                 printf("%s: opened/truncated %s OK\n", progname, TABLE3);
00111 
00112         /* Allocate send buffer. */
00113         len = Fneeded(1, 3 * sizeof(long));
00114         if ((buf = (FBFR*)tpalloc("FML32", NULL, len)) == 0)
00115                 goto tuxedo_err;
00116         if (verbose)
00117                 printf("%s: tpalloc(\"FML32\"), send buffer OK\n", progname);
00118 
00119         /* Allocate reply buffer. */
00120         replyLen = 1024;
00121         if ((replyBuf = (FBFR*)tpalloc("FML32", NULL, replyLen)) == NULL)
00122                 goto tuxedo_err;
00123         if (verbose)
00124                 printf("%s: tpalloc(\"FML32\"), reply buffer OK\n", progname);
00125 
00126         memset(&key, 0, sizeof(key));
00127         memset(&data, 0, sizeof(data));
00128         for (rec.SeqNo = 1, i = 0; i < cnt; ++i, ++rec.SeqNo) {
00129                 GetTime(&rec.Ts);
00130 
00131                 if (Fchg(buf, SEQ_NO, 0, (char *)&rec.SeqNo, 0) == -1)
00132                         goto tuxedo_fml_err;
00133                 if (verbose)
00134                         printf("%s: Fchg(), sequence number OK\n", progname);
00135                 if (Fchg(buf, TS_SEC, 0, (char *)&rec.Ts.Sec, 0) == -1)
00136                         goto tuxedo_fml_err;
00137                 if (verbose)
00138                         printf("%s: Fchg(), seconds OK\n", progname);
00139                 if (Fchg(buf, TS_USEC, 0, (char *)&rec.Ts.Usec, 0) == -1)
00140                         goto tuxedo_fml_err;
00141                 if (verbose)
00142                         printf("%s: Fchg(), microseconds OK\n", progname);
00143 
00144                 if (tpbegin(60L, 0L) == -1)
00145                         goto tuxedo_err;
00146                 if (verbose)
00147                         printf("%s: tpbegin() OK\n", progname);
00148 
00149                 /* Randomly send half of our requests to each server. */
00150                 if (rand() % 2 > 0) {
00151                         ++cnt_server1;
00152                         target = "TestTxn1";
00153                 } else
00154                         target = "TestTxn2";
00155                 if (tpcall(target, (char *)buf,
00156                     0L, (char **)&replyBuf, &replyLen, TPSIGRSTRT) == -1)
00157                         goto tuxedo_err;
00158 
00159                 /* Commit for a return value of 0, otherwise abort. */
00160                 if (tpurcode == 0) {
00161                         ++cnt_commit;
00162                         if (verbose)
00163                                 printf("%s: txn success\n", progname);
00164 
00165                         if (tpcommit(0L) == -1)
00166                                 goto tuxedo_err;
00167                         if (verbose)
00168                                 printf("%s: tpcommit() OK\n", progname);
00169 
00170                         /*
00171                          * Store a copy of the key/data pair into table #3
00172                          * on success, we'll compare table #1 and table #3
00173                          * after the run finishes.
00174                          */
00175                         seqNo = rec.SeqNo;
00176                         key.data = &seqNo;
00177                         key.size = sizeof(seqNo);
00178                         data.data = &rec;
00179                         data.size = sizeof(rec);
00180                         if ((ret =
00181                             dbp3->put(dbp3, NULL, &key, &data, 0)) != 0) {
00182                                 fprintf(stderr, "%s: DB->put: %s %s\n",
00183                                     progname, TABLE3, db_strerror(ret));
00184                                 goto err;
00185                         }
00186                 } else {
00187                         ++cnt_abort;
00188                         if (verbose)
00189                                 printf("%s: txn failure\n", progname);
00190 
00191                         if (tpabort(0L) == -1)
00192                                 goto tuxedo_err;
00193                         if (verbose)
00194                                 printf("%s: tpabort() OK\n", progname);
00195                 }
00196         }
00197 
00198         printf("%s: %d requests: %d committed, %d aborted\n",
00199             progname, cnt, cnt_commit, cnt_abort);
00200         printf("%s: %d sent to server #1, %d sent to server #2\n",
00201             progname, cnt_server1, cnt - cnt_server1);
00202 
00203         ret = check_data(dbp3);
00204 
00205         if (0) {
00206 tuxedo_err:     fprintf(stderr, "%s: TUXEDO ERROR: %s (code %d)\n",
00207                     progname, tpstrerror(tperrno), tperrno);
00208                 goto err;
00209         }
00210         if (0) {
00211 tuxedo_fml_err: fprintf(stderr, "%s: FML ERROR: %s (code %d)\n",
00212                     progname, Fstrerror(Ferror), Ferror);
00213         }
00214         if (0) {
00215 err:            ret = EXIT_FAILURE;
00216         }
00217 
00218         if (replyBuf != NULL)
00219                 tpfree((char *)replyBuf);
00220         if (buf != NULL)
00221                 tpfree((char *)buf);
00222         if (initBuf != NULL)
00223                 tpfree((char *)initBuf);
00224         if (dbp3 != NULL)
00225                 (void)dbp3->close(dbp3, 0);
00226         if (dbenv != NULL)
00227                 (void)dbenv->close(dbenv, 0);
00228 
00229         tpterm();
00230         if (verbose)
00231                 printf("%s: tpterm() OK\n", progname);
00232 
00233         return (ret);
00234 }
00235 
00236 /*
00237  * check_data --
00238  *      Compare committed data with our local copy, stored in table3.
00239  */
00240 int
00241 check_data(dbp3)
00242         DB *dbp3;
00243 {
00244         DB *dbp1;
00245         DBC *dbc1, *dbc3;
00246         DBT key1, data1, key3, data3;
00247         int ret, ret1, ret3;
00248 
00249         dbp1 = NULL;
00250         dbc1 = dbc3 = NULL;
00251 
00252         /* Open table #1. */
00253         if ((ret = db_create(&dbp1, dbenv, 0)) != 0 ||
00254             (ret = dbp1->open(
00255             dbp1, NULL, TABLE1, NULL, DB_UNKNOWN, DB_RDONLY, 0)) != 0) {
00256                 fprintf(stderr,
00257                     "%s: %s: %s\n", progname, TABLE1, db_strerror(ret));
00258                 goto err;
00259         }
00260         if (verbose)
00261                 printf("%s: opened %s OK\n", progname, TABLE1);
00262 
00263         /* Open cursors. */
00264         if ((ret = dbp1->cursor(dbp1, NULL, &dbc1, 0)) != 0 ||
00265             (ret = dbp3->cursor(dbp3, NULL, &dbc3, 0)) != 0) {
00266                 fprintf(stderr,
00267                     "%s: DB->cursor: %s\n", progname, db_strerror(ret));
00268                 goto err;
00269         }
00270         if (verbose)
00271                 printf("%s: opened cursors OK\n", progname);
00272 
00273         /* Compare the two databases. */
00274         memset(&key1, 0, sizeof(key1));
00275         memset(&data1, 0, sizeof(data1));
00276         memset(&key3, 0, sizeof(key3));
00277         memset(&data3, 0, sizeof(data3));
00278         for (;;) {
00279                 ret1 = dbc1->c_get(dbc1, &key1, &data1, DB_NEXT);
00280                 ret3 = dbc3->c_get(dbc3, &key3, &data3, DB_NEXT);
00281                 if (verbose) {
00282                         printf("get: key1: %s\n", db_buf(&key1));
00283                         printf("get: key3: %s\n", db_buf(&key3));
00284                         printf("get: data1: %s\n", db_buf(&data1));
00285                         printf("get: data3: %s\n", db_buf(&data3));
00286                 }
00287                 if (ret1 != 0 || ret3 != 0)
00288                         break;
00289                 /*
00290                  * Only compare the first N bytes, the saved message chunks
00291                  * are different.
00292                  */
00293                 if (key1.size != key3.size ||
00294                     memcmp(key1.data, key3.data, key1.size) != 0 ||
00295                     data1.size != data3.size ||
00296                     memcmp(data1.data, data3.data,
00297                     sizeof(long) + sizeof(HTimestampData)) != 0)
00298                         goto mismatch;
00299         }
00300         if (ret1 != DB_NOTFOUND || ret3 != DB_NOTFOUND) {
00301 mismatch:       fprintf(stderr,
00302                     "%s: DB_ERROR: databases 1 and 3 weren't identical\n",
00303                     progname);
00304                 ret = 1;
00305         }
00306 
00307 err:    if (dbc1 != NULL)
00308                 (void)dbc1->c_close(dbc1);
00309         if (dbc3 != NULL)
00310                 (void)dbc3->c_close(dbc1);
00311         if (dbp1 != NULL)
00312                 (void)dbp1->close(dbp1, 0);
00313 
00314         return (ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
00315 }
00316 
00317 char *
00318 db_buf(dbt)
00319         DBT *dbt;
00320 {
00321         static u_char buf[1024];
00322         size_t len;
00323         u_char *p, *b;
00324 
00325         for (p = dbt->data, len = dbt->size, b = buf; len > 0; ++p, --len)
00326                 if (isprint(*p))
00327                         b += sprintf((char *)b, "%c", *p);
00328                 else
00329                         b += sprintf((char *)b, "%#o", *p);
00330         return ((char *)buf);
00331 }
00332 
00333 int
00334 usage()
00335 {
00336         fprintf(stderr, "usage: %s [-v] [-n txn]\n", progname);
00337         return (EXIT_FAILURE);
00338 }

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