diff options
Diffstat (limited to 'bdb/examples_c')
-rw-r--r-- | bdb/examples_c/README | 29 | ||||
-rw-r--r-- | bdb/examples_c/bench_001.c | 382 | ||||
-rw-r--r-- | bdb/examples_c/ex_access.c | 162 | ||||
-rw-r--r-- | bdb/examples_c/ex_apprec/auto_rebuild | 9 | ||||
-rw-r--r-- | bdb/examples_c/ex_apprec/ex_apprec.c | 267 | ||||
-rw-r--r-- | bdb/examples_c/ex_apprec/ex_apprec.h | 24 | ||||
-rw-r--r-- | bdb/examples_c/ex_apprec/ex_apprec.src | 41 | ||||
-rw-r--r-- | bdb/examples_c/ex_apprec/ex_apprec_rec.c | 115 | ||||
-rw-r--r-- | bdb/examples_c/ex_btrec.c | 203 | ||||
-rw-r--r-- | bdb/examples_c/ex_dbclient.c | 226 | ||||
-rw-r--r-- | bdb/examples_c/ex_env.c | 135 | ||||
-rw-r--r-- | bdb/examples_c/ex_lock.c | 239 | ||||
-rw-r--r-- | bdb/examples_c/ex_mpool.c | 253 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_repquote.h | 69 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_rq_client.c | 250 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_rq_main.c | 303 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_rq_master.c | 165 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_rq_net.c | 692 | ||||
-rw-r--r-- | bdb/examples_c/ex_repquote/ex_rq_util.c | 412 | ||||
-rw-r--r-- | bdb/examples_c/ex_thread.c | 629 | ||||
-rw-r--r-- | bdb/examples_c/ex_tpcb.c | 698 | ||||
-rw-r--r-- | bdb/examples_c/ex_tpcb.h | 39 |
22 files changed, 0 insertions, 5342 deletions
diff --git a/bdb/examples_c/README b/bdb/examples_c/README deleted file mode 100644 index d5475ba01b2..00000000000 --- a/bdb/examples_c/README +++ /dev/null @@ -1,29 +0,0 @@ -# $Id: README,v 11.5 2002/02/26 16:22:45 krinsky Exp $ - -ex_access.c Using just the DB access methods. - -ex_apprec Application-specific recovery. - -ex_btrec.c Using the BTREE access method with record numbers. - -ex_env.c Setting up the DB environment. - -ex_lock.c Locking. - -ex_mpool.c Shared memory buffer pools. - -ex_repquote Replication. This creates a toy stock quote server - with DB's single-master, multiple-client replication, - with communication over TCP. - -ex_tpcb.c TPC/B. - Ex_tpcb sets up a framework in which to run a TPC/B test. - Database initialization (the -i flag) and running the - benchmark (-n flag) must take place separately (i.e., - first create the database, then run 1 or more copies of - the benchmark). Furthermore, when running more than one - TPCB process, it is necessary to run the deadlock detector - (db_deadlock), since it is possible for concurrent tpcb - processes to deadlock. For performance measurement, it - will also be beneficial to run the db_checkpoint process - as well. diff --git a/bdb/examples_c/bench_001.c b/bdb/examples_c/bench_001.c deleted file mode 100644 index 14fd3e549b6..00000000000 --- a/bdb/examples_c/bench_001.c +++ /dev/null @@ -1,382 +0,0 @@ -/*- - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: bench_001.c,v 1.13 2002/08/15 02:45:39 bostic Exp $ - */ - -/* - * bench_001 - time bulk fetch interface. - * Without -R builds a btree acording to the arguments. - * With -R runs and times bulk fetches. If -d is specified - * during reads the DB_MULTIPLE interface is used - * otherwise the DB_MULTIPLE_KEY interface is used. - * - * ARGUMENTS: - * -c cachesize [1000 * pagesize] - * -d number of duplicates [none] - * -E don't use environment - * -I Just initialize the environment - * -i number of read iterations [1000000] - * -l length of data item [20] - * -n number of keys [1000000] - * -p pagesize [65536] - * -R perform read test. - * -T incorporate transactions. - * - * COMPILE: - * cc -I /usr/local/BerkeleyDB/include \ - * -o bench_001 -O2 bench_001.c /usr/local/BerkeleyDB/lib/libdb.so - */ -#include <sys/types.h> - -#include <sys/time.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#define DATABASE "bench_001.db" - -int main(int, char *[]); -void usage(void); - -const char - *progname = "bench_001"; /* Program name. */ -/* - * db_init -- - * Initialize the environment. - */ -DB_ENV * -db_init(home, prefix, cachesize, txn) - char *home, *prefix; - int cachesize, txn; -{ - DB_ENV *dbenv; - int flags, ret; - - if ((ret = db_env_create(&dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_env_create"); - return (NULL); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, prefix); - (void)dbenv->set_cachesize(dbenv, 0, - cachesize == 0 ? 50 * 1024 * 1024 : (u_int32_t)cachesize, 0); - - flags = DB_CREATE | DB_INIT_MPOOL; - if (txn) - flags |= DB_INIT_TXN | DB_INIT_LOCK; - if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open: %s", home); - (void)dbenv->close(dbenv, 0); - return (NULL); - } - return (dbenv); -} - -/* - * get -- loop getting batches of records. - * - */ -int -get(dbp, txn, datalen, num, dups, iter, countp) - DB *dbp; - int txn, datalen, num, dups, iter, *countp; -{ - DBC *dbcp; - DBT key, data; - DB_TXN *txnp; - u_int32_t len, klen; - int count, flags, i, j, ret; - void *pointer, *dp, *kp; - - memset(&key, 0, sizeof(key)); - key.data = &j; - key.size = sizeof(j); - memset(&data, 0, sizeof(data)); - data.flags = DB_DBT_USERMEM; - data.data = malloc(datalen*1024*1024); - data.ulen = data.size = datalen*1024*1024; - count = 0; - flags = DB_SET; - if (!dups) - flags |= DB_MULTIPLE_KEY; - else - flags |= DB_MULTIPLE; - for (i = 0; i < iter; i++) { - txnp = NULL; - if (txn) - dbp->dbenv->txn_begin(dbp->dbenv, NULL, &txnp, 0); - dbp->cursor(dbp, txnp, &dbcp, 0); - - j = random() % num; - switch (ret = dbcp->c_get(dbcp, &key, &data, flags)) { - case 0: - break; - default: - dbp->err(dbcp->dbp, ret, "DBC->c_get"); - return (ret); - } - DB_MULTIPLE_INIT(pointer, &data); - if (dups) - while (pointer != NULL) { - DB_MULTIPLE_NEXT(pointer, &data, dp, len); - if (dp != NULL) - count++; - } - else - while (pointer != NULL) { - DB_MULTIPLE_KEY_NEXT(pointer, - &data, kp, klen, dp, len); - if (kp != NULL) - count++; - } - dbcp->c_close(dbcp); - if (txn) - txnp->commit(txnp, 0); - } - - *countp = count; - return (0); -} - -/* - * fill - fill a db - * Since we open/created the db with transactions (potentially), - * we need to populate it with transactions. We'll bundle the puts - * 10 to a transaction. - */ -#define PUTS_PER_TXN 10 -int -fill(dbenv, dbp, txn, datalen, num, dups) - DB_ENV *dbenv; - DB *dbp; - int txn, datalen, num, dups; -{ - DBT key, data; - DB_TXN *txnp; - struct data { - int id; - char str[1]; - } *data_val; - int count, i, ret; - /* - * Insert records into the database, where the key is the user - * input and the data is the user input in reverse order. - */ - txnp = NULL; - ret = 0; - count = 0; - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - key.data = &i; - key.size = sizeof(i); - data.data = data_val = (struct data *) malloc(datalen); - memcpy(data_val->str, "0123456789012345678901234567890123456789", - datalen - sizeof (data_val->id)); - data.size = datalen; - data.flags = DB_DBT_USERMEM; - - for (i = 0; i < num; i++) { - if (txn != 0 && i % PUTS_PER_TXN == 0) { - if (txnp != NULL) { - ret = txnp->commit(txnp, 0); - txnp = NULL; - if (ret != 0) - goto err; - } - if ((ret = - dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0) - goto err; - } - data_val->id = 0; - do { - switch (ret = - dbp->put(dbp, txnp, &key, &data, 0)) { - case 0: - count++; - break; - default: - dbp->err(dbp, ret, "DB->put"); - goto err; - } - } while (++data_val->id < dups); - } - if (txnp != NULL) - ret = txnp->commit(txnp, 0); - - printf("%d\n", count); - return (ret); - -err: if (txnp != NULL) - (void)txnp->abort(txnp); - return (ret); -} - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB *dbp; - DB_ENV *dbenv; - DB_TXN *txnp; - struct timeval start_time, end_time; - double secs; - int cache, ch, count, datalen, dups, env, init, iter, num, pagesize; - int ret, rflag, txn; - - txnp = NULL; - datalen = 20; - iter = num = 1000000; - env = 1; - dups = init = rflag = txn = 0; - - pagesize = 65536; - cache = 1000 * pagesize; - - while ((ch = getopt(argc, argv, "c:d:EIi:l:n:p:RT")) != EOF) - switch (ch) { - case 'c': - cache = atoi(optarg); - break; - case 'd': - dups = atoi(optarg); - break; - case 'E': - env = 0; - break; - case 'I': - init = 1; - break; - case 'i': - iter = atoi(optarg); - break; - case 'l': - datalen = atoi(optarg); - break; - case 'n': - num = atoi(optarg); - break; - case 'p': - pagesize = atoi(optarg); - break; - case 'R': - rflag = 1; - break; - case 'T': - txn = 1; - break; - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - /* Remove the previous database. */ - if (!rflag) { - if (env) - system("rm -rf BENCH_001; mkdir BENCH_001"); - else - (void)unlink(DATABASE); - } - - dbenv = NULL; - if (env == 1 && - (dbenv = db_init("BENCH_001", "bench_001", cache, txn)) == NULL) - return (-1); - if (init) - exit(0); - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_create: %s\n", progname, db_strerror(ret)); - exit(EXIT_FAILURE); - } - dbp->set_errfile(dbp, stderr); - dbp->set_errpfx(dbp, progname); - if ((ret = dbp->set_pagesize(dbp, pagesize)) != 0) { - dbp->err(dbp, ret, "set_pagesize"); - goto err1; - } - if (dups && (ret = dbp->set_flags(dbp, DB_DUP)) != 0) { - dbp->err(dbp, ret, "set_flags"); - goto err1; - } - - if (env == 0 && (ret = dbp->set_cachesize(dbp, 0, cache, 0)) != 0) { - dbp->err(dbp, ret, "set_cachesize"); - goto err1; - } - - if ((ret = dbp->set_flags(dbp, DB_DUP)) != 0) { - dbp->err(dbp, ret, "set_flags"); - goto err1; - } - - if (txn != 0) - if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0) - goto err1; - - if ((ret = dbp->open( - dbp, txnp, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { - dbp->err(dbp, ret, "%s: open", DATABASE); - if (txnp != NULL) - (void)txnp->abort(txnp); - goto err1; - } - - if (txnp != NULL) - ret = txnp->commit(txnp, 0); - txnp = NULL; - if (ret != 0) - goto err1; - - if (rflag) { - /* If no environment, fill the cache. */ - if (!env && (ret = - get(dbp, txn, datalen, num, dups, iter, &count)) != 0) - goto err1; - - /* Time the get loop. */ - gettimeofday(&start_time, NULL); - if ((ret = - get(dbp, txn, datalen, num, dups, iter, &count)) != 0) - goto err1; - gettimeofday(&end_time, NULL); - secs = - (((double)end_time.tv_sec * 1000000 + end_time.tv_usec) - - ((double)start_time.tv_sec * 1000000 + start_time.tv_usec)) - / 1000000; - printf("%d records read using %d batches in %.2f seconds: ", - count, iter, secs); - printf("%.0f records/second\n", (double)count / secs); - - } else if ((ret = fill(dbenv, dbp, txn, datalen, num, dups)) != 0) - goto err1; - - /* Close everything down. */ - if ((ret = dbp->close(dbp, rflag ? DB_NOSYNC : 0)) != 0) { - fprintf(stderr, - "%s: DB->close: %s\n", progname, db_strerror(ret)); - return (1); - } - return (ret); - -err1: (void)dbp->close(dbp, 0); - return (1); -} - -void -usage() -{ - (void)fprintf(stderr, "usage: %s %s\n\t%s\n", - progname, "[-EIRT] [-c cachesize] [-d dups]", - "[-i iterations] [-l datalen] [-n keys] [-p pagesize]"); - exit(EXIT_FAILURE); -} diff --git a/bdb/examples_c/ex_access.c b/bdb/examples_c/ex_access.c deleted file mode 100644 index 5cac09ecf05..00000000000 --- a/bdb/examples_c/ex_access.c +++ /dev/null @@ -1,162 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_access.c,v 11.22 2002/09/03 12:54:26 bostic Exp $ - */ - -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef _WIN32 -extern int getopt(int, char * const *, const char *); -#else -#include <unistd.h> -#endif - -#include <db.h> - -#define DATABASE "access.db" -int main __P((int, char *[])); -int usage __P((void)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern int optind; - DB *dbp; - DBC *dbcp; - DBT key, data; - u_int32_t len; - int ch, ret, rflag; - char *database, *p, *t, buf[1024], rbuf[1024]; - const char *progname = "ex_access"; /* Program name. */ - - rflag = 0; - while ((ch = getopt(argc, argv, "r")) != EOF) - switch (ch) { - case 'r': - rflag = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - /* Accept optional database name. */ - database = *argv == NULL ? DATABASE : argv[0]; - - /* Optionally discard the database. */ - if (rflag) - (void)remove(database); - - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&dbp, NULL, 0)) != 0) { - fprintf(stderr, - "%s: db_create: %s\n", progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - dbp->set_errfile(dbp, stderr); - dbp->set_errpfx(dbp, progname); - if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) { - dbp->err(dbp, ret, "set_pagesize"); - goto err1; - } - if ((ret = dbp->set_cachesize(dbp, 0, 32 * 1024, 0)) != 0) { - dbp->err(dbp, ret, "set_cachesize"); - goto err1; - } - if ((ret = dbp->open(dbp, - NULL, database, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { - dbp->err(dbp, ret, "%s: open", database); - goto err1; - } - - /* - * Insert records into the database, where the key is the user - * input and the data is the user input in reverse order. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - for (;;) { - printf("input> "); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - if (strcmp(buf, "exit\n") == 0 || strcmp(buf, "quit\n") == 0) - break; - if ((len = strlen(buf)) <= 1) - continue; - for (t = rbuf, p = buf + (len - 2); p >= buf;) - *t++ = *p--; - *t++ = '\0'; - - key.data = buf; - data.data = rbuf; - data.size = key.size = len - 1; - - switch (ret = - dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) { - case 0: - break; - default: - dbp->err(dbp, ret, "DB->put"); - if (ret != DB_KEYEXIST) - goto err1; - break; - } - } - printf("\n"); - - /* Acquire a cursor for the database. */ - if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { - dbp->err(dbp, ret, "DB->cursor"); - goto err1; - } - - /* Initialize the key/data pair so the flags aren't set. */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - - /* Walk through the database and print out the key/data pairs. */ - while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) - printf("%.*s : %.*s\n", - (int)key.size, (char *)key.data, - (int)data.size, (char *)data.data); - if (ret != DB_NOTFOUND) { - dbp->err(dbp, ret, "DBcursor->get"); - goto err2; - } - - /* Close everything down. */ - if ((ret = dbcp->c_close(dbcp)) != 0) { - dbp->err(dbp, ret, "DBcursor->close"); - goto err1; - } - if ((ret = dbp->close(dbp, 0)) != 0) { - fprintf(stderr, - "%s: DB->close: %s\n", progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - return (EXIT_SUCCESS); - -err2: (void)dbcp->c_close(dbcp); -err1: (void)dbp->close(dbp, 0); - return (EXIT_FAILURE); -} - -int -usage() -{ - (void)fprintf(stderr, "usage: ex_access [-r] [database]\n"); - return (EXIT_FAILURE); -} diff --git a/bdb/examples_c/ex_apprec/auto_rebuild b/bdb/examples_c/ex_apprec/auto_rebuild deleted file mode 100644 index 34251984888..00000000000 --- a/bdb/examples_c/ex_apprec/auto_rebuild +++ /dev/null @@ -1,9 +0,0 @@ -# Script to rebuild automatically generated files for ex_apprec. - -E=../examples_c/ex_apprec - -cd ../../dist -awk -f gen_rec.awk \ - -v source_file=$E/ex_apprec_auto.c \ - -v header_file=$E/ex_apprec_auto.h \ - -v template_file=$E/ex_apprec_template < $E/ex_apprec.src diff --git a/bdb/examples_c/ex_apprec/ex_apprec.c b/bdb/examples_c/ex_apprec/ex_apprec.c deleted file mode 100644 index c045e734250..00000000000 --- a/bdb/examples_c/ex_apprec/ex_apprec.c +++ /dev/null @@ -1,267 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_apprec.c,v 1.2 2002/08/06 05:39:01 bostic Exp $ - */ - -#include <sys/types.h> -#include <sys/stat.h> - -#include <errno.h> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_apprec.h" - -int apprec_dispatch __P((DB_ENV *, DBT *, DB_LSN *, db_recops)); -int open_env __P((const char *, FILE *, const char *, DB_ENV **)); -int verify_absence __P((DB_ENV *, const char *)); -int verify_presence __P((DB_ENV *, const char *)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - DB_LSN lsn; - DB_TXN *txn; - DBT dirnamedbt; - int ret; - const char *home; - char ch, dirname[256]; - const char *progname = "ex_apprec"; /* Program name. */ - - /* Default home. */ - home = "TESTDIR"; - - while ((ch = getopt(argc, argv, "h:")) != EOF) - switch (ch) { - case 'h': - home = optarg; - break; - default: - fprintf(stderr, "usage: %s [-h home]", progname); - exit(EXIT_FAILURE); - } - - printf("Set up environment.\n"); - if ((ret = open_env(home, stderr, progname, &dbenv)) != 0) - return (EXIT_FAILURE); - - printf("Create a directory in a transaction.\n"); - /* - * This application's convention is to log the full directory name, - * including trailing nul. - */ - memset(&dirnamedbt, 0, sizeof(dirnamedbt)); - sprintf(dirname, "%s/MYDIRECTORY", home); - dirnamedbt.data = dirname; - dirnamedbt.size = strlen(dirname) + 1; - - if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) { - dbenv->err(dbenv, ret, "txn_begin"); - return (EXIT_FAILURE); - } - - /* Remember, always log actions before you execute them! */ - memset(&lsn, 0, sizeof(lsn)); - if ((ret = - ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) { - dbenv->err(dbenv, ret, "mkdir_log"); - return (EXIT_FAILURE); - } - if (mkdir(dirname, 0755) != 0) { - dbenv->err(dbenv, errno, "mkdir"); - return (EXIT_FAILURE); - } - - printf("Verify the directory's presence: "); - verify_presence(dbenv, dirname); - printf("check.\n"); - - /* Now abort the transaction and verify that the directory goes away. */ - printf("Abort the transaction.\n"); - if ((ret = txn->abort(txn)) != 0) { - dbenv->err(dbenv, ret, "txn_abort"); - return (EXIT_FAILURE); - } - - printf("Verify the directory's absence: "); - verify_absence(dbenv, dirname); - printf("check.\n"); - - /* Now do the same thing over again, only with a commit this time. */ - printf("Create a directory in a transaction.\n"); - memset(&dirnamedbt, 0, sizeof(dirnamedbt)); - sprintf(dirname, "%s/MYDIRECTORY", home); - dirnamedbt.data = dirname; - dirnamedbt.size = strlen(dirname) + 1; - if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) { - dbenv->err(dbenv, ret, "txn_begin"); - return (EXIT_FAILURE); - } - - memset(&lsn, 0, sizeof(lsn)); - if ((ret = - ex_apprec_mkdir_log(dbenv, txn, &lsn, 0, &dirnamedbt)) != 0) { - dbenv->err(dbenv, ret, "mkdir_log"); - return (EXIT_FAILURE); - } - if (mkdir(dirname, 0755) != 0) { - dbenv->err(dbenv, errno, "mkdir"); - return (EXIT_FAILURE); - } - - printf("Verify the directory's presence: "); - verify_presence(dbenv, dirname); - printf("check.\n"); - - /* Now abort the transaction and verify that the directory goes away. */ - printf("Commit the transaction.\n"); - if ((ret = txn->commit(txn, 0)) != 0) { - dbenv->err(dbenv, ret, "txn_commit"); - return (EXIT_FAILURE); - } - - printf("Verify the directory's presence: "); - verify_presence(dbenv, dirname); - printf("check.\n"); - - printf("Now remove the directory, then run recovery.\n"); - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret)); - return (EXIT_FAILURE); - } - if (rmdir(dirname) != 0) { - fprintf(stderr, - "%s: rmdir failed with error %s", progname, - strerror(errno)); - } - verify_absence(dbenv, dirname); - - /* Opening with DB_RECOVER runs recovery. */ - if ((ret = open_env(home, stderr, progname, &dbenv)) != 0) - return (EXIT_FAILURE); - - printf("Verify the directory's presence: "); - verify_presence(dbenv, dirname); - printf("check.\n"); - - /* Close the handle. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret)); - return (EXIT_FAILURE); - } - - return (EXIT_SUCCESS); -} - -int -open_env(home, errfp, progname, dbenvp) - const char *home, *progname; - FILE *errfp; - DB_ENV **dbenvp; -{ - DB_ENV *dbenv; - int ret; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(errfp, "%s: %s\n", progname, db_strerror(ret)); - return (ret); - } - dbenv->set_errfile(dbenv, errfp); - dbenv->set_errpfx(dbenv, progname); - - /* Set up our custom recovery dispatch function. */ - if ((ret = dbenv->set_app_dispatch(dbenv, apprec_dispatch)) != 0) { - dbenv->err(dbenv, ret, "set_app_dispatch"); - return (ret); - } - - /* - * Open the environment with full transactional support, running - * recovery. - */ - if ((ret = - dbenv->open(dbenv, home, DB_CREATE | DB_RECOVER | DB_INIT_LOCK | - DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0)) != 0) { - dbenv->err(dbenv, ret, "environment open: %s", home); - dbenv->close(dbenv, 0); - return (ret); - } - - *dbenvp = dbenv; - return (0); -} - -/* - * Sample application dispatch function to handle user-specified log record - * types. - */ -int -apprec_dispatch(dbenv, dbt, lsn, op) - DB_ENV *dbenv; - DBT *dbt; - DB_LSN *lsn; - db_recops op; -{ - u_int32_t rectype; - - /* Pull the record type out of the log record. */ - memcpy(&rectype, dbt->data, sizeof(rectype)); - - switch (rectype) { - case DB_ex_apprec_mkdir: - return (ex_apprec_mkdir_recover(dbenv, dbt, lsn, op, NULL)); - default: - /* - * We've hit an unexpected, allegedly user-defined record - * type. - */ - dbenv->errx(dbenv, "Unexpected log record type encountered"); - return (EINVAL); - } -} - -int -verify_absence(dbenv, dirname) - DB_ENV *dbenv; - const char *dirname; -{ - - if (access(dirname, F_OK) == 0) { - dbenv->errx(dbenv, "Error--directory present!"); - exit(EXIT_FAILURE); - } - - return (0); -} - -int -verify_presence(dbenv, dirname) - DB_ENV *dbenv; - const char *dirname; -{ - - if (access(dirname, F_OK) != 0) { - dbenv->errx(dbenv, "Error--directory not present!"); - exit(EXIT_FAILURE); - } - - return (0); -} diff --git a/bdb/examples_c/ex_apprec/ex_apprec.h b/bdb/examples_c/ex_apprec/ex_apprec.h deleted file mode 100644 index 9bbb567d4a6..00000000000 --- a/bdb/examples_c/ex_apprec/ex_apprec.h +++ /dev/null @@ -1,24 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_apprec.h,v 1.2 2002/08/08 15:47:00 bostic Exp $ - */ - -#ifndef _EX_APPREC_H_ -#define _EX_APPREC_H_ - -#include "ex_apprec_auto.h" - -int ex_apprec_mkdir_log - __P((DB_ENV *, DB_TXN *, DB_LSN *, u_int32_t, const DBT *)); -int ex_apprec_mkdir_print - __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); -int ex_apprec_mkdir_read - __P((DB_ENV *, void *, ex_apprec_mkdir_args **)); -int ex_apprec_mkdir_recover - __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - -#endif /* !_EX_APPREC_H_ */ diff --git a/bdb/examples_c/ex_apprec/ex_apprec.src b/bdb/examples_c/ex_apprec/ex_apprec.src deleted file mode 100644 index b048c504927..00000000000 --- a/bdb/examples_c/ex_apprec/ex_apprec.src +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_apprec.src,v 1.3 2002/08/08 15:47:00 bostic Exp $ - */ - -PREFIX ex_apprec - -/* - * This is the source file used to generate the application-specific recovery - * functions used by the ex_apprec example. It should be turned into usable - * source code (including a template for the recovery function itself) by - * invoking changing to the dist directory of the DB distribution and - * running the gen_rec.awk script there as follows: - * - * awk -f ./gen_rec.awk \ - * -v source_file=../examples_c/ex_apprec/ex_apprec_auto.c \ - * -v header_file=../examples_c/ex_apprec/ex_apprec_auto.h \ - * -v template_file=../examples_c/ex_apprec/ex_apprec_template \ - * < ../examples_c/ex_apprec/ex_apprec.src - -INCLUDE #include <ctype.h> -INCLUDE #include <errno.h> -INCLUDE #include <stdlib.h> -INCLUDE #include <string.h> -INCLUDE -INCLUDE #include <db.h> -INCLUDE -INCLUDE #include "ex_apprec.h" - -/* - * mkdir: used to create a directory - * - * dirname: relative or absolute pathname of the directory to be created - */ -BEGIN mkdir 10000 -DBT dirname DBT s -END diff --git a/bdb/examples_c/ex_apprec/ex_apprec_rec.c b/bdb/examples_c/ex_apprec/ex_apprec_rec.c deleted file mode 100644 index 8b6056d73f1..00000000000 --- a/bdb/examples_c/ex_apprec/ex_apprec_rec.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_apprec_rec.c,v 1.2 2002/08/06 05:39:02 bostic Exp $ - */ - -/* - * This file is based on the template file ex_apprec_template. Note that - * because ex_apprec_mkdir, like most application-specific recovery functions, - * does not make use of DB-private structures, it has actually been simplified - * significantly. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_apprec.h" - -/* - * ex_apprec_mkdir_recover -- - * Recovery function for mkdir. - * - * PUBLIC: int ex_apprec_mkdir_recover - * PUBLIC: __P((DB_ENV *, DBT *, DB_LSN *, db_recops, void *)); - */ -int -ex_apprec_mkdir_recover(dbenv, dbtp, lsnp, op, info) - DB_ENV *dbenv; - DBT *dbtp; - DB_LSN *lsnp; - db_recops op; - void *info; -{ - ex_apprec_mkdir_args *argp; - int ret; - - argp = NULL; - - /* - * Shut up the compiler--"info" is used for the recovery functions - * belonging to transaction meta-operations such as txn_create, and - * need not concern us here either. - */ - info = NULL; - - if ((ret = ex_apprec_mkdir_read(dbenv, dbtp->data, &argp)) != 0) - goto out; - - switch (op) { - case DB_TXN_ABORT: - case DB_TXN_BACKWARD_ROLL: - /* - * If we're aborting, we need to remove the directory if it - * exists. We log the trailing zero in pathnames, so we can - * simply pass the data part of the DBT into rmdir as a string. - * (Note that we don't have any alignment guarantees, but for - * a char * this doesn't matter.) - * - * Ignore all errors other than ENOENT; DB may attempt to undo - * or redo operations without knowing whether they have already - * been done or undone, so we should never assume in a recovery - * function that the task definitely needs doing or undoing. - */ - ret = rmdir(argp->dirname.data); - if (ret != 0 && errno != ENOENT) - dbenv->err(dbenv, ret, "Error in abort of mkdir"); - else - ret = 0; - break; - case DB_TXN_FORWARD_ROLL: - /* - * The forward direction is just the opposite; here, we ignore - * EEXIST, because the directory may already exist. - */ - ret = mkdir(argp->dirname.data, 0755); - if (ret != 0 && errno != EEXIST) - dbenv->err(dbenv, - ret, "Error in roll-forward of mkdir"); - else - ret = 0; - break; - default: - /* - * We might want to handle DB_TXN_PRINT or DB_TXN_APPLY here, - * too, but we don't try to print the log records and aren't - * using replication, so there's no need to in this example. - */ - dbenv->errx(dbenv, "Unexpected operation type\n"); - return (EINVAL); - } - - /* - * The recovery function is responsible for returning the LSN of the - * previous log record in this transaction, so that transaction aborts - * can follow the chain backwards. - * - * (If we'd wanted the LSN of this record earlier, we could have - * read it from lsnp, as well--but because we weren't working with - * pages or other objects that store their LSN and base recovery - * decisions on it, we didn't need to.) - */ - *lsnp = argp->prev_lsn; - -out: if (argp != NULL) - free(argp); - return (ret); -} diff --git a/bdb/examples_c/ex_btrec.c b/bdb/examples_c/ex_btrec.c deleted file mode 100644 index 8e4aa3901d1..00000000000 --- a/bdb/examples_c/ex_btrec.c +++ /dev/null @@ -1,203 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_btrec.c,v 11.18 2002/01/23 15:33:18 bostic Exp $ - */ - -#include <sys/types.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <db.h> - -#define DATABASE "access.db" -#define WORDLIST "../test/wordlist" -int main __P((void)); - -int ex_btrec __P((void)); -void show __P((const char *, DBT *, DBT *)); - -int -main() -{ - return (ex_btrec() == 1 ? EXIT_FAILURE : EXIT_SUCCESS); -} - -int -ex_btrec() -{ - DB *dbp; - DBC *dbcp; - DBT key, data; - DB_BTREE_STAT *statp; - FILE *fp; - db_recno_t recno; - u_int32_t len; - int cnt, ret; - char *p, *t, buf[1024], rbuf[1024]; - const char *progname = "ex_btrec"; /* Program name. */ - - /* Open the word database. */ - if ((fp = fopen(WORDLIST, "r")) == NULL) { - fprintf(stderr, "%s: open %s: %s\n", - progname, WORDLIST, db_strerror(errno)); - return (1); - } - - /* Remove the previous database. */ - (void)remove(DATABASE); - - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&dbp, NULL, 0)) != 0) { - fprintf(stderr, - "%s: db_create: %s\n", progname, db_strerror(ret)); - return (1); - } - dbp->set_errfile(dbp, stderr); - dbp->set_errpfx(dbp, progname); /* 1K page sizes. */ - if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) { - dbp->err(dbp, ret, "set_pagesize"); - return (1); - } /* Record numbers. */ - if ((ret = dbp->set_flags(dbp, DB_RECNUM)) != 0) { - dbp->err(dbp, ret, "set_flags: DB_RECNUM"); - return (1); - } - if ((ret = dbp->open(dbp, - NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { - dbp->err(dbp, ret, "open: %s", DATABASE); - return (1); - } - - /* - * Insert records into the database, where the key is the word - * preceded by its record number, and the data is the same, but - * in reverse order. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - for (cnt = 1; cnt <= 1000; ++cnt) { - (void)sprintf(buf, "%04d_", cnt); - if (fgets(buf + 4, sizeof(buf) - 4, fp) == NULL) - break; - len = strlen(buf); - for (t = rbuf, p = buf + (len - 2); p >= buf;) - *t++ = *p--; - *t++ = '\0'; - - key.data = buf; - data.data = rbuf; - data.size = key.size = len - 1; - - if ((ret = - dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) != 0) { - dbp->err(dbp, ret, "DB->put"); - if (ret != DB_KEYEXIST) - goto err1; - } - } - - /* Close the word database. */ - (void)fclose(fp); - - /* Print out the number of records in the database. */ - if ((ret = dbp->stat(dbp, &statp, 0)) != 0) { - dbp->err(dbp, ret, "DB->stat"); - goto err1; - } - printf("%s: database contains %lu records\n", - progname, (u_long)statp->bt_ndata); - free(statp); - - /* Acquire a cursor for the database. */ - if ((ret = dbp->cursor(dbp, NULL, &dbcp, 0)) != 0) { - dbp->err(dbp, ret, "DB->cursor"); - goto err1; - } - - /* - * Prompt the user for a record number, then retrieve and display - * that record. - */ - for (;;) { - /* Get a record number. */ - printf("recno #> "); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - recno = atoi(buf); - - /* - * Reset the key each time, the dbp->c_get() routine returns - * the key and data pair, not just the key! - */ - key.data = &recno; - key.size = sizeof(recno); - if ((ret = dbcp->c_get(dbcp, &key, &data, DB_SET_RECNO)) != 0) - goto get_err; - - /* Display the key and data. */ - show("k/d\t", &key, &data); - - /* Move the cursor a record forward. */ - if ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) != 0) - goto get_err; - - /* Display the key and data. */ - show("next\t", &key, &data); - - /* - * Retrieve the record number for the following record into - * local memory. - */ - data.data = &recno; - data.size = sizeof(recno); - data.ulen = sizeof(recno); - data.flags |= DB_DBT_USERMEM; - if ((ret = dbcp->c_get(dbcp, &key, &data, DB_GET_RECNO)) != 0) { -get_err: dbp->err(dbp, ret, "DBcursor->get"); - if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) - goto err2; - } else - printf("retrieved recno: %lu\n", (u_long)recno); - - /* Reset the data DBT. */ - memset(&data, 0, sizeof(data)); - } - - if ((ret = dbcp->c_close(dbcp)) != 0) { - dbp->err(dbp, ret, "DBcursor->close"); - goto err1; - } - if ((ret = dbp->close(dbp, 0)) != 0) { - fprintf(stderr, - "%s: DB->close: %s\n", progname, db_strerror(ret)); - return (1); - } - - return (0); - -err2: (void)dbcp->c_close(dbcp); -err1: (void)dbp->close(dbp, 0); - return (ret); - -} - -/* - * show -- - * Display a key/data pair. - */ -void -show(msg, key, data) - const char *msg; - DBT *key, *data; -{ - printf("%s%.*s : %.*s\n", msg, - (int)key->size, (char *)key->data, - (int)data->size, (char *)data->data); -} diff --git a/bdb/examples_c/ex_dbclient.c b/bdb/examples_c/ex_dbclient.c deleted file mode 100644 index 5baa640811f..00000000000 --- a/bdb/examples_c/ex_dbclient.c +++ /dev/null @@ -1,226 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_dbclient.c,v 1.28 2002/08/06 06:11:24 bostic Exp $ - */ - -#include <sys/types.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#define DATABASE_HOME "database" - -#define DATABASE "access.db" - -int db_clientrun __P((DB_ENV *, const char *)); -int ex_dbclient_run __P((const char *, FILE *, const char *, const char *)); -int main __P((int, char *[])); - -/* - * An example of a program creating/configuring a Berkeley DB environment. - */ -int -main(argc, argv) - int argc; - char *argv[]; -{ - const char *home; - - if (argc != 2) { - fprintf(stderr, "Usage: %s hostname\n", argv[0]); - return (EXIT_FAILURE); - } - - /* - * All of the shared database files live in DATABASE_HOME, but - * data files will live in CONFIG_DATA_DIR. - */ - home = DATABASE_HOME; - return (ex_dbclient_run(home, - stderr, argv[1], argv[0]) == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -ex_dbclient(host) - const char *host; -{ - const char *home; - const char *progname = "ex_dbclient"; /* Program name. */ - int ret; - - /* - * All of the shared database files live in DATABASE_HOME, but - * data files will live in CONFIG_DATA_DIR. - */ - home = DATABASE_HOME; - - if ((ret = ex_dbclient_run(home, stderr, host, progname)) != 0) - return (ret); - - return (0); -} - -int -ex_dbclient_run(home, errfp, host, progname) - const char *home, *host, *progname; - FILE *errfp; -{ - DB_ENV *dbenv; - int ret, retry; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, DB_CLIENT)) != 0) { - fprintf(errfp, "%s: %s\n", progname, db_strerror(ret)); - return (1); - } - retry = 0; -retry: - while (retry < 5) { - /* - * Set the server host we are talking to. - */ - if ((ret = dbenv->set_rpc_server(dbenv, NULL, host, 10000, - 10000, 0)) != 0) { - fprintf(stderr, "Try %d: DB_ENV->set_rpc_server: %s\n", - retry, db_strerror(ret)); - retry++; - sleep(15); - } else - break; - } - - if (retry >= 5) { - fprintf(stderr, - "DB_ENV->set_rpc_server: %s\n", db_strerror(ret)); - dbenv->close(dbenv, 0); - return (1); - } - /* - * We want to specify the shared memory buffer pool cachesize, - * but everything else is the default. - */ - if ((ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - dbenv->close(dbenv, 0); - return (1); - } - /* - * We have multiple processes reading/writing these files, so - * we need concurrency control and a shared buffer pool, but - * not logging or transactions. - */ - if ((ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_LOCK | DB_INIT_MPOOL, 0)) != 0) { - dbenv->err(dbenv, ret, "environment open: %s", home); - dbenv->close(dbenv, 0); - if (ret == DB_NOSERVER) - goto retry; - return (1); - } - - ret = db_clientrun(dbenv, progname); - printf("db_clientrun returned %d\n", ret); - if (ret == DB_NOSERVER) - goto retry; - - /* Close the handle. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret)); - return (1); - } - return (0); -} - -int -db_clientrun(dbenv, progname) - DB_ENV *dbenv; - const char *progname; -{ - DB *dbp; - DBT key, data; - u_int32_t len; - int ret; - char *p, *t, buf[1024], rbuf[1024]; - - /* Remove the previous database. */ - - /* Create and initialize database object, open the database. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_create: %s\n", progname, db_strerror(ret)); - return (ret); - } - if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) { - dbp->err(dbp, ret, "set_pagesize"); - goto err1; - } - if ((ret = dbp->open(dbp, - NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0664)) != 0) { - dbp->err(dbp, ret, "%s: open", DATABASE); - goto err1; - } - - /* - * Insert records into the database, where the key is the user - * input and the data is the user input in reverse order. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - for (;;) { - printf("input> "); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - if ((len = strlen(buf)) <= 1) - continue; - for (t = rbuf, p = buf + (len - 2); p >= buf;) - *t++ = *p--; - *t++ = '\0'; - - key.data = buf; - data.data = rbuf; - data.size = key.size = len - 1; - - switch (ret = - dbp->put(dbp, NULL, &key, &data, DB_NOOVERWRITE)) { - case 0: - break; - default: - dbp->err(dbp, ret, "DB->put"); - if (ret != DB_KEYEXIST) - goto err1; - break; - } - memset(&data, 0, sizeof(DBT)); - switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) { - case 0: - printf("%.*s : %.*s\n", - (int)key.size, (char *)key.data, - (int)data.size, (char *)data.data); - break; - default: - dbp->err(dbp, ret, "DB->get"); - break; - } - } - if ((ret = dbp->close(dbp, 0)) != 0) { - fprintf(stderr, - "%s: DB->close: %s\n", progname, db_strerror(ret)); - return (1); - } - return (0); - -err1: (void)dbp->close(dbp, 0); - return (ret); -} diff --git a/bdb/examples_c/ex_env.c b/bdb/examples_c/ex_env.c deleted file mode 100644 index 32257effb7b..00000000000 --- a/bdb/examples_c/ex_env.c +++ /dev/null @@ -1,135 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_env.c,v 11.27 2002/08/15 14:34:11 bostic Exp $ - */ - -#include <sys/types.h> - -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> - -#include <db.h> - -#ifdef macintosh -#define DATABASE_HOME ":database" -#define CONFIG_DATA_DIR ":database" -#else -#ifdef DB_WIN32 -#define DATABASE_HOME "\\tmp\\database" -#define CONFIG_DATA_DIR "\\database\\files" -#else -#define DATABASE_HOME "/tmp/database" -#define CONFIG_DATA_DIR "/database/files" -#endif -#endif - -int db_setup __P((const char *, const char *, FILE *, const char *)); -int db_teardown __P((const char *, const char *, FILE *, const char *)); -int main __P((void)); - -/* - * An example of a program creating/configuring a Berkeley DB environment. - */ -int -main() -{ - const char *data_dir, *home; - const char *progname = "ex_env"; /* Program name. */ - - /* - * All of the shared database files live in DATABASE_HOME, but - * data files will live in CONFIG_DATA_DIR. - */ - home = DATABASE_HOME; - data_dir = CONFIG_DATA_DIR; - - printf("Setup env\n"); - if (db_setup(home, data_dir, stderr, progname) != 0) - return (EXIT_FAILURE); - - printf("Teardown env\n"); - if (db_teardown(home, data_dir, stderr, progname) != 0) - return (EXIT_FAILURE); - - return (EXIT_SUCCESS); -} - -int -db_setup(home, data_dir, errfp, progname) - const char *home, *data_dir, *progname; - FILE *errfp; -{ - DB_ENV *dbenv; - int ret; - - /* - * Create an environment object and initialize it for error - * reporting. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(errfp, "%s: %s\n", progname, db_strerror(ret)); - return (1); - } - dbenv->set_errfile(dbenv, errfp); - dbenv->set_errpfx(dbenv, progname); - - /* - * We want to specify the shared memory buffer pool cachesize, - * but everything else is the default. - */ - if ((ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - dbenv->close(dbenv, 0); - return (1); - } - - /* Databases are in a subdirectory. */ - (void)dbenv->set_data_dir(dbenv, data_dir); - - /* Open the environment with full transactional support. */ - if ((ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, - 0)) != 0) { - dbenv->err(dbenv, ret, "environment open: %s", home); - dbenv->close(dbenv, 0); - return (1); - } - - /* Do something interesting... */ - - /* Close the handle. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret)); - return (1); - } - return (0); -} - -int -db_teardown(home, data_dir, errfp, progname) - const char *home, *data_dir, *progname; - FILE *errfp; -{ - DB_ENV *dbenv; - int ret; - - /* Remove the shared database regions. */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(errfp, "%s: %s\n", progname, db_strerror(ret)); - return (1); - } - dbenv->set_errfile(dbenv, errfp); - dbenv->set_errpfx(dbenv, progname); - - (void)dbenv->set_data_dir(dbenv, data_dir); - if ((ret = dbenv->remove(dbenv, home, 0)) != 0) { - fprintf(stderr, "DB_ENV->remove: %s\n", db_strerror(ret)); - return (1); - } - return (0); -} diff --git a/bdb/examples_c/ex_lock.c b/bdb/examples_c/ex_lock.c deleted file mode 100644 index 21a3584ceea..00000000000 --- a/bdb/examples_c/ex_lock.c +++ /dev/null @@ -1,239 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_lock.c,v 11.18 2002/04/10 21:48:20 bostic Exp $ - */ - -#include <sys/types.h> - -#include <stdlib.h> -#include <string.h> - -#ifdef _WIN32 -extern int getopt(int, char * const *, const char *); -#else -#include <unistd.h> -#endif - -#include <db.h> - -int db_init __P((const char *, u_int32_t, int)); -int main __P((int, char *[])); -int usage __P((void)); - -DB_ENV *dbenv; -const char - *progname = "ex_lock"; /* Program name. */ - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DBT lock_dbt; - DB_LOCK lock; - DB_LOCK *locks; - db_lockmode_t lock_type; - long held; - u_int32_t len, locker, maxlocks; - int ch, do_unlink, did_get, i, lockid, lockcount, ret; - const char *home; - char opbuf[16], objbuf[1024], lockbuf[16]; - - home = "TESTDIR"; - maxlocks = 0; - do_unlink = 0; - while ((ch = getopt(argc, argv, "h:m:u")) != EOF) - switch (ch) { - case 'h': - home = optarg; - break; - case 'm': - if ((i = atoi(optarg)) <= 0) - return (usage()); - maxlocks = (u_int32_t)i; /* XXX: possible overflow. */ - break; - case 'u': - do_unlink = 1; - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - if (argc != 0) - return (usage()); - - /* Initialize the database environment. */ - if ((ret = db_init(home, maxlocks, do_unlink)) != 0) - return (ret); - - locks = 0; - lockcount = 0; - - /* - * Accept lock requests. - */ - if ((ret = dbenv->lock_id(dbenv, &locker)) != 0) { - dbenv->err(dbenv, ret, "unable to get locker id"); - (void)dbenv->close(dbenv, 0); - return (EXIT_FAILURE); - } - lockid = -1; - - memset(&lock_dbt, 0, sizeof(lock_dbt)); - for (held = 0, did_get = 0;;) { - printf("Operation get/release [get]> "); - fflush(stdout); - if (fgets(opbuf, sizeof(opbuf), stdin) == NULL) - break; - if ((len = strlen(opbuf)) <= 1 || strcmp(opbuf, "get\n") == 0) { - /* Acquire a lock. */ - printf("input object (text string) to lock> "); - fflush(stdout); - if (fgets(objbuf, sizeof(objbuf), stdin) == NULL) - break; - if ((len = strlen(objbuf)) <= 1) - continue; - - do { - printf("lock type read/write [read]> "); - fflush(stdout); - if (fgets(lockbuf, - sizeof(lockbuf), stdin) == NULL) - break; - len = strlen(lockbuf); - } while (len > 1 && - strcmp(lockbuf, "read\n") != 0 && - strcmp(lockbuf, "write\n") != 0); - if (len == 1 || strcmp(lockbuf, "read\n") == 0) - lock_type = DB_LOCK_READ; - else - lock_type = DB_LOCK_WRITE; - - lock_dbt.data = objbuf; - lock_dbt.size = strlen(objbuf); - ret = dbenv->lock_get(dbenv, locker, - DB_LOCK_NOWAIT, &lock_dbt, lock_type, &lock); - if (ret == 0) { - did_get = 1; - lockid = lockcount++; - if (locks == NULL) - locks = - (DB_LOCK *)malloc(sizeof(DB_LOCK)); - else - locks = (DB_LOCK *)realloc(locks, - lockcount * sizeof(DB_LOCK)); - locks[lockid] = lock; - } - } else { - /* Release a lock. */ - do { - printf("input lock to release> "); - fflush(stdout); - if (fgets(objbuf, - sizeof(objbuf), stdin) == NULL) - break; - } while ((len = strlen(objbuf)) <= 1); - lockid = strtol(objbuf, NULL, 16); - if (lockid < 0 || lockid >= lockcount) { - printf("Lock #%d out of range\n", lockid); - continue; - } - lock = locks[lockid]; - ret = dbenv->lock_put(dbenv, &lock); - did_get = 0; - } - switch (ret) { - case 0: - printf("Lock #%d %s\n", lockid, - did_get ? "granted" : "released"); - held += did_get ? 1 : -1; - break; - case DB_LOCK_NOTGRANTED: - dbenv->err(dbenv, ret, NULL); - break; - case DB_LOCK_DEADLOCK: - dbenv->err(dbenv, ret, - "lock_%s", did_get ? "get" : "put"); - break; - default: - dbenv->err(dbenv, ret, - "lock_%s", did_get ? "get" : "put"); - (void)dbenv->close(dbenv, 0); - return (EXIT_FAILURE); - } - } - - printf("\nClosing lock region %ld locks held\n", held); - - if (locks != NULL) - free(locks); - - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, - "%s: dbenv->close: %s\n", progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - return (EXIT_SUCCESS); -} - -/* - * db_init -- - * Initialize the environment. - */ -int -db_init(home, maxlocks, do_unlink) - const char *home; - u_int32_t maxlocks; - int do_unlink; -{ - int ret; - - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, "%s: db_env_create: %s\n", - progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - - if (do_unlink) { - if ((ret = dbenv->remove(dbenv, home, DB_FORCE)) != 0) { - fprintf(stderr, "%s: dbenv->remove: %s\n", - progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, "%s: db_env_create: %s\n", - progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - if (maxlocks != 0) - dbenv->set_lk_max_locks(dbenv, maxlocks); - - if ((ret = - dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOCK, 0)) != 0) { - dbenv->err(dbenv, ret, NULL); - (void)dbenv->close(dbenv, 0); - return (EXIT_FAILURE); - } - return (0); -} - -int -usage() -{ - (void)fprintf(stderr, - "usage: %s [-u] [-h home] [-m maxlocks]\n", progname); - return (EXIT_FAILURE); -} diff --git a/bdb/examples_c/ex_mpool.c b/bdb/examples_c/ex_mpool.c deleted file mode 100644 index 280adc48910..00000000000 --- a/bdb/examples_c/ex_mpool.c +++ /dev/null @@ -1,253 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_mpool.c,v 11.26 2002/08/15 14:34:56 bostic Exp $ - */ - -#include <sys/types.h> - -#include <errno.h> -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef _WIN32 -extern int getopt(int, char * const *, const char *); -#else -#include <unistd.h> -#endif - -#include <db.h> - -int init __P((const char *, int, int, const char *)); -int run __P((int, int, int, int, const char *)); -int run_mpool __P((int, int, int, int, const char *)); -int main __P((int, char *[])); -int usage __P((const char *)); -#define MPOOL "mpool" /* File. */ - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - int cachesize, ch, hits, npages, pagesize; - char *progname; - - cachesize = 20 * 1024; - hits = 1000; - npages = 50; - pagesize = 1024; - progname = argv[0]; - while ((ch = getopt(argc, argv, "c:h:n:p:")) != EOF) - switch (ch) { - case 'c': - if ((cachesize = atoi(optarg)) < 20 * 1024) - return (usage(progname)); - break; - case 'h': - if ((hits = atoi(optarg)) <= 0) - return (usage(progname)); - break; - case 'n': - if ((npages = atoi(optarg)) <= 0) - return (usage(progname)); - break; - case 'p': - if ((pagesize = atoi(optarg)) <= 0) - return (usage(progname)); - break; - case '?': - default: - return (usage(progname)); - } - argc -= optind; - argv += optind; - - return (run_mpool(pagesize, cachesize, - hits, npages, progname) == 0 ? EXIT_SUCCESS : EXIT_FAILURE); -} - -int -usage(progname) - const char *progname; -{ - (void)fprintf(stderr, - "usage: %s [-c cachesize] [-h hits] [-n npages] [-p pagesize]\n", - progname); - return (EXIT_FAILURE); -} - -int -run_mpool(pagesize, cachesize, hits, npages, progname) - int pagesize, cachesize, hits, npages; - const char *progname; -{ - int ret; - - /* Initialize the file. */ - if ((ret = init(MPOOL, pagesize, npages, progname)) != 0) - return (ret); - - /* Get the pages. */ - if ((ret = run(hits, cachesize, pagesize, npages, progname)) != 0) - return (ret); - - return (0); -} - -/* - * init -- - * Create a backing file. - */ -int -init(file, pagesize, npages, progname) - const char *file, *progname; - int pagesize, npages; -{ - FILE *fp; - int cnt; - char *p; - - /* - * Create a file with the right number of pages, and store a page - * number on each page. - */ - if ((fp = fopen(file, "wb")) == NULL) { - fprintf(stderr, - "%s: %s: %s\n", progname, file, strerror(errno)); - return (1); - } - if ((p = (char *)malloc(pagesize)) == NULL) { - fprintf(stderr, "%s: %s\n", progname, strerror(ENOMEM)); - return (1); - } - - /* The pages are numbered from 0. */ - for (cnt = 0; cnt <= npages; ++cnt) { - *(int *)p = cnt; - if (fwrite(p, pagesize, 1, fp) != 1) { - fprintf(stderr, - "%s: %s: %s\n", progname, file, strerror(errno)); - return (1); - } - } - - (void)fclose(fp); - free(p); - return (0); -} - -/* - * run -- - * Get a set of pages. - */ -int -run(hits, cachesize, pagesize, npages, progname) - int hits, cachesize, pagesize, npages; - const char *progname; -{ - DB_ENV *dbenv; - DB_MPOOLFILE *mfp; - db_pgno_t pageno; - int cnt, ret; - void *p; - - dbenv = NULL; - mfp = NULL; - - printf("%s: cachesize: %d; pagesize: %d; N pages: %d\n", - progname, cachesize, pagesize, npages); - - /* - * Open a memory pool, specify a cachesize, output error messages - * to stderr. - */ - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - return (1); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); -#ifdef HAVE_VXWORKS - if ((ret = dbenv->set_shm_key(dbenv, VXSHM_KEY)) != 0) { - dbenv->err(dbenv, ret, "set_shm_key"); - return (1); - } -#endif - - /* Set the cachesize. */ - if ((ret = dbenv->set_cachesize(dbenv, 0, cachesize, 0)) != 0) { - dbenv->err(dbenv, ret, "set_cachesize"); - goto err; - } - - /* Open the environment. */ - if ((ret = dbenv->open( - dbenv, NULL, DB_CREATE | DB_INIT_MPOOL, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open"); - goto err; - } - - /* Open the file in the environment. */ - if ((ret = dbenv->memp_fcreate(dbenv, &mfp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->memp_fcreate: %s", MPOOL); - goto err; - } - if ((ret = mfp->open(mfp, MPOOL, 0, 0, pagesize)) != 0) { - dbenv->err(dbenv, ret, "DB_MPOOLFILE->open: %s", MPOOL); - goto err; - } - - printf("retrieve %d random pages... ", hits); - - srand((u_int)time(NULL)); - for (cnt = 0; cnt < hits; ++cnt) { - pageno = (rand() % npages) + 1; - if ((ret = mfp->get(mfp, &pageno, 0, &p)) != 0) { - dbenv->err(dbenv, ret, - "unable to retrieve page %lu", (u_long)pageno); - goto err; - } - if (*(db_pgno_t *)p != pageno) { - dbenv->errx(dbenv, - "wrong page retrieved (%lu != %d)", - (u_long)pageno, *(int *)p); - goto err; - } - if ((ret = mfp->put(mfp, p, 0)) != 0) { - dbenv->err(dbenv, ret, - "unable to return page %lu", (u_long)pageno); - goto err; - } - } - - printf("successful.\n"); - - /* Close the file. */ - if ((ret = mfp->close(mfp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_MPOOLFILE->close"); - goto err; - } - - /* Close the pool. */ - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - return (1); - } - return (0); - -err: if (mfp != NULL) - (void)mfp->close(mfp, 0); - if (dbenv != NULL) - (void)dbenv->close(dbenv, 0); - return (1); -} diff --git a/bdb/examples_c/ex_repquote/ex_repquote.h b/bdb/examples_c/ex_repquote/ex_repquote.h deleted file mode 100644 index 74a0860e050..00000000000 --- a/bdb/examples_c/ex_repquote/ex_repquote.h +++ /dev/null @@ -1,69 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_repquote.h,v 1.27 2002/04/23 04:27:50 krinsky Exp $ - */ - -#ifndef _EX_REPQUOTE_H_ -#define _EX_REPQUOTE_H_ - -#define SELF_EID 1 - -typedef struct { - char *host; /* Host name. */ - u_int32_t port; /* Port on which to connect to this site. */ -} repsite_t; - -/* Globals */ -extern int master_eid; -extern char *myaddr; - -struct __member; typedef struct __member member_t; -struct __machtab; typedef struct __machtab machtab_t; - -/* Arguments for the connect_all thread. */ -typedef struct { - DB_ENV *dbenv; - const char *progname; - const char *home; - machtab_t *machtab; - repsite_t *sites; - int nsites; -} all_args; - -/* Arguments for the connect_loop thread. */ -typedef struct { - DB_ENV *dbenv; - const char * home; - const char * progname; - machtab_t *machtab; - int port; -} connect_args; - -#define CACHESIZE (10 * 1024 * 1024) -#define DATABASE "quote.db" -#define SLEEPTIME 3 - -void *connect_all __P((void *args)); -void *connect_thread __P((void *args)); -int doclient __P((DB_ENV *, const char *, machtab_t *)); -int domaster __P((DB_ENV *, const char *)); -int get_accepted_socket __P((const char *, int)); -int get_connected_socket __P((machtab_t *, const char *, const char *, int, int *, int *)); -int get_next_message __P((int, DBT *, DBT *)); -int listen_socket_init __P((const char *, int)); -int listen_socket_accept __P((machtab_t *, const char *, int, int *)); -int machtab_getinfo __P((machtab_t *, int, u_int32_t *, int *)); -int machtab_init __P((machtab_t **, int, int)); -void machtab_parm __P((machtab_t *, int *, int *, u_int32_t *)); -int machtab_rem __P((machtab_t *, int, int)); -int quote_send __P((DB_ENV *, const DBT *, const DBT *, int, u_int32_t)); - -#ifndef COMPQUIET -#define COMPQUIET(x,y) x = (y) -#endif - -#endif /* !_EX_REPQUOTE_H_ */ diff --git a/bdb/examples_c/ex_repquote/ex_rq_client.c b/bdb/examples_c/ex_repquote/ex_rq_client.c deleted file mode 100644 index d382fe84fc7..00000000000 --- a/bdb/examples_c/ex_repquote/ex_rq_client.c +++ /dev/null @@ -1,250 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_rq_client.c,v 1.29 2002/01/23 15:33:19 bostic Exp $ - */ - -#include <sys/types.h> -#include <sys/wait.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_repquote.h" - -static void *check_loop __P((void *)); -static void *display_loop __P((void *)); -static int print_stocks __P((DBC *)); - -typedef struct { - const char *progname; - DB_ENV *dbenv; -} disploop_args; - -typedef struct { - DB_ENV *dbenv; - machtab_t *machtab; -} checkloop_args; - -int -doclient(dbenv, progname, machtab) - DB_ENV *dbenv; - const char *progname; - machtab_t *machtab; -{ - checkloop_args cargs; - disploop_args dargs; - pthread_t check_thr, disp_thr; - void *cstatus, *dstatus; - int rval, s; - - rval = EXIT_SUCCESS; - s = -1; - - memset(&dargs, 0, sizeof(dargs)); - dstatus = (void *)EXIT_FAILURE; - - dargs.progname = progname; - dargs.dbenv = dbenv; - if (pthread_create(&disp_thr, NULL, display_loop, (void *)&dargs)) { - dbenv->err(dbenv, errno, "display_loop pthread_create failed"); - goto err; - } - - cargs.dbenv = dbenv; - cargs.machtab = machtab; - if (pthread_create(&check_thr, NULL, check_loop, (void *)&cargs)) { - dbenv->err(dbenv, errno, "check_thread pthread_create failed"); - goto err; - } - if (pthread_join(disp_thr, &dstatus) || - pthread_join(check_thr, &cstatus)) { - dbenv->err(dbenv, errno, "pthread_join failed"); - goto err; - } - - if (0) { -err: rval = EXIT_FAILURE; - } - return (rval); -} - -/* - * Our only job is to check that the master is valid and if it's not - * for an extended period, to trigger an election. We do two phases. - * If we do not have a master, first we send out a request for a master - * to identify itself (that would be a call to rep_start). If that fails, - * we trigger an election. - */ -static void * -check_loop(args) - void *args; -{ - DB_ENV *dbenv; - DBT dbt; - checkloop_args *cargs; - int count, n, pri; - machtab_t *machtab; - u_int32_t timeout; - - cargs = (checkloop_args *)args; - dbenv = cargs->dbenv; - machtab = cargs->machtab; - -#define IDLE_INTERVAL 1 - - count = 0; - while (master_eid == DB_EID_INVALID) { - /* - * Call either rep_start or rep_elect depending on if - * count is 0 or 1. - */ - - if (count == 0) { - memset(&dbt, 0, sizeof(dbt)); - dbt.data = myaddr; - dbt.size = strlen(myaddr) + 1; - (void)dbenv->rep_start(dbenv, &dbt, DB_REP_CLIENT); - count = 1; - } else { - machtab_parm(machtab, &n, &pri, &timeout); - (void)dbenv->rep_elect(dbenv, - n, pri, timeout, &master_eid); - count = 0; - } - sleep(IDLE_INTERVAL); - } - - return ((void *)EXIT_SUCCESS); -} - -static void * -display_loop(args) - void *args; -{ - DB *dbp; - DB_ENV *dbenv; - DBC *dbc; - const char *progname; - disploop_args *dargs; - int ret, rval; - - dargs = (disploop_args *)args; - progname = dargs->progname; - dbenv = dargs->dbenv; - - dbc = NULL; - dbp = NULL; - - for (;;) { - /* If we become master, shut this loop off. */ - if (master_eid == SELF_EID) - break; - - if (dbp == NULL) { - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - return ((void *)EXIT_FAILURE); - } - - if ((ret = dbp->open(dbp, NULL, - DATABASE, NULL, DB_BTREE, DB_RDONLY, 0)) != 0) { - if (ret == ENOENT) { - printf( - "No stock database yet available.\n"); - if ((ret = dbp->close(dbp, 0)) != 0) { - dbenv->err(dbenv, - ret, "DB->close"); - goto err; - } - dbp = NULL; - sleep(SLEEPTIME); - continue; - } - dbenv->err(dbenv, ret, "DB->open"); - goto err; - } - } - - if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->cursor"); - goto err; - } - - if ((ret = print_stocks(dbc)) != 0) { - dbenv->err(dbenv, ret, "database traversal failed"); - goto err; - } - - if ((ret = dbc->c_close(dbc)) != 0) { - dbenv->err(dbenv, ret, "DB->close"); - goto err; - } - - dbc = NULL; - - sleep(SLEEPTIME); - } - - rval = EXIT_SUCCESS; - - if (0) { -err: rval = EXIT_FAILURE; - } - - if (dbc != NULL && (ret = dbc->c_close(dbc)) != 0) { - dbenv->err(dbenv, ret, "DB->close"); - rval = EXIT_FAILURE; - } - - if (dbp != NULL && (ret = dbp->close(dbp, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->close"); - return ((void *)EXIT_FAILURE); - } - - return ((void *)rval); -} - -static int -print_stocks(dbc) - DBC *dbc; -{ - DBT key, data; -#define MAXKEYSIZE 10 -#define MAXDATASIZE 20 - char keybuf[MAXKEYSIZE + 1], databuf[MAXDATASIZE + 1]; - int ret; - u_int32_t keysize, datasize; - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - - printf("\tSymbol\tPrice\n"); - printf("\t======\t=====\n"); - - for (ret = dbc->c_get(dbc, &key, &data, DB_FIRST); - ret == 0; - ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) { - keysize = key.size > MAXKEYSIZE ? MAXKEYSIZE : key.size; - memcpy(keybuf, key.data, keysize); - keybuf[keysize] = '\0'; - - datasize = data.size >= MAXDATASIZE ? MAXDATASIZE : data.size; - memcpy(databuf, data.data, datasize); - databuf[datasize] = '\0'; - - printf("\t%s\t%s\n", keybuf, databuf); - } - printf("\n"); - return (ret == DB_NOTFOUND ? 0 : ret); -} diff --git a/bdb/examples_c/ex_repquote/ex_rq_main.c b/bdb/examples_c/ex_repquote/ex_rq_main.c deleted file mode 100644 index 03819728679..00000000000 --- a/bdb/examples_c/ex_repquote/ex_rq_main.c +++ /dev/null @@ -1,303 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_rq_main.c,v 1.23 2002/08/06 05:39:03 bostic Exp $ - */ - -#include <sys/types.h> -#include <pthread.h> - -#include <errno.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_repquote.h" - -/* - * Process globals (we could put these in the machtab I suppose. - */ -int master_eid; -char *myaddr; - -static int env_init __P((const char *, const char *, DB_ENV **, machtab_t *, - u_int32_t)); -static void usage __P((const char *)); - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - DBT local; - enum { MASTER, CLIENT, UNKNOWN } whoami; - all_args aa; - connect_args ca; - machtab_t *machtab; - pthread_t all_thr, conn_thr; - repsite_t site, *sitep, self, *selfp; - struct sigaction sigact; - int maxsites, nsites, ret, priority, totalsites; - char *c, ch; - const char *home, *progname; - void *astatus, *cstatus; - - master_eid = DB_EID_INVALID; - - dbenv = NULL; - whoami = UNKNOWN; - machtab = NULL; - selfp = sitep = NULL; - maxsites = nsites = ret = totalsites = 0; - priority = 100; - home = "TESTDIR"; - progname = "ex_repquote"; - - while ((ch = getopt(argc, argv, "Ch:Mm:n:o:p:")) != EOF) - switch (ch) { - case 'M': - whoami = MASTER; - master_eid = SELF_EID; - break; - case 'C': - whoami = CLIENT; - break; - case 'h': - home = optarg; - break; - case 'm': - if ((myaddr = strdup(optarg)) == NULL) { - fprintf(stderr, - "System error %s\n", strerror(errno)); - goto err; - } - self.host = optarg; - self.host = strtok(self.host, ":"); - if ((c = strtok(NULL, ":")) == NULL) { - fprintf(stderr, "Bad host specification.\n"); - goto err; - } - self.port = atoi(c); - selfp = &self; - break; - case 'n': - totalsites = atoi(optarg); - break; - case 'o': - site.host = optarg; - site.host = strtok(site.host, ":"); - if ((c = strtok(NULL, ":")) == NULL) { - fprintf(stderr, "Bad host specification.\n"); - goto err; - } - site.port = atoi(c); - if (sitep == NULL || nsites >= maxsites) { - maxsites = maxsites == 0 ? 10 : 2 * maxsites; - if ((sitep = realloc(sitep, - maxsites * sizeof(repsite_t))) == NULL) { - fprintf(stderr, "System error %s\n", - strerror(errno)); - goto err; - } - } - sitep[nsites++] = site; - break; - case 'p': - priority = atoi(optarg); - break; - case '?': - default: - usage(progname); - } - - /* Error check command line. */ - if (whoami == UNKNOWN) { - fprintf(stderr, "Must specify -M or -C.\n"); - goto err; - } - - if (selfp == NULL) - usage(progname); - - if (home == NULL) - usage(progname); - - /* - * Turn off SIGPIPE so that we don't kill processes when they - * happen to lose a connection at the wrong time. - */ - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler = SIG_IGN; - if ((ret = sigaction(SIGPIPE, &sigact, NULL)) != 0) { - fprintf(stderr, - "Unable to turn off SIGPIPE: %s\n", strerror(ret)); - goto err; - } - - /* - * We are hardcoding priorities here that all clients have the - * same priority except for a designated master who gets a higher - * priority. - */ - if ((ret = - machtab_init(&machtab, priority, totalsites)) != 0) - goto err; - - /* - * We can know open our environment, although we're not ready to - * begin replicating. However, we want to have a dbenv around - * so that we can send it into any of our message handlers. - */ - if ((ret = env_init(progname, home, &dbenv, machtab, DB_RECOVER)) != 0) - goto err; - - /* - * Now sets up comm infrastructure. There are two phases. First, - * we open our port for listening for incoming connections. Then - * we attempt to connect to every host we know about. - */ - - ca.dbenv = dbenv; - ca.home = home; - ca.progname = progname; - ca.machtab = machtab; - ca.port = selfp->port; - if ((ret = pthread_create(&conn_thr, NULL, connect_thread, &ca)) != 0) - goto err; - - aa.dbenv = dbenv; - aa.progname = progname; - aa.home = home; - aa.machtab = machtab; - aa.sites = sitep; - aa.nsites = nsites; - if ((ret = pthread_create(&all_thr, NULL, connect_all, &aa)) != 0) - goto err; - - /* - * We have now got the entire communication infrastructure set up. - * It's time to declare ourselves to be a client or master. - */ - if (whoami == MASTER) { - if ((ret = dbenv->rep_start(dbenv, NULL, DB_REP_MASTER)) != 0) { - dbenv->err(dbenv, ret, "dbenv->rep_start failed"); - goto err; - } - if ((ret = domaster(dbenv, progname)) != 0) { - dbenv->err(dbenv, ret, "Master failed"); - goto err; - } - } else { - memset(&local, 0, sizeof(local)); - local.data = myaddr; - local.size = strlen(myaddr) + 1; - if ((ret = - dbenv->rep_start(dbenv, &local, DB_REP_CLIENT)) != 0) { - dbenv->err(dbenv, ret, "dbenv->rep_start failed"); - goto err; - } - /* Sleep to give ourselves a minute to find a master. */ - sleep(5); - if ((ret = doclient(dbenv, progname, machtab)) != 0) { - dbenv->err(dbenv, ret, "Client failed"); - goto err; - } - - } - - /* Wait on the connection threads. */ - if (pthread_join(all_thr, &astatus) || pthread_join(conn_thr, &cstatus)) - ret = errno; - if (ret == 0 && - ((int)astatus != EXIT_SUCCESS || (int)cstatus != EXIT_SUCCESS)) - ret = -1; - -err: if (machtab != NULL) - free(machtab); - if (dbenv != NULL) - (void)dbenv->close(dbenv, 0); - return (ret); -} - -/* - * In this application, we specify all communication via the command line. - * In a real application, we would expect that information about the other - * sites in the system would be maintained in some sort of configuration - * file. The critical part of this interface is that we assume at startup - * that we can find out 1) what host/port we wish to listen on for connections, - * 2) a (possibly empty) list of other sites we should attempt to connect to. - * 3) whether we are a master or client (if we don't know, we should come up - * as a client and see if there is a master out there) and 4) what our - * Berkeley DB home environment is. - * - * These pieces of information are expressed by the following flags. - * -m host:port (required; m stands for me) - * -o host:port (optional; o stands for other; any number of these may be - * specified) - * -[MC] M for master/C for client - * -h home directory - * -n nsites (optional; number of sites in replication group; defaults to 0 - * in which case we try to dynamically compute the number of sites in - * the replication group.) - * -p priority (optional: defaults to 100) - */ -static void -usage(progname) - const char *progname; -{ - fprintf(stderr, "usage: %s ", progname); - fprintf(stderr, "[-CM][-h home][-o host:port][-m host:port]%s", - "[-n nsites][-p priority]\n"); - exit(EXIT_FAILURE); -} - -/* Open and configure an environment. */ -int -env_init(progname, home, dbenvp, machtab, flags) - const char *progname, *home; - DB_ENV **dbenvp; - machtab_t *machtab; - u_int32_t flags; -{ - DB_ENV *dbenv; - int ret; - char *prefix; - - if ((prefix = malloc(strlen(progname) + 2)) == NULL) { - fprintf(stderr, - "%s: System error: %s\n", progname, strerror(errno)); - return (errno); - } - sprintf(prefix, "%s:", progname); - - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, "%s: env create failed: %s\n", - progname, db_strerror(ret)); - return (ret); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, prefix); - /* (void)dbenv->set_verbose(dbenv, DB_VERB_REPLICATION, 1); */ - (void)dbenv->set_cachesize(dbenv, 0, CACHESIZE, 0); - /* (void)dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1); */ - - dbenv->app_private = machtab; - (void)dbenv->set_rep_transport(dbenv, SELF_EID, quote_send); - - flags |= DB_CREATE | DB_THREAD | - DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN; - - ret = dbenv->open(dbenv, home, flags, 0); - - *dbenvp = dbenv; - return (ret); -} diff --git a/bdb/examples_c/ex_repquote/ex_rq_master.c b/bdb/examples_c/ex_repquote/ex_rq_master.c deleted file mode 100644 index bb3f37f55b9..00000000000 --- a/bdb/examples_c/ex_repquote/ex_rq_master.c +++ /dev/null @@ -1,165 +0,0 @@ -/*- - * #include <pthread.h> - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_rq_master.c,v 1.22 2002/08/06 05:39:03 bostic Exp $ - */ - -#include <sys/types.h> - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_repquote.h" - -static void *master_loop __P((void *)); - -#define BUFSIZE 1024 - -int -domaster(dbenv, progname) - DB_ENV *dbenv; - const char *progname; -{ - int ret, t_ret; - pthread_t interface_thr; - pthread_attr_t attr; - - COMPQUIET(progname, NULL); - - /* Spawn off a thread to handle the basic master interface. */ - if ((ret = pthread_attr_init(&attr)) != 0 && - (ret = pthread_attr_setdetachstate(&attr, - PTHREAD_CREATE_DETACHED)) != 0) - goto err; - - if ((ret = pthread_create(&interface_thr, - &attr, master_loop, (void *)dbenv)) != 0) - goto err; - -err: if ((t_ret = pthread_attr_destroy(&attr)) != 0 && ret == 0) - ret = t_ret; - - return (ret); -} - -static void * -master_loop(dbenvv) - void *dbenvv; -{ - DB *dbp; - DB_ENV *dbenv; - DB_TXN *txn; - DBT key, data; - char buf[BUFSIZE], *rbuf; - int ret; - - dbp = NULL; - txn = NULL; - - dbenv = (DB_ENV *)dbenvv; - /* - * Check if the database exists and if it verifies cleanly. - * If it does, run with it; else recreate it and go. Note - * that we have to verify outside of the environment. - */ -#ifdef NOTDEF - if ((ret = db_create(&dbp, NULL, 0)) != 0) - return (ret); - if ((ret = dbp->verify(dbp, DATABASE, NULL, NULL, 0)) != 0) { - if ((ret = dbp->remove(dbp, DATABASE, NULL, 0)) != 0 && - ret != DB_NOTFOUND && ret != ENOENT) - return (ret); -#endif - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return ((void *)ret); - - if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - if ((ret = dbp->open(dbp, txn, DATABASE, - NULL, DB_BTREE, DB_CREATE /* | DB_THREAD */, 0)) != 0) - goto err; - ret = txn->commit(txn, 0); - txn = NULL; - if (ret != 0) { - dbp = NULL; - goto err; - } - -#ifdef NOTDEF - } else { - /* Reopen in the environment. */ - if ((ret = dbp->close(dbp, 0)) != 0) - return (ret); - if ((ret = db_create(&dbp, dbenv, 0)) != 0) - return (ret); - if ((ret = dbp->open(dbp, - DATABASE, NULL, DB_UNKNOWN, DB_THREAD, 0)) != 0) - goto err; - } -#endif - /* - * XXX - * It would probably be kind of cool to do this in Tcl and - * have a nice GUI. It would also be cool to be independently - * wealthy. - */ - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - for (;;) { - printf("QUOTESERVER> "); - fflush(stdout); - - if (fgets(buf, sizeof(buf), stdin) == NULL) - break; - (void)strtok(&buf[0], " \t\n"); - rbuf = strtok(NULL, " \t\n"); - if (rbuf == NULL || rbuf[0] == '\0') { - if (strncmp(buf, "exit", 4) == 0 || - strncmp(buf, "quit", 4) == 0) - break; - dbenv->errx(dbenv, "Format: TICKER VALUE"); - continue; - } - - key.data = buf; - key.size = strlen(buf); - - data.data = rbuf; - data.size = strlen(rbuf); - - if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0) - goto err; - switch (ret = - dbp->put(dbp, txn, &key, &data, 0)) { - case 0: - break; - default: - dbp->err(dbp, ret, "DB->put"); - if (ret != DB_KEYEXIST) - goto err; - break; - } - ret = txn->commit(txn, 0); - txn = NULL; - if (ret != 0) - goto err; - } - -err: if (txn != NULL) - (void)txn->abort(txn); - - if (dbp != NULL) - (void)dbp->close(dbp, DB_NOSYNC); - - return ((void *)ret); -} diff --git a/bdb/examples_c/ex_repquote/ex_rq_net.c b/bdb/examples_c/ex_repquote/ex_rq_net.c deleted file mode 100644 index 1a6d26488d6..00000000000 --- a/bdb/examples_c/ex_repquote/ex_rq_net.c +++ /dev/null @@ -1,692 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_rq_net.c,v 1.37 2002/08/06 05:39:04 bostic Exp $ - */ - -#include <sys/types.h> - -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/wait.h> - -#include <assert.h> -#include <errno.h> -#include <netdb.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> -#include <dbinc/queue.h> /* !!!: for the LIST_XXX macros. */ - -#include "ex_repquote.h" - -int machtab_add __P((machtab_t *, int, u_int32_t, int, int *)); -ssize_t readn __P((int, void *, size_t)); - -/* - * This file defines the communication infrastructure for the ex_repquote - * sample application. - * - * This application uses TCP/IP for its communication. In an N-site - * replication group, this means that there are N * N communication - * channels so that every site can communicate with every other site - * (this allows elections to be held when the master fails). We do - * not require that anyone know about all sites when the application - * starts up. In order to communicate, the application should know - * about someone, else it has no idea how to ever get in the game. - * - * Communication is handled via a number of different threads. These - * thread functions are implemented in rep_util.c In this file, we - * define the data structures that maintain the state that describes - * the comm infrastructure, the functions that manipulates this state - * and the routines used to actually send and receive data over the - * sockets. - */ - -/* - * The communication infrastructure is represented by a machine table, - * machtab_t, which is essentially a mutex-protected linked list of members - * of the group. The machtab also contains the parameters that are needed - * to call for an election. We hardwire values for these parameters in the - * init function, but these could be set via some configuration setup in a - * real application. We reserve the machine-id 1 to refer to ourselves and - * make the machine-id 0 be invalid. - */ - -#define MACHID_INVALID 0 -#define MACHID_SELF 1 - -struct __machtab { - LIST_HEAD(__machlist, __member) machlist; - int nextid; - pthread_mutex_t mtmutex; - u_int32_t timeout_time; - int current; - int max; - int nsites; - int priority; -}; - -/* Data structure that describes each entry in the machtab. */ -struct __member { - u_int32_t hostaddr; /* Host IP address. */ - int port; /* Port number. */ - int eid; /* Application-specific machine id. */ - int fd; /* File descriptor for the socket. */ - LIST_ENTRY(__member) links; - /* For linked list of all members we know of. */ -}; - -static int quote_send_broadcast __P((machtab_t *, - const DBT *, const DBT *, u_int32_t)); -static int quote_send_one __P((const DBT *, const DBT *, int, u_int32_t)); - -/* - * machtab_init -- - * Initialize the machine ID table. - * XXX Right now we treat the number of sites as the maximum - * number we've ever had on the list at one time. We probably - * want to make that smarter. - */ -int -machtab_init(machtabp, pri, nsites) - machtab_t **machtabp; - int pri, nsites; -{ - int ret; - machtab_t *machtab; - - if ((machtab = malloc(sizeof(machtab_t))) == NULL) - return (ENOMEM); - - LIST_INIT(&machtab->machlist); - - /* Reserve eid's 0 and 1. */ - machtab->nextid = 2; - machtab->timeout_time = 2 * 1000000; /* 2 seconds. */ - machtab->current = machtab->max = 0; - machtab->priority = pri; - machtab->nsites = nsites; - - ret = pthread_mutex_init(&machtab->mtmutex, NULL); - - *machtabp = machtab; - - return (ret); -} - -/* - * machtab_add -- - * Add a file descriptor to the table of machines, returning - * a new machine ID. - */ -int -machtab_add(machtab, fd, hostaddr, port, idp) - machtab_t *machtab; - int fd; - u_int32_t hostaddr; - int port, *idp; -{ - int ret; - member_t *m, *member; - - if ((member = malloc(sizeof(member_t))) == NULL) - return (ENOMEM); - - member->fd = fd; - member->hostaddr = hostaddr; - member->port = port; - - if ((ret = pthread_mutex_lock(&machtab->mtmutex)) != 0) - return (ret); - - for (m = LIST_FIRST(&machtab->machlist); - m != NULL; m = LIST_NEXT(m, links)) - if (m->hostaddr == hostaddr && m->port == port) - break; - - if (m == NULL) { - member->eid = machtab->nextid++; - LIST_INSERT_HEAD(&machtab->machlist, member, links); - } else - member->eid = m->eid; - - ret = pthread_mutex_unlock(&machtab->mtmutex); - - if (idp != NULL) - *idp = member->eid; - - if (m == NULL) { - if (++machtab->current > machtab->max) - machtab->max = machtab->current; - } else { - free(member); - ret = EEXIST; - } - return (ret); -} - -/* - * machtab_getinfo -- - * Return host and port information for a particular machine id. - */ -int -machtab_getinfo(machtab, eid, hostp, portp) - machtab_t *machtab; - int eid; - u_int32_t *hostp; - int *portp; -{ - int ret; - member_t *member; - - if ((ret = pthread_mutex_lock(&machtab->mtmutex)) != 0) - return (ret); - - for (member = LIST_FIRST(&machtab->machlist); - member != NULL; - member = LIST_NEXT(member, links)) - if (member->eid == eid) { - *hostp = member->hostaddr; - *portp = member->port; - break; - } - - if ((ret = pthread_mutex_unlock(&machtab->mtmutex)) != 0) - return (ret); - - return (member != NULL ? 0 : EINVAL); -} - -/* - * machtab_rem -- - * Remove a mapping from the table of machines. Lock indicates - * whether we need to lock the machtab or not (0 indicates we do not - * need to lock; non-zero indicates that we do need to lock). - */ -int -machtab_rem(machtab, eid, lock) - machtab_t *machtab; - int eid; - int lock; -{ - int found, ret; - member_t *member; - - ret = 0; - if (lock && (ret = pthread_mutex_lock(&machtab->mtmutex)) != 0) - return (ret); - - for (found = 0, member = LIST_FIRST(&machtab->machlist); - member != NULL; - member = LIST_NEXT(member, links)) - if (member->eid == eid) { - found = 1; - LIST_REMOVE(member, links); - (void)close(member->fd); - free(member); - machtab->current--; - break; - } - - if (LIST_FIRST(&machtab->machlist) == NULL) - machtab->nextid = 2; - - if (lock) - ret = pthread_mutex_unlock(&machtab->mtmutex); - - return (ret); -} - -void -machtab_parm(machtab, nump, prip, timeoutp) - machtab_t *machtab; - int *nump, *prip; - u_int32_t *timeoutp; -{ - if (machtab->nsites == 0) - *nump = machtab->max; - else - *nump = machtab->nsites; - *prip = machtab->priority; - *timeoutp = machtab->timeout_time; -} - -/* - * listen_socket_init -- - * Initialize a socket for listening on the specified port. Returns - * a file descriptor for the socket, ready for an accept() call - * in a thread that we're happy to let block. - */ -int -listen_socket_init(progname, port) - const char *progname; - int port; -{ - int s; - struct protoent *proto; - struct sockaddr_in si; - - if ((proto = getprotobyname("tcp")) == NULL) - return (-1); - - if ((s = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0) - return (-1); - - memset(&si, 0, sizeof(si)); - si.sin_family = AF_INET; - si.sin_addr.s_addr = htonl(INADDR_ANY); - si.sin_port = htons(port); - - if (bind(s, (struct sockaddr *)&si, sizeof(si)) != 0) - goto err; - - if (listen(s, 5) != 0) - goto err; - - return (s); - -err: fprintf(stderr, "%s: %s", progname, strerror(errno)); - close (s); - return (-1); -} - -/* - * listen_socket_accept -- - * Accept a connection on a socket. This is essentially just a wrapper - * for accept(3). - */ -int -listen_socket_accept(machtab, progname, s, eidp) - machtab_t *machtab; - const char *progname; - int s, *eidp; -{ - struct sockaddr_in si; - int si_len; - int host, ns, port, ret; - - COMPQUIET(progname, NULL); - -wait: memset(&si, 0, sizeof(si)); - si_len = sizeof(si); - ns = accept(s, (struct sockaddr *)&si, &si_len); - host = ntohl(si.sin_addr.s_addr); - port = ntohs(si.sin_port); - ret = machtab_add(machtab, ns, host, port, eidp); - if (ret == EEXIST) { - close(ns); - goto wait; - } else if (ret != 0) - goto err; - - return (ns); - -err: close(ns); - return (-1); -} - -/* - * get_accepted_socket -- - * Listen on the specified port, and return a file descriptor - * when we have accepted a connection on it. - */ -int -get_accepted_socket(progname, port) - const char *progname; - int port; -{ - struct protoent *proto; - struct sockaddr_in si; - int si_len; - int s, ns; - - if ((proto = getprotobyname("tcp")) == NULL) - return (-1); - - if ((s = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0) - return (-1); - - memset(&si, 0, sizeof(si)); - si.sin_family = AF_INET; - si.sin_addr.s_addr = htonl(INADDR_ANY); - si.sin_port = htons(port); - - if (bind(s, (struct sockaddr *)&si, sizeof(si)) != 0) - goto err; - - if (listen(s, 5) != 0) - goto err; - - memset(&si, 0, sizeof(si)); - si_len = sizeof(si); - ns = accept(s, (struct sockaddr *)&si, &si_len); - - return (ns); - -err: fprintf(stderr, "%s: %s", progname, strerror(errno)); - close (s); - return (-1); -} - -/* - * get_connected_socket -- - * Connect to the specified port of the specified remote machine, - * and return a file descriptor when we have accepted a connection on it. - * Add this connection to the machtab. If we already have a connection - * open to this machine, then don't create another one, return the eid - * of the connection (in *eidp) and set is_open to 1. Return 0. - */ -int -get_connected_socket(machtab, progname, remotehost, port, is_open, eidp) - machtab_t *machtab; - const char *progname, *remotehost; - int port, *is_open, *eidp; -{ - int ret, s; - struct hostent *hp; - struct protoent *proto; - struct sockaddr_in si; - u_int32_t addr; - - *is_open = 0; - - if ((proto = getprotobyname("tcp")) == NULL) - return (-1); - - if ((hp = gethostbyname(remotehost)) == NULL) { - fprintf(stderr, "%s: host not found: %s\n", progname, - strerror(errno)); - return (-1); - } - - if ((s = socket(AF_INET, SOCK_STREAM, proto->p_proto)) < 0) - return (-1); - memset(&si, 0, sizeof(si)); - memcpy((char *)&si.sin_addr, hp->h_addr, hp->h_length); - addr = ntohl(si.sin_addr.s_addr); - ret = machtab_add(machtab, s, addr, port, eidp); - if (ret == EEXIST) { - *is_open = 1; - close(s); - return (0); - } else if (ret != 0) { - close (s); - return (-1); - } - - si.sin_family = AF_INET; - si.sin_port = htons(port); - if (connect(s, (struct sockaddr *)&si, sizeof(si)) < 0) { - fprintf(stderr, "%s: connection failed: %s", - progname, strerror(errno)); - (void)machtab_rem(machtab, *eidp, 1); - return (-1); - } - - return (s); -} - -/* - * get_next_message -- - * Read a single message from the specified file descriptor, and - * return it in the format used by rep functions (two DBTs and a type). - * - * This function is called in a loop by both clients and masters, and - * the resulting DBTs are manually dispatched to DB_ENV->rep_process_message(). - */ -int -get_next_message(fd, rec, control) - int fd; - DBT *rec, *control; -{ - size_t nr; - u_int32_t rsize, csize; - u_int8_t *recbuf, *controlbuf; - - /* - * The protocol we use on the wire is dead simple: - * - * 4 bytes - rec->size - * (# read above) - rec->data - * 4 bytes - control->size - * (# read above) - control->data - */ - - /* Read rec->size. */ - nr = readn(fd, &rsize, 4); - if (nr != 4) - return (1); - - /* Read the record itself. */ - if (rsize > 0) { - if (rec->size < rsize) - rec->data = realloc(rec->data, rsize); - recbuf = rec->data; - nr = readn(fd, recbuf, rsize); - } else { - if (rec->data != NULL) - free(rec->data); - rec->data = NULL; - } - rec->size = rsize; - - /* Read control->size. */ - nr = readn(fd, &csize, 4); - if (nr != 4) - return (1); - - /* Read the control struct itself. */ - if (csize > 0) { - controlbuf = control->data; - if (control->size < csize) - controlbuf = realloc(controlbuf, csize); - nr = readn(fd, controlbuf, csize); - if (nr != csize) - return (1); - } else { - if (control->data != NULL) - free(control->data); - controlbuf = NULL; - } - control->data = controlbuf; - control->size = csize; - - return (0); -} - -/* - * readn -- - * Read a full n characters from a file descriptor, unless we get an error - * or EOF. - */ -ssize_t -readn(fd, vptr, n) - int fd; - void *vptr; - size_t n; -{ - size_t nleft; - ssize_t nread; - char *ptr; - - ptr = vptr; - nleft = n; - while (nleft > 0) { - if ( (nread = read(fd, ptr, nleft)) < 0) { - /* - * Call read() again on interrupted system call; - * on other errors, bail. - */ - if (errno == EINTR) - nread = 0; - else - return (-1); - } else if (nread == 0) - break; /* EOF */ - - nleft -= nread; - ptr += nread; - } - - return (n - nleft); -} - -/* - * quote_send -- - * The f_send function for DB_ENV->set_rep_transport. - */ -int -quote_send(dbenv, control, rec, eid, flags) - DB_ENV *dbenv; - const DBT *control, *rec; - int eid; - u_int32_t flags; -{ - int fd, n, ret, t_ret; - machtab_t *machtab; - member_t *m; - - machtab = (machtab_t *)dbenv->app_private; - - if (eid == DB_EID_BROADCAST) { - /* - * Right now, we do not require successful transmission. - * I'd like to move this requiring at least one successful - * transmission on PERMANENT requests. - */ - n = quote_send_broadcast(machtab, rec, control, flags); - if (n < 0 /*|| (n == 0 && LF_ISSET(DB_REP_PERMANENT))*/) - return (DB_REP_UNAVAIL); - return (0); - } - - if ((ret = pthread_mutex_lock(&machtab->mtmutex)) != 0) - return (ret); - - fd = 0; - for (m = LIST_FIRST(&machtab->machlist); m != NULL; - m = LIST_NEXT(m, links)) { - if (m->eid == eid) { - fd = m->fd; - break; - } - } - - if (fd == 0) { - dbenv->err(dbenv, DB_REP_UNAVAIL, - "quote_send: cannot find machine ID %d", eid); - return (DB_REP_UNAVAIL); - } - - ret = quote_send_one(rec, control, fd, flags); - - if ((t_ret = (pthread_mutex_unlock(&machtab->mtmutex))) != 0 && - ret == 0) - ret = t_ret; - - return (ret); -} - -/* - * quote_send_broadcast -- - * Send a message to everybody. - * Returns the number of sites to which this message was successfully - * communicated. A -1 indicates a fatal error. - */ -static int -quote_send_broadcast(machtab, rec, control, flags) - machtab_t *machtab; - const DBT *rec, *control; - u_int32_t flags; -{ - int ret, sent; - member_t *m, *next; - - if ((ret = pthread_mutex_lock(&machtab->mtmutex)) != 0) - return (0); - - sent = 0; - for (m = LIST_FIRST(&machtab->machlist); m != NULL; m = next) { - next = LIST_NEXT(m, links); - if ((ret = quote_send_one(rec, control, m->fd, flags)) != 0) { - (void)machtab_rem(machtab, m->eid, 0); - } else - sent++; - } - - if (pthread_mutex_unlock(&machtab->mtmutex) != 0) - return (-1); - - return (sent); -} - -/* - * quote_send_one -- - * Send a message to a single machine, given that machine's file - * descriptor. - * - * !!! - * Note that the machtab mutex should be held through this call. - * It doubles as a synchronizer to make sure that two threads don't - * intersperse writes that are part of two single messages. - */ -static int -quote_send_one(rec, control, fd, flags) - const DBT *rec, *control; - int fd; - u_int32_t flags; - -{ - int retry; - ssize_t bytes_left, nw; - u_int8_t *wp; - - COMPQUIET(flags, 0); - - /* - * The protocol is simply: write rec->size, write rec->data, - * write control->size, write control->data. - */ - nw = write(fd, &rec->size, 4); - if (nw != 4) - return (DB_REP_UNAVAIL); - - if (rec->size > 0) { - nw = write(fd, rec->data, rec->size); - if (nw < 0) - return (DB_REP_UNAVAIL); - if (nw != (ssize_t)rec->size) { - /* Try a couple of times to finish the write. */ - wp = (u_int8_t *)rec->data + nw; - bytes_left = rec->size - nw; - for (retry = 0; bytes_left > 0 && retry < 3; retry++) { - nw = write(fd, wp, bytes_left); - if (nw < 0) - return (DB_REP_UNAVAIL); - bytes_left -= nw; - wp += nw; - } - if (bytes_left > 0) - return (DB_REP_UNAVAIL); - } - } - - nw = write(fd, &control->size, 4); - if (nw != 4) - return (DB_REP_UNAVAIL); - if (control->size > 0) { - nw = write(fd, control->data, control->size); - if (nw != (ssize_t)control->size) - return (DB_REP_UNAVAIL); - } - return (0); -} diff --git a/bdb/examples_c/ex_repquote/ex_rq_util.c b/bdb/examples_c/ex_repquote/ex_rq_util.c deleted file mode 100644 index 89fd7ae485a..00000000000 --- a/bdb/examples_c/ex_repquote/ex_rq_util.c +++ /dev/null @@ -1,412 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 2001-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_rq_util.c,v 1.20 2002/08/06 05:39:04 bostic Exp $ - */ - -#include <sys/types.h> - -#include <errno.h> -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <db.h> - -#include "ex_repquote.h" - -static int connect_site __P((DB_ENV *, machtab_t *, const char *, - repsite_t *, int *, int *)); -void * elect_thread __P((void *)); - -typedef struct { - DB_ENV *dbenv; - machtab_t *machtab; -} elect_args; - -typedef struct { - DB_ENV *dbenv; - const char *progname; - const char *home; - int fd; - u_int32_t eid; - machtab_t *tab; -} hm_loop_args; - -/* - * This is a generic message handling loop that is used both by the - * master to accept messages from a client as well as by clients - * to communicate with other clients. - */ -void * -hm_loop(args) - void *args; -{ - DB_ENV *dbenv; - DBT rec, control; - const char *c, *home, *progname; - int fd, eid, n, newm; - int open, pri, r, ret, t_ret, tmpid; - elect_args *ea; - hm_loop_args *ha; - machtab_t *tab; - pthread_t elect_thr; - repsite_t self; - u_int32_t timeout; - void *status; - - ea = NULL; - - ha = (hm_loop_args *)args; - dbenv = ha->dbenv; - fd = ha->fd; - home = ha->home; - eid = ha->eid; - progname = ha->progname; - tab = ha->tab; - free(ha); - - memset(&rec, 0, sizeof(DBT)); - memset(&control, 0, sizeof(DBT)); - - for (ret = 0; ret == 0;) { - if ((ret = get_next_message(fd, &rec, &control)) != 0) { - /* - * Close this connection; if it's the master call - * for an election. - */ - close(fd); - if ((ret = machtab_rem(tab, eid, 1)) != 0) - break; - - /* - * If I'm the master, I just lost a client and this - * thread is done. - */ - if (master_eid == SELF_EID) - break; - - /* - * If I was talking with the master and the master - * went away, I need to call an election; else I'm - * done. - */ - if (master_eid != eid) - break; - - master_eid = DB_EID_INVALID; - machtab_parm(tab, &n, &pri, &timeout); - if ((ret = dbenv->rep_elect(dbenv, - n, pri, timeout, &newm)) != 0) - continue; - - /* - * Regardless of the results, the site I was talking - * to is gone, so I have nothing to do but exit. - */ - if (newm == SELF_EID && (ret = - dbenv->rep_start(dbenv, NULL, DB_REP_MASTER)) == 0) - ret = domaster(dbenv, progname); - break; - } - - tmpid = eid; - switch(r = dbenv->rep_process_message(dbenv, - &control, &rec, &tmpid)) { - case DB_REP_NEWSITE: - /* - * Check if we got sent connect information and if we - * did, if this is me or if we already have a - * connection to this new site. If we don't, - * establish a new one. - */ - - /* No connect info. */ - if (rec.size == 0) - break; - - /* It's me, do nothing. */ - if (strncmp(myaddr, rec.data, rec.size) == 0) - break; - - self.host = (char *)rec.data; - self.host = strtok(self.host, ":"); - if ((c = strtok(NULL, ":")) == NULL) { - dbenv->errx(dbenv, "Bad host specification"); - goto out; - } - self.port = atoi(c); - - /* - * We try to connect to the new site. If we can't, - * we treat it as an error since we know that the site - * should be up if we got a message from it (even - * indirectly). - */ - if ((ret = connect_site(dbenv, - tab, progname, &self, &open, &eid)) != 0) - goto out; - break; - case DB_REP_HOLDELECTION: - if (master_eid == SELF_EID) - break; - /* Make sure that previous election has finished. */ - if (ea != NULL) { - (void)pthread_join(elect_thr, &status); - ea = NULL; - } - if ((ea = calloc(sizeof(elect_args), 1)) == NULL) { - ret = errno; - goto out; - } - ea->dbenv = dbenv; - ea->machtab = tab; - ret = pthread_create(&elect_thr, - NULL, elect_thread, (void *)ea); - break; - case DB_REP_NEWMASTER: - /* Check if it's us. */ - master_eid = tmpid; - if (tmpid == SELF_EID) { - if ((ret = dbenv->rep_start(dbenv, - NULL, DB_REP_MASTER)) != 0) - goto out; - ret = domaster(dbenv, progname); - } - break; - case 0: - break; - default: - dbenv->err(dbenv, r, "DB_ENV->rep_process_message"); - break; - } - } - -out: if ((t_ret = machtab_rem(tab, eid, 1)) != 0 && ret == 0) - ret = t_ret; - - /* Don't close the environment before any children exit. */ - if (ea != NULL) - (void)pthread_join(elect_thr, &status); - - return ((void *)ret); -} - -/* - * This is a generic thread that spawns a thread to listen for connections - * on a socket and then spawns off child threads to handle each new - * connection. - */ -void * -connect_thread(args) - void *args; -{ - DB_ENV *dbenv; - const char *home, *progname; - int fd, i, eid, ns, port, ret; - hm_loop_args *ha; - connect_args *cargs; - machtab_t *machtab; -#define MAX_THREADS 25 - pthread_t hm_thrs[MAX_THREADS]; - pthread_attr_t attr; - - ha = NULL; - cargs = (connect_args *)args; - dbenv = cargs->dbenv; - home = cargs->home; - progname = cargs->progname; - machtab = cargs->machtab; - port = cargs->port; - - if ((ret = pthread_attr_init(&attr)) != 0) - return ((void *)EXIT_FAILURE); - - if ((ret = - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) != 0) - goto err; - - /* - * Loop forever, accepting connections from new machines, - * and forking off a thread to handle each. - */ - if ((fd = listen_socket_init(progname, port)) < 0) { - ret = errno; - goto err; - } - - for (i = 0; i < MAX_THREADS; i++) { - if ((ns = listen_socket_accept(machtab, - progname, fd, &eid)) < 0) { - ret = errno; - goto err; - } - if ((ha = calloc(sizeof(hm_loop_args), 1)) == NULL) - goto err; - ha->progname = progname; - ha->home = home; - ha->fd = ns; - ha->eid = eid; - ha->tab = machtab; - ha->dbenv = dbenv; - if ((ret = pthread_create(&hm_thrs[i++], &attr, - hm_loop, (void *)ha)) != 0) - goto err; - ha = NULL; - } - - /* If we fell out, we ended up with too many threads. */ - dbenv->errx(dbenv, "Too many threads"); - ret = ENOMEM; - -err: pthread_attr_destroy(&attr); - return (ret == 0 ? (void *)EXIT_SUCCESS : (void *)EXIT_FAILURE); -} - -/* - * Open a connection to everyone that we've been told about. If we - * cannot open some connections, keep trying. - */ -void * -connect_all(args) - void *args; -{ - DB_ENV *dbenv; - all_args *aa; - const char *home, *progname; - hm_loop_args *ha; - int failed, i, eid, nsites, open, ret, *success; - machtab_t *machtab; - repsite_t *sites; - - ha = NULL; - aa = (all_args *)args; - dbenv = aa->dbenv; - progname = aa->progname; - home = aa->home; - machtab = aa->machtab; - nsites = aa->nsites; - sites = aa->sites; - - ret = 0; - - /* Some implementations of calloc are sad about alloc'ing 0 things. */ - if ((success = calloc(nsites > 0 ? nsites : 1, sizeof(int))) == NULL) { - dbenv->err(dbenv, errno, "connect_all"); - ret = 1; - goto err; - } - - for (failed = nsites; failed > 0;) { - for (i = 0; i < nsites; i++) { - if (success[i]) - continue; - - ret = connect_site(dbenv, machtab, - progname, &sites[i], &open, &eid); - - /* - * If we couldn't make the connection, this isn't - * fatal to the loop, but we have nothing further - * to do on this machine at the moment. - */ - if (ret == DB_REP_UNAVAIL) - continue; - - if (ret != 0) - goto err; - - failed--; - success[i] = 1; - - /* If the connection is already open, we're done. */ - if (ret == 0 && open == 1) - continue; - - } - sleep(1); - } - -err: free(success); - return (ret ? (void *)EXIT_FAILURE : (void *)EXIT_SUCCESS); -} - -int -connect_site(dbenv, machtab, progname, site, is_open, eidp) - DB_ENV *dbenv; - machtab_t *machtab; - const char *progname; - repsite_t *site; - int *is_open; - int *eidp; -{ - int ret, s; - hm_loop_args *ha; - pthread_t hm_thr; - - if ((s = get_connected_socket(machtab, progname, - site->host, site->port, is_open, eidp)) < 0) - return (DB_REP_UNAVAIL); - - if (*is_open) - return (0); - - if ((ha = calloc(sizeof(hm_loop_args), 1)) == NULL) { - ret = errno; - goto err; - } - - ha->progname = progname; - ha->fd = s; - ha->eid = *eidp; - ha->tab = machtab; - ha->dbenv = dbenv; - - if ((ret = pthread_create(&hm_thr, NULL, - hm_loop, (void *)ha)) != 0) { - dbenv->err(dbenv, ret, "connect site"); - goto err1; - } - - return (0); - -err1: free(ha); -err: - return (ret); -} - -/* - * We need to spawn off a new thread in which to hold an election in - * case we are the only thread listening on for messages. - */ -void * -elect_thread(args) - void *args; -{ - DB_ENV *dbenv; - elect_args *eargs; - int n, ret, pri; - machtab_t *machtab; - u_int32_t timeout; - - eargs = (elect_args *)args; - dbenv = eargs->dbenv; - machtab = eargs->machtab; - free(eargs); - - machtab_parm(machtab, &n, &pri, &timeout); - while ((ret = - dbenv->rep_elect(dbenv, n, pri, timeout, &master_eid)) != 0) - sleep(2); - - /* Check if it's us. */ - if (master_eid == SELF_EID) - ret = dbenv->rep_start(dbenv, NULL, DB_REP_MASTER); - - return ((void *)(ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE)); -} diff --git a/bdb/examples_c/ex_thread.c b/bdb/examples_c/ex_thread.c deleted file mode 100644 index 104de37ad38..00000000000 --- a/bdb/examples_c/ex_thread.c +++ /dev/null @@ -1,629 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_thread.c,v 11.34 2002/08/15 14:37:13 bostic Exp $ - */ - -#include <sys/types.h> -#include <sys/time.h> - -#include <errno.h> -#include <pthread.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef _WIN32 -extern int getopt(int, char * const *, const char *); -#else -#include <unistd.h> -#endif - -#include <db.h> - -/* - * NB: This application is written using POSIX 1003.1b-1993 pthreads - * interfaces, which may not be portable to your system. - */ -extern int sched_yield __P((void)); /* Pthread yield function. */ - -int db_init __P((const char *)); -void *deadlock __P((void *)); -void fatal __P((const char *, int, int)); -void onint __P((int)); -int main __P((int, char *[])); -int reader __P((int)); -void stats __P((void)); -void *trickle __P((void *)); -void *tstart __P((void *)); -int usage __P((void)); -void word __P((void)); -int writer __P((int)); - -int quit; /* Interrupt handling flag. */ - -struct _statistics { - int aborted; /* Write. */ - int aborts; /* Read/write. */ - int adds; /* Write. */ - int deletes; /* Write. */ - int txns; /* Write. */ - int found; /* Read. */ - int notfound; /* Read. */ -} *perf; - -const char - *progname = "ex_thread"; /* Program name. */ - -#define DATABASE "access.db" /* Database name. */ -#define WORDLIST "../test/wordlist" /* Dictionary. */ - -/* - * We can seriously increase the number of collisions and transaction - * aborts by yielding the scheduler after every DB call. Specify the - * -p option to do this. - */ -int punish; /* -p */ -int nlist; /* -n */ -int nreaders; /* -r */ -int verbose; /* -v */ -int nwriters; /* -w */ - -DB *dbp; /* Database handle. */ -DB_ENV *dbenv; /* Database environment. */ -int nthreads; /* Total threads. */ -char **list; /* Word list. */ - -/* - * ex_thread -- - * Run a simple threaded application of some numbers of readers and - * writers competing for a set of words. - * - * Example UNIX shell script to run this program: - * % rm -rf TESTDIR - * % mkdir TESTDIR - * % ex_thread -h TESTDIR - */ -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int errno, optind; - DB_TXN *txnp; - pthread_t *tids; - int ch, i, ret; - const char *home; - void *retp; - - txnp = NULL; - nlist = 1000; - nreaders = nwriters = 4; - home = "TESTDIR"; - while ((ch = getopt(argc, argv, "h:pn:r:vw:")) != EOF) - switch (ch) { - case 'h': - home = optarg; - break; - case 'p': - punish = 1; - break; - case 'n': - nlist = atoi(optarg); - break; - case 'r': - nreaders = atoi(optarg); - break; - case 'v': - verbose = 1; - break; - case 'w': - nwriters = atoi(optarg); - break; - case '?': - default: - return (usage()); - } - argc -= optind; - argv += optind; - - /* Initialize the random number generator. */ - srand(getpid() | time(NULL)); - - /* Register the signal handler. */ - (void)signal(SIGINT, onint); - - /* Build the key list. */ - word(); - - /* Remove the previous database. */ - (void)remove(DATABASE); - - /* Initialize the database environment. */ - if ((ret = db_init(home)) != 0) - return (ret); - - /* Initialize the database. */ - if ((ret = db_create(&dbp, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - (void)dbenv->close(dbenv, 0); - return (EXIT_FAILURE); - } - if ((ret = dbp->set_pagesize(dbp, 1024)) != 0) { - dbp->err(dbp, ret, "set_pagesize"); - goto err; - } - - if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0) - fatal("txn_begin", ret, 1); - if ((ret = dbp->open(dbp, txnp, - DATABASE, NULL, DB_BTREE, DB_CREATE | DB_THREAD, 0664)) != 0) { - dbp->err(dbp, ret, "%s: open", DATABASE); - goto err; - } else { - ret = txnp->commit(txnp, 0); - txnp = NULL; - if (ret != 0) - goto err; - } - - nthreads = nreaders + nwriters + 2; - printf("Running: readers %d, writers %d\n", nreaders, nwriters); - fflush(stdout); - - /* Create statistics structures, offset by 1. */ - if ((perf = calloc(nreaders + nwriters + 1, sizeof(*perf))) == NULL) - fatal(NULL, errno, 1); - - /* Create thread ID structures. */ - if ((tids = malloc(nthreads * sizeof(pthread_t))) == NULL) - fatal(NULL, errno, 1); - - /* Create reader/writer threads. */ - for (i = 0; i < nreaders + nwriters; ++i) - if ((ret = - pthread_create(&tids[i], NULL, tstart, (void *)i)) != 0) - fatal("pthread_create", ret > 0 ? ret : errno, 1); - - /* Create buffer pool trickle thread. */ - if (pthread_create(&tids[i], NULL, trickle, &i)) - fatal("pthread_create", errno, 1); - ++i; - - /* Create deadlock detector thread. */ - if (pthread_create(&tids[i], NULL, deadlock, &i)) - fatal("pthread_create", errno, 1); - - /* Wait for the threads. */ - for (i = 0; i < nthreads; ++i) - (void)pthread_join(tids[i], &retp); - - printf("Exiting\n"); - stats(); - -err: if (txnp != NULL) - (void)txnp->abort(txnp); - (void)dbp->close(dbp, 0); - (void)dbenv->close(dbenv, 0); - - return (EXIT_SUCCESS); -} - -int -reader(id) - int id; -{ - DBT key, data; - int n, ret; - char buf[64]; - - /* - * DBT's must use local memory or malloc'd memory if the DB handle - * is accessed in a threaded fashion. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - data.flags = DB_DBT_MALLOC; - - /* - * Read-only threads do not require transaction protection, unless - * there's a need for repeatable reads. - */ - while (!quit) { - /* Pick a key at random, and look it up. */ - n = rand() % nlist; - key.data = list[n]; - key.size = strlen(key.data); - - if (verbose) { - sprintf(buf, "reader: %d: list entry %d\n", id, n); - write(STDOUT_FILENO, buf, strlen(buf)); - } - - switch (ret = dbp->get(dbp, NULL, &key, &data, 0)) { - case DB_LOCK_DEADLOCK: /* Deadlock. */ - ++perf[id].aborts; - break; - case 0: /* Success. */ - ++perf[id].found; - free(data.data); - break; - case DB_NOTFOUND: /* Not found. */ - ++perf[id].notfound; - break; - default: - sprintf(buf, - "reader %d: dbp->get: %s", id, (char *)key.data); - fatal(buf, ret, 0); - } - } - return (0); -} - -int -writer(id) - int id; -{ - DBT key, data; - DB_TXN *tid; - time_t now, then; - int n, ret; - char buf[256], dbuf[10000]; - - time(&now); - then = now; - - /* - * DBT's must use local memory or malloc'd memory if the DB handle - * is accessed in a threaded fashion. - */ - memset(&key, 0, sizeof(DBT)); - memset(&data, 0, sizeof(DBT)); - data.data = dbuf; - data.ulen = sizeof(dbuf); - data.flags = DB_DBT_USERMEM; - - while (!quit) { - /* Pick a random key. */ - n = rand() % nlist; - key.data = list[n]; - key.size = strlen(key.data); - - if (verbose) { - sprintf(buf, "writer: %d: list entry %d\n", id, n); - write(STDOUT_FILENO, buf, strlen(buf)); - } - - /* Abort and retry. */ - if (0) { -retry: if ((ret = tid->abort(tid)) != 0) - fatal("DB_TXN->abort", ret, 1); - ++perf[id].aborts; - ++perf[id].aborted; - } - - /* Thread #1 prints out the stats every 20 seconds. */ - if (id == 1) { - time(&now); - if (now - then >= 20) { - stats(); - then = now; - } - } - - /* Begin the transaction. */ - if ((ret = dbenv->txn_begin(dbenv, NULL, &tid, 0)) != 0) - fatal("txn_begin", ret, 1); - - /* - * Get the key. If it doesn't exist, add it. If it does - * exist, delete it. - */ - switch (ret = dbp->get(dbp, tid, &key, &data, 0)) { - case DB_LOCK_DEADLOCK: - goto retry; - case 0: - goto delete; - case DB_NOTFOUND: - goto add; - } - - sprintf(buf, "writer: %d: dbp->get", id); - fatal(buf, ret, 1); - /* NOTREACHED */ - -delete: /* Delete the key. */ - switch (ret = dbp->del(dbp, tid, &key, 0)) { - case DB_LOCK_DEADLOCK: - goto retry; - case 0: - ++perf[id].deletes; - goto commit; - } - - sprintf(buf, "writer: %d: dbp->del", id); - fatal(buf, ret, 1); - /* NOTREACHED */ - -add: /* Add the key. 1 data item in 30 is an overflow item. */ - data.size = 20 + rand() % 128; - if (rand() % 30 == 0) - data.size += 8192; - - switch (ret = dbp->put(dbp, tid, &key, &data, 0)) { - case DB_LOCK_DEADLOCK: - goto retry; - case 0: - ++perf[id].adds; - goto commit; - default: - sprintf(buf, "writer: %d: dbp->put", id); - fatal(buf, ret, 1); - } - -commit: /* The transaction finished, commit it. */ - if ((ret = tid->commit(tid, 0)) != 0) - fatal("DB_TXN->commit", ret, 1); - - /* - * Every time the thread completes 20 transactions, show - * our progress. - */ - if (++perf[id].txns % 20 == 0) { - sprintf(buf, -"writer: %2d: adds: %4d: deletes: %4d: aborts: %4d: txns: %4d\n", - id, perf[id].adds, perf[id].deletes, - perf[id].aborts, perf[id].txns); - write(STDOUT_FILENO, buf, strlen(buf)); - } - - /* - * If this thread was aborted more than 5 times before - * the transaction finished, complain. - */ - if (perf[id].aborted > 5) { - sprintf(buf, -"writer: %2d: adds: %4d: deletes: %4d: aborts: %4d: txns: %4d: ABORTED: %2d\n", - id, perf[id].adds, perf[id].deletes, - perf[id].aborts, perf[id].txns, perf[id].aborted); - write(STDOUT_FILENO, buf, strlen(buf)); - } - perf[id].aborted = 0; - } - return (0); -} - -/* - * stats -- - * Display reader/writer thread statistics. To display the statistics - * for the mpool trickle or deadlock threads, use db_stat(1). - */ -void -stats() -{ - int id; - char *p, buf[8192]; - - p = buf + sprintf(buf, "-------------\n"); - for (id = 0; id < nreaders + nwriters;) - if (id++ < nwriters) - p += sprintf(p, - "writer: %2d: adds: %4d: deletes: %4d: aborts: %4d: txns: %4d\n", - id, perf[id].adds, - perf[id].deletes, perf[id].aborts, perf[id].txns); - else - p += sprintf(p, - "reader: %2d: found: %5d: notfound: %5d: aborts: %4d\n", - id, perf[id].found, - perf[id].notfound, perf[id].aborts); - p += sprintf(p, "-------------\n"); - - write(STDOUT_FILENO, buf, p - buf); -} - -/* - * db_init -- - * Initialize the environment. - */ -int -db_init(home) - const char *home; -{ - int ret; - - if ((ret = db_env_create(&dbenv, 0)) != 0) { - fprintf(stderr, - "%s: db_env_create: %s\n", progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - if (punish) { - (void)dbenv->set_flags(dbenv, DB_YIELDCPU, 1); - (void)db_env_set_func_yield(sched_yield); - } - - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, progname); - (void)dbenv->set_cachesize(dbenv, 0, 100 * 1024, 0); - (void)dbenv->set_lg_max(dbenv, 200000); - - if ((ret = dbenv->open(dbenv, home, - DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | - DB_INIT_MPOOL | DB_INIT_TXN | DB_THREAD, 0)) != 0) { - dbenv->err(dbenv, ret, NULL); - (void)dbenv->close(dbenv, 0); - return (EXIT_FAILURE); - } - - return (0); -} - -/* - * tstart -- - * Thread start function for readers and writers. - */ -void * -tstart(arg) - void *arg; -{ - pthread_t tid; - u_int id; - - id = (u_int)arg + 1; - - tid = pthread_self(); - - if (id <= (u_int)nwriters) { - printf("write thread %d starting: tid: %lu\n", id, (u_long)tid); - fflush(stdout); - writer(id); - } else { - printf("read thread %d starting: tid: %lu\n", id, (u_long)tid); - fflush(stdout); - reader(id); - } - - /* NOTREACHED */ - return (NULL); -} - -/* - * deadlock -- - * Thread start function for DB_ENV->lock_detect. - */ -void * -deadlock(arg) - void *arg; -{ - struct timeval t; - pthread_t tid; - - arg = arg; /* XXX: shut the compiler up. */ - tid = pthread_self(); - - printf("deadlock thread starting: tid: %lu\n", (u_long)tid); - fflush(stdout); - - t.tv_sec = 0; - t.tv_usec = 100000; - while (!quit) { - (void)dbenv->lock_detect(dbenv, 0, DB_LOCK_YOUNGEST, NULL); - - /* Check every 100ms. */ - (void)select(0, NULL, NULL, NULL, &t); - } - - return (NULL); -} - -/* - * trickle -- - * Thread start function for memp_trickle. - */ -void * -trickle(arg) - void *arg; -{ - pthread_t tid; - int wrote; - char buf[64]; - - arg = arg; /* XXX: shut the compiler up. */ - tid = pthread_self(); - - printf("trickle thread starting: tid: %lu\n", (u_long)tid); - fflush(stdout); - - while (!quit) { - (void)dbenv->memp_trickle(dbenv, 10, &wrote); - if (verbose) { - sprintf(buf, "trickle: wrote %d\n", wrote); - write(STDOUT_FILENO, buf, strlen(buf)); - } - if (wrote == 0) { - sleep(1); - sched_yield(); - } - } - - return (NULL); -} - -/* - * word -- - * Build the dictionary word list. - */ -void -word() -{ - FILE *fp; - int cnt; - char buf[256]; - - if ((fp = fopen(WORDLIST, "r")) == NULL) - fatal(WORDLIST, errno, 1); - - if ((list = malloc(nlist * sizeof(char *))) == NULL) - fatal(NULL, errno, 1); - - for (cnt = 0; cnt < nlist; ++cnt) { - if (fgets(buf, sizeof(buf), fp) == NULL) - break; - if ((list[cnt] = strdup(buf)) == NULL) - fatal(NULL, errno, 1); - } - nlist = cnt; /* In case nlist was larger than possible. */ -} - -/* - * fatal -- - * Report a fatal error and quit. - */ -void -fatal(msg, err, syserr) - const char *msg; - int err, syserr; -{ - fprintf(stderr, "%s: ", progname); - if (msg != NULL) { - fprintf(stderr, "%s", msg); - if (syserr) - fprintf(stderr, ": "); - } - if (syserr) - fprintf(stderr, "%s", strerror(err)); - fprintf(stderr, "\n"); - exit(EXIT_FAILURE); - - /* NOTREACHED */ -} - -/* - * usage -- - * Usage message. - */ -int -usage() -{ - (void)fprintf(stderr, - "usage: %s [-pv] [-h home] [-n words] [-r readers] [-w writers]\n", - progname); - return (EXIT_FAILURE); -} - -/* - * onint -- - * Interrupt signal handler. - */ -void -onint(signo) - int signo; -{ - signo = 0; /* Quiet compiler. */ - quit = 1; -} diff --git a/bdb/examples_c/ex_tpcb.c b/bdb/examples_c/ex_tpcb.c deleted file mode 100644 index 017cfeb5bdd..00000000000 --- a/bdb/examples_c/ex_tpcb.c +++ /dev/null @@ -1,698 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1997-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_tpcb.c,v 11.42 2002/08/06 05:39:00 bostic Exp $ - */ - -#include <sys/types.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#ifdef _WIN32 -extern int getopt(int, char * const *, const char *); -#else -#include <unistd.h> -#endif - -#include <db.h> - -typedef enum { ACCOUNT, BRANCH, TELLER } FTYPE; - -DB_ENV *db_init __P((const char *, const char *, int, int, u_int32_t)); -int hpopulate __P((DB *, int, int, int, int)); -int populate __P((DB *, u_int32_t, u_int32_t, int, const char *)); -u_int32_t random_id __P((FTYPE, int, int, int)); -u_int32_t random_int __P((u_int32_t, u_int32_t)); -int tp_populate __P((DB_ENV *, int, int, int, int, int)); -int tp_run __P((DB_ENV *, int, int, int, int, int)); -int tp_txn __P((DB_ENV *, DB *, DB *, DB *, DB *, int, int, int, int)); - -int invarg __P((const char *, int, const char *)); -int main __P((int, char *[])); -int usage __P((const char *)); - -/* - * This program implements a basic TPC/B driver program. To create the - * TPC/B database, run with the -i (init) flag. The number of records - * with which to populate the account, history, branch, and teller tables - * is specified by the a, s, b, and t flags respectively. To run a TPC/B - * test, use the n flag to indicate a number of transactions to run (note - * that you can run many of these processes in parallel to simulate a - * multiuser test run). - */ -#define TELLERS_PER_BRANCH 10 -#define ACCOUNTS_PER_TELLER 10000 -#define HISTORY_PER_BRANCH 2592000 - -/* - * The default configuration that adheres to TPCB scaling rules requires - * nearly 3 GB of space. To avoid requiring that much space for testing, - * we set the parameters much lower. If you want to run a valid 10 TPS - * configuration, define VALID_SCALING. - */ -#ifdef VALID_SCALING -#define ACCOUNTS 1000000 -#define BRANCHES 10 -#define TELLERS 100 -#define HISTORY 25920000 -#endif - -#ifdef TINY -#define ACCOUNTS 1000 -#define BRANCHES 10 -#define TELLERS 100 -#define HISTORY 10000 -#endif - -#ifdef VERY_TINY -#define ACCOUNTS 500 -#define BRANCHES 10 -#define TELLERS 50 -#define HISTORY 5000 -#endif - -#if !defined(VALID_SCALING) && !defined(TINY) && !defined(VERY_TINY) -#define ACCOUNTS 100000 -#define BRANCHES 10 -#define TELLERS 100 -#define HISTORY 259200 -#endif - -#define HISTORY_LEN 100 -#define RECLEN 100 -#define BEGID 1000000 - -typedef struct _defrec { - u_int32_t id; - u_int32_t balance; - u_int8_t pad[RECLEN - sizeof(u_int32_t) - sizeof(u_int32_t)]; -} defrec; - -typedef struct _histrec { - u_int32_t aid; - u_int32_t bid; - u_int32_t tid; - u_int32_t amount; - u_int8_t pad[RECLEN - 4 * sizeof(u_int32_t)]; -} histrec; - -int -main(argc, argv) - int argc; - char *argv[]; -{ - extern char *optarg; - extern int optind; - DB_ENV *dbenv; - int accounts, branches, seed, tellers, history; - int ch, iflag, mpool, ntxns, ret, txn_no_sync, verbose; - const char *home, *progname; - - home = "TESTDIR"; - progname = "ex_tpcb"; - accounts = branches = history = tellers = 0; - iflag = mpool = ntxns = txn_no_sync = verbose = 0; - seed = (int)time(NULL); - - while ((ch = getopt(argc, argv, "a:b:c:fh:in:S:s:t:v")) != EOF) - switch (ch) { - case 'a': /* Number of account records */ - if ((accounts = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 'b': /* Number of branch records */ - if ((branches = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 'c': /* Cachesize in bytes */ - if ((mpool = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 'f': /* Fast mode: no txn sync. */ - txn_no_sync = 1; - break; - case 'h': /* DB home. */ - home = optarg; - break; - case 'i': /* Initialize the test. */ - iflag = 1; - break; - case 'n': /* Number of transactions */ - if ((ntxns = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 'S': /* Random number seed. */ - if ((seed = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 's': /* Number of history records */ - if ((history = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 't': /* Number of teller records */ - if ((tellers = atoi(optarg)) <= 0) - return (invarg(progname, ch, optarg)); - break; - case 'v': /* Verbose option. */ - verbose = 1; - break; - case '?': - default: - return (usage(progname)); - } - argc -= optind; - argv += optind; - - srand((u_int)seed); - - /* Initialize the database environment. */ - if ((dbenv = db_init(home, - progname, mpool, iflag, txn_no_sync ? DB_TXN_NOSYNC : 0)) == NULL) - return (EXIT_FAILURE); - - accounts = accounts == 0 ? ACCOUNTS : accounts; - branches = branches == 0 ? BRANCHES : branches; - tellers = tellers == 0 ? TELLERS : tellers; - history = history == 0 ? HISTORY : history; - - if (verbose) - printf("%ld Accounts, %ld Branches, %ld Tellers, %ld History\n", - (long)accounts, (long)branches, - (long)tellers, (long)history); - - if (iflag) { - if (ntxns != 0) - return (usage(progname)); - tp_populate(dbenv, - accounts, branches, history, tellers, verbose); - } else { - if (ntxns == 0) - return (usage(progname)); - tp_run(dbenv, ntxns, accounts, branches, tellers, verbose); - } - - if ((ret = dbenv->close(dbenv, 0)) != 0) { - fprintf(stderr, "%s: dbenv->close failed: %s\n", - progname, db_strerror(ret)); - return (EXIT_FAILURE); - } - - return (EXIT_SUCCESS); -} - -int -invarg(progname, arg, str) - const char *progname; - int arg; - const char *str; -{ - (void)fprintf(stderr, - "%s: invalid argument for -%c: %s\n", progname, arg, str); - return (EXIT_FAILURE); -} - -int -usage(progname) - const char *progname; -{ - const char *a1, *a2; - - a1 = "[-fv] [-a accounts] [-b branches]\n"; - a2 = "\t[-c cache_size] [-h home] [-S seed] [-s history] [-t tellers]"; - (void)fprintf(stderr, "usage: %s -i %s %s\n", progname, a1, a2); - (void)fprintf(stderr, - " %s -n transactions %s %s\n", progname, a1, a2); - return (EXIT_FAILURE); -} - -/* - * db_init -- - * Initialize the environment. - */ -DB_ENV * -db_init(home, prefix, cachesize, initializing, flags) - const char *home, *prefix; - int cachesize, initializing; - u_int32_t flags; -{ - DB_ENV *dbenv; - u_int32_t local_flags; - int ret; - - if ((ret = db_env_create(&dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_env_create"); - return (NULL); - } - dbenv->set_errfile(dbenv, stderr); - dbenv->set_errpfx(dbenv, prefix); - (void)dbenv->set_cachesize(dbenv, 0, - cachesize == 0 ? 4 * 1024 * 1024 : (u_int32_t)cachesize, 0); - - if (flags & (DB_TXN_NOSYNC)) - (void)dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1); - flags &= ~(DB_TXN_NOSYNC); - - local_flags = flags | DB_CREATE | (initializing ? DB_INIT_MPOOL : - DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL); - if ((ret = dbenv->open(dbenv, home, local_flags, 0)) != 0) { - dbenv->err(dbenv, ret, "DB_ENV->open: %s", home); - (void)dbenv->close(dbenv, 0); - return (NULL); - } - return (dbenv); -} - -/* - * Initialize the database to the specified number of accounts, branches, - * history records, and tellers. - */ -int -tp_populate(env, accounts, branches, history, tellers, verbose) - DB_ENV *env; - int accounts, branches, history, tellers, verbose; -{ - DB *dbp; - u_int32_t balance, idnum, oflags; - u_int32_t end_anum, end_bnum, end_tnum; - u_int32_t start_anum, start_bnum, start_tnum; - int ret; - - idnum = BEGID; - balance = 500000; - oflags = DB_CREATE | DB_TRUNCATE; - - if ((ret = db_create(&dbp, env, 0)) != 0) { - env->err(env, ret, "db_create"); - return (1); - } - (void)dbp->set_h_nelem(dbp, (u_int32_t)accounts); - - if ((ret = dbp->open(dbp, NULL, "account", NULL, - DB_HASH, oflags, 0644)) != 0) { - env->err(env, ret, "DB->open: account"); - return (1); - } - - start_anum = idnum; - populate(dbp, idnum, balance, accounts, "account"); - idnum += accounts; - end_anum = idnum - 1; - if ((ret = dbp->close(dbp, 0)) != 0) { - env->err(env, ret, "DB->close: account"); - return (1); - } - if (verbose) - printf("Populated accounts: %ld - %ld\n", - (long)start_anum, (long)end_anum); - - /* - * Since the number of branches is very small, we want to use very - * small pages and only 1 key per page, i.e., key-locking instead - * of page locking. - */ - if ((ret = db_create(&dbp, env, 0)) != 0) { - env->err(env, ret, "db_create"); - return (1); - } - (void)dbp->set_h_ffactor(dbp, 1); - (void)dbp->set_h_nelem(dbp, (u_int32_t)branches); - (void)dbp->set_pagesize(dbp, 512); - if ((ret = dbp->open(dbp, NULL, "branch", NULL, - DB_HASH, oflags, 0644)) != 0) { - env->err(env, ret, "DB->open: branch"); - return (1); - } - start_bnum = idnum; - populate(dbp, idnum, balance, branches, "branch"); - idnum += branches; - end_bnum = idnum - 1; - if ((ret = dbp->close(dbp, 0)) != 0) { - env->err(env, ret, "DB->close: branch"); - return (1); - } - if (verbose) - printf("Populated branches: %ld - %ld\n", - (long)start_bnum, (long)end_bnum); - - /* - * In the case of tellers, we also want small pages, but we'll let - * the fill factor dynamically adjust itself. - */ - if ((ret = db_create(&dbp, env, 0)) != 0) { - env->err(env, ret, "db_create"); - return (1); - } - (void)dbp->set_h_ffactor(dbp, 0); - (void)dbp->set_h_nelem(dbp, (u_int32_t)tellers); - (void)dbp->set_pagesize(dbp, 512); - if ((ret = dbp->open(dbp, NULL, "teller", NULL, - DB_HASH, oflags, 0644)) != 0) { - env->err(env, ret, "DB->open: teller"); - return (1); - } - - start_tnum = idnum; - populate(dbp, idnum, balance, tellers, "teller"); - idnum += tellers; - end_tnum = idnum - 1; - if ((ret = dbp->close(dbp, 0)) != 0) { - env->err(env, ret, "DB->close: teller"); - return (1); - } - if (verbose) - printf("Populated tellers: %ld - %ld\n", - (long)start_tnum, (long)end_tnum); - - if ((ret = db_create(&dbp, env, 0)) != 0) { - env->err(env, ret, "db_create"); - return (1); - } - (void)dbp->set_re_len(dbp, HISTORY_LEN); - if ((ret = dbp->open(dbp, NULL, "history", NULL, - DB_RECNO, oflags, 0644)) != 0) { - env->err(env, ret, "DB->open: history"); - return (1); - } - - hpopulate(dbp, history, accounts, branches, tellers); - if ((ret = dbp->close(dbp, 0)) != 0) { - env->err(env, ret, "DB->close: history"); - return (1); - } - return (0); -} - -int -populate(dbp, start_id, balance, nrecs, msg) - DB *dbp; - u_int32_t start_id, balance; - int nrecs; - const char *msg; -{ - DBT kdbt, ddbt; - defrec drec; - int i, ret; - - kdbt.flags = 0; - kdbt.data = &drec.id; - kdbt.size = sizeof(u_int32_t); - ddbt.flags = 0; - ddbt.data = &drec; - ddbt.size = sizeof(drec); - memset(&drec.pad[0], 1, sizeof(drec.pad)); - - for (i = 0; i < nrecs; i++) { - drec.id = start_id + (u_int32_t)i; - drec.balance = balance; - if ((ret = - (dbp->put)(dbp, NULL, &kdbt, &ddbt, DB_NOOVERWRITE)) != 0) { - dbp->err(dbp, - ret, "Failure initializing %s file\n", msg); - return (1); - } - } - return (0); -} - -int -hpopulate(dbp, history, accounts, branches, tellers) - DB *dbp; - int history, accounts, branches, tellers; -{ - DBT kdbt, ddbt; - histrec hrec; - db_recno_t key; - int i, ret; - - memset(&kdbt, 0, sizeof(kdbt)); - memset(&ddbt, 0, sizeof(ddbt)); - ddbt.data = &hrec; - ddbt.size = sizeof(hrec); - kdbt.data = &key; - kdbt.size = sizeof(key); - memset(&hrec.pad[0], 1, sizeof(hrec.pad)); - hrec.amount = 10; - - for (i = 1; i <= history; i++) { - hrec.aid = random_id(ACCOUNT, accounts, branches, tellers); - hrec.bid = random_id(BRANCH, accounts, branches, tellers); - hrec.tid = random_id(TELLER, accounts, branches, tellers); - if ((ret = dbp->put(dbp, NULL, &kdbt, &ddbt, DB_APPEND)) != 0) { - dbp->err(dbp, ret, "dbp->put"); - return (1); - } - } - return (0); -} - -u_int32_t -random_int(lo, hi) - u_int32_t lo, hi; -{ - u_int32_t ret; - int t; - -#ifndef RAND_MAX -#define RAND_MAX 0x7fffffff -#endif - t = rand(); - ret = (u_int32_t)(((double)t / ((double)(RAND_MAX) + 1)) * - (hi - lo + 1)); - ret += lo; - return (ret); -} - -u_int32_t -random_id(type, accounts, branches, tellers) - FTYPE type; - int accounts, branches, tellers; -{ - u_int32_t min, max, num; - - max = min = BEGID; - num = accounts; - switch(type) { - case TELLER: - min += branches; - num = tellers; - /* FALLTHROUGH */ - case BRANCH: - if (type == BRANCH) - num = branches; - min += accounts; - /* FALLTHROUGH */ - case ACCOUNT: - max = min + num - 1; - } - return (random_int(min, max)); -} - -int -tp_run(dbenv, n, accounts, branches, tellers, verbose) - DB_ENV *dbenv; - int n, accounts, branches, tellers, verbose; -{ - DB *adb, *bdb, *hdb, *tdb; - double gtps, itps; - int failed, ifailed, ret, txns; - time_t starttime, curtime, lasttime; - - adb = bdb = hdb = tdb = NULL; - txns = failed = 0; - - /* - * Open the database files. - */ - if ((ret = db_create(&adb, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - if ((ret = adb->open(adb, NULL, "account", NULL, DB_UNKNOWN, - DB_AUTO_COMMIT, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open: account"); - goto err; - } - if ((ret = db_create(&bdb, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - if ((ret = bdb->open(bdb, NULL, "branch", NULL, DB_UNKNOWN, - DB_AUTO_COMMIT, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open: branch"); - goto err; - } - if ((ret = db_create(&hdb, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - if ((ret = hdb->open(hdb, NULL, "history", NULL, DB_UNKNOWN, - DB_AUTO_COMMIT, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open: history"); - goto err; - } - if ((ret = db_create(&tdb, dbenv, 0)) != 0) { - dbenv->err(dbenv, ret, "db_create"); - goto err; - } - if ((ret = tdb->open(tdb, NULL, "teller", NULL, DB_UNKNOWN, - DB_AUTO_COMMIT, 0)) != 0) { - dbenv->err(dbenv, ret, "DB->open: teller"); - goto err; - } - - starttime = time(NULL); - lasttime = starttime; - for (ifailed = 0; n-- > 0;) { - txns++; - ret = tp_txn(dbenv, adb, bdb, tdb, hdb, - accounts, branches, tellers, verbose); - if (ret != 0) { - failed++; - ifailed++; - } - if (n % 5000 == 0) { - curtime = time(NULL); - gtps = (double)(txns - failed) / (curtime - starttime); - itps = (double)(5000 - ifailed) / (curtime - lasttime); - printf("%d txns %d failed ", txns, failed); - printf("%6.2f TPS (gross) %6.2f TPS (interval)\n", - gtps, itps); - lasttime = curtime; - ifailed = 0; - } - } - -err: if (adb != NULL) - (void)adb->close(adb, 0); - if (bdb != NULL) - (void)bdb->close(bdb, 0); - if (tdb != NULL) - (void)tdb->close(tdb, 0); - if (hdb != NULL) - (void)hdb->close(hdb, 0); - - printf("%ld transactions begun %ld failed\n", (long)txns, (long)failed); - return (ret == 0 ? 0 : 1); -} - -/* - * XXX Figure out the appropriate way to pick out IDs. - */ -int -tp_txn(dbenv, adb, bdb, tdb, hdb, accounts, branches, tellers, verbose) - DB_ENV *dbenv; - DB *adb, *bdb, *tdb, *hdb; - int accounts, branches, tellers, verbose; -{ - DBC *acurs, *bcurs, *tcurs; - DBT d_dbt, d_histdbt, k_dbt, k_histdbt; - DB_TXN *t; - db_recno_t key; - defrec rec; - histrec hrec; - int account, branch, teller, ret; - - t = NULL; - acurs = bcurs = tcurs = NULL; - - /* - * XXX We could move a lot of this into the driver to make this - * faster. - */ - account = random_id(ACCOUNT, accounts, branches, tellers); - branch = random_id(BRANCH, accounts, branches, tellers); - teller = random_id(TELLER, accounts, branches, tellers); - - memset(&d_histdbt, 0, sizeof(d_histdbt)); - - memset(&k_histdbt, 0, sizeof(k_histdbt)); - k_histdbt.data = &key; - k_histdbt.size = sizeof(key); - - memset(&k_dbt, 0, sizeof(k_dbt)); - k_dbt.size = sizeof(int); - - memset(&d_dbt, 0, sizeof(d_dbt)); - d_dbt.flags = DB_DBT_USERMEM; - d_dbt.data = &rec; - d_dbt.ulen = sizeof(rec); - - hrec.aid = account; - hrec.bid = branch; - hrec.tid = teller; - hrec.amount = 10; - /* Request 0 bytes since we're just positioning. */ - d_histdbt.flags = DB_DBT_PARTIAL; - - /* START TIMING */ - if (dbenv->txn_begin(dbenv, NULL, &t, 0) != 0) - goto err; - - if (adb->cursor(adb, t, &acurs, 0) != 0 || - bdb->cursor(bdb, t, &bcurs, 0) != 0 || - tdb->cursor(tdb, t, &tcurs, 0) != 0) - goto err; - - /* Account record */ - k_dbt.data = &account; - if (acurs->c_get(acurs, &k_dbt, &d_dbt, DB_SET) != 0) - goto err; - rec.balance += 10; - if (acurs->c_put(acurs, &k_dbt, &d_dbt, DB_CURRENT) != 0) - goto err; - - /* Branch record */ - k_dbt.data = &branch; - if (bcurs->c_get(bcurs, &k_dbt, &d_dbt, DB_SET) != 0) - goto err; - rec.balance += 10; - if (bcurs->c_put(bcurs, &k_dbt, &d_dbt, DB_CURRENT) != 0) - goto err; - - /* Teller record */ - k_dbt.data = &teller; - if (tcurs->c_get(tcurs, &k_dbt, &d_dbt, DB_SET) != 0) - goto err; - rec.balance += 10; - if (tcurs->c_put(tcurs, &k_dbt, &d_dbt, DB_CURRENT) != 0) - goto err; - - /* History record */ - d_histdbt.flags = 0; - d_histdbt.data = &hrec; - d_histdbt.ulen = sizeof(hrec); - if (hdb->put(hdb, t, &k_histdbt, &d_histdbt, DB_APPEND) != 0) - goto err; - - if (acurs->c_close(acurs) != 0 || bcurs->c_close(bcurs) != 0 || - tcurs->c_close(tcurs) != 0) - goto err; - - ret = t->commit(t, 0); - t = NULL; - if (ret != 0) - goto err; - - /* END TIMING */ - return (0); - -err: if (acurs != NULL) - (void)acurs->c_close(acurs); - if (bcurs != NULL) - (void)bcurs->c_close(bcurs); - if (tcurs != NULL) - (void)tcurs->c_close(tcurs); - if (t != NULL) - (void)t->abort(t); - - if (verbose) - printf("Transaction A=%ld B=%ld T=%ld failed\n", - (long)account, (long)branch, (long)teller); - return (-1); -} diff --git a/bdb/examples_c/ex_tpcb.h b/bdb/examples_c/ex_tpcb.h deleted file mode 100644 index 22b79c37e80..00000000000 --- a/bdb/examples_c/ex_tpcb.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * See the file LICENSE for redistribution information. - * - * Copyright (c) 1996-2002 - * Sleepycat Software. All rights reserved. - * - * $Id: ex_tpcb.h,v 11.6 2002/01/11 15:52:06 bostic Exp $ - */ - -#ifndef _TPCB_H_ -#define _TPCB_H_ - -typedef enum { ACCOUNT, BRANCH, TELLER } FTYPE; - -#define TELLERS_PER_BRANCH 100 -#define ACCOUNTS_PER_TELLER 1000 - -#define ACCOUNTS 1000000 -#define BRANCHES 10 -#define TELLERS 1000 -#define HISTORY 1000000 -#define HISTORY_LEN 100 -#define RECLEN 100 -#define BEGID 1000000 - -typedef struct _defrec { - u_int32_t id; - u_int32_t balance; - u_int8_t pad[RECLEN - sizeof(u_int32_t) - sizeof(u_int32_t)]; -} defrec; - -typedef struct _histrec { - u_int32_t aid; - u_int32_t bid; - u_int32_t tid; - u_int32_t amount; - u_int8_t pad[RECLEN - 4 * sizeof(u_int32_t)]; -} histrec; -#endif /* _TPCB_H_ */ |