1/*
2 * $Id: b_recover.c,v 1.12 2008/03/13 20:47:06 mbrey Exp $
3 */
4#include "bench.h"
5
6static int b_recover_usage(void);
7
8int
9b_recover(int argc, char *argv[])
10{
11	extern char *optarg;
12	extern int optind, __db_getopt_reset;
13	DB *dbp;
14	DBT key, data;
15	DB_ENV *dbenv;
16	DB_TXN *txn;
17	u_int32_t cachesize;
18	int ch, i, count;
19
20	/*
21	 * Recover was too slow before release 4.0 that it's not worth
22	 * running the test.
23	 */
24#if DB_VERSION_MAJOR < 4
25	return (0);
26#endif
27	cachesize = MEGABYTE;
28	count = 1000;
29	__db_getopt_reset = 1;
30	while ((ch = getopt(argc, argv, "C:c:")) != EOF)
31		switch (ch) {
32		case 'C':
33			cachesize = (u_int32_t)atoi(optarg);
34			break;
35		case 'c':
36			count = atoi(optarg);
37			break;
38		case '?':
39		default:
40			return (b_recover_usage());
41		}
42	argc -= optind;
43	argv += optind;
44	if (argc != 0)
45		return (b_recover_usage());
46
47	/* Create the environment. */
48	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
49	dbenv->set_errfile(dbenv, stderr);
50	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0);
51
52#define	OFLAGS								\
53	(DB_CREATE | DB_INIT_LOCK |					\
54	DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN | DB_PRIVATE)
55#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
56	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, NULL, OFLAGS, 0666) == 0);
57#endif
58#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
59	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
60#endif
61#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
62	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR, OFLAGS, 0666) == 0);
63#endif
64
65	/* Create the database. */
66	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
67#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
68	DB_BENCH_ASSERT(dbp->open(dbp, NULL,
69	    TESTFILE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0666) == 0);
70#else
71	DB_BENCH_ASSERT(
72	    dbp->open(dbp, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
73#endif
74
75	/* Initialize the data. */
76	memset(&key, 0, sizeof(key));
77	memset(&data, 0, sizeof(data));
78	key.size = data.size = 20;
79	key.data = data.data = "01234567890123456789";
80
81	/* Start/commit a transaction count times. */
82	for (i = 0; i < count; ++i) {
83#if DB_VERSION_MAJOR < 4
84		DB_BENCH_ASSERT(
85		    txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
86		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
87		DB_BENCH_ASSERT(txn_commit(txn, 0) == 0);
88#else
89		DB_BENCH_ASSERT(
90		    dbenv->txn_begin(dbenv, NULL, &txn, DB_TXN_NOSYNC) == 0);
91		DB_BENCH_ASSERT(dbp->put(dbp, txn, &key, &data, 0) == 0);
92		DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
93#endif
94	}
95
96	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
97	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
98
99	/* Create a new DB_ENV handle. */
100	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
101	dbenv->set_errfile(dbenv, stderr);
102	DB_BENCH_ASSERT(
103	    dbenv->set_cachesize(dbenv, 0, 1048576 /* 1MB */, 0) == 0);
104
105	/* Now run recovery. */
106	TIMER_START;
107#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 0
108	DB_BENCH_ASSERT(dbenv->open(
109	    dbenv, TESTDIR, NULL, OFLAGS | DB_RECOVER, 0666) == 0);
110#endif
111#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR == 1
112	DB_BENCH_ASSERT(
113	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
114#endif
115#if DB_VERSION_MAJOR > 3 || DB_VERSION_MINOR > 1
116	DB_BENCH_ASSERT(
117	    dbenv->open(dbenv, TESTDIR, OFLAGS | DB_RECOVER, 0666) == 0);
118#endif
119	TIMER_STOP;
120
121	/*
122	 * We divide the time by the number of transactions, so an "operation"
123	 * is the recovery of a single transaction.
124	 */
125	printf("# recovery after %d transactions\n", count);
126	TIMER_DISPLAY(count);
127
128	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
129
130	return (0);
131}
132
133static int
134b_recover_usage()
135{
136	(void)fprintf(stderr, "usage: b_recover [-C cachesz] [-c count]\n");
137	return (EXIT_FAILURE);
138}
139