1/*
2 * $Id: b_put.c,v 1.15 2008/01/31 17:01:22 bostic Exp $
3 */
4#include "bench.h"
5
6static int b_put_usage(void);
7static int b_put_secondary(DB *, const DBT *, const DBT *, DBT *);
8
9int
10b_put(int argc, char *argv[])
11{
12	extern char *optarg;
13	extern int optind, __db_getopt_reset;
14	DB_ENV *dbenv;
15	DB *dbp, **second;
16	DBTYPE type;
17	DBT key, data;
18	db_recno_t recno;
19	u_int32_t cachesize;
20	int ch, dsize, i, count, secondaries;
21	char *ts, buf[64];
22
23	second = NULL;
24	type = DB_BTREE;
25	cachesize = MEGABYTE;
26	dsize = 20;
27	count = 100000;
28	secondaries = 0;
29	ts = "Btree";
30	__db_getopt_reset = 1;
31	while ((ch = getopt(argc, argv, "C:c:d:s:t:")) != EOF)
32		switch (ch) {
33		case 'C':
34			cachesize = (u_int32_t)atoi(optarg);
35			break;
36		case 'c':
37			count = atoi(optarg);
38			break;
39		case 'd':
40			dsize = atoi(optarg);
41			break;
42		case 's':
43			secondaries = atoi(optarg);
44			break;
45		case 't':
46			switch (optarg[0]) {
47			case 'B': case 'b':
48				ts = "Btree";
49				type = DB_BTREE;
50				break;
51			case 'H': case 'h':
52				if (b_util_have_hash())
53					return (0);
54				ts = "Hash";
55				type = DB_HASH;
56				break;
57			case 'Q': case 'q':
58				if (b_util_have_queue())
59					return (0);
60				ts = "Queue";
61				type = DB_QUEUE;
62				break;
63			case 'R': case 'r':
64				ts = "Recno";
65				type = DB_RECNO;
66				break;
67			default:
68				return (b_put_usage());
69			}
70			break;
71		case '?':
72		default:
73			return (b_put_usage());
74		}
75	argc -= optind;
76	argv += optind;
77	if (argc != 0)
78		return (b_put_usage());
79
80#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 3
81	/*
82	 * Secondaries were added after DB 3.2.9.
83	 */
84	if (secondaries)
85		return (0);
86#endif
87
88	/* Create the environment. */
89	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
90	dbenv->set_errfile(dbenv, stderr);
91	DB_BENCH_ASSERT(dbenv->set_cachesize(dbenv, 0, cachesize, 0) == 0);
92#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1
93	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
94	    NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
95#else
96	DB_BENCH_ASSERT(dbenv->open(dbenv, TESTDIR,
97	    DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);
98#endif
99
100	/*
101	 * Create the database.
102	 * Optionally set the record length for Queue.
103	 */
104	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
105	if (type == DB_QUEUE)
106		DB_BENCH_ASSERT(dbp->set_re_len(dbp, (u_int32_t)dsize) == 0);
107#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
108	DB_BENCH_ASSERT(
109	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
110#else
111	DB_BENCH_ASSERT(
112	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
113#endif
114
115	/* Optionally create the secondaries. */
116	if (secondaries != 0) {
117		DB_BENCH_ASSERT((second =
118		    calloc(sizeof(DB *), (size_t)secondaries)) != NULL);
119		for (i = 0; i < secondaries; ++i) {
120			DB_BENCH_ASSERT(db_create(&second[i], dbenv, 0) == 0);
121			snprintf(buf, sizeof(buf), "%d.db", i);
122#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
123			DB_BENCH_ASSERT(second[i]->open(second[i], NULL,
124			    buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0);
125#else
126			DB_BENCH_ASSERT(second[i]->open(second[i],
127			    buf, NULL, DB_BTREE, DB_CREATE, 0600) == 0);
128#endif
129#if DB_VERSION_MAJOR > 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR >= 3
130#if DB_VERSION_MAJOR > 3 && DB_VERSION_MINOR > 0
131			/*
132			 * The DB_TXN argument to Db.associate was added in
133			 * 4.1.25.
134			 */
135			DB_BENCH_ASSERT(dbp->associate(
136			    dbp, NULL, second[i], b_put_secondary, 0) == 0);
137#else
138			DB_BENCH_ASSERT(dbp->associate(
139			    dbp, second[i], b_put_secondary, 0) == 0);
140#endif
141#endif
142		}
143	}
144
145	/* Store a key/data pair. */
146	memset(&key, 0, sizeof(key));
147	memset(&data, 0, sizeof(data));
148	switch (type) {
149	case DB_BTREE:
150	case DB_HASH:
151		key.data = "01234567890123456789";
152		key.size = 20;
153		break;
154	case DB_QUEUE:
155	case DB_RECNO:
156		recno = 1;
157		key.data = &recno;
158		key.size = sizeof(recno);
159		break;
160	case DB_UNKNOWN:
161		b_util_abort();
162		break;
163	}
164
165	DB_BENCH_ASSERT(
166	    (data.data = malloc(data.size = (size_t)dsize)) != NULL);
167
168	/* Store the key/data pair count times. */
169	TIMER_START;
170	for (i = 0; i < count; ++i)
171		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
172	TIMER_STOP;
173
174	if (type == DB_BTREE || type == DB_HASH)
175		printf(
176		    "# %d %s database put of 10 byte key, %lu byte data",
177		    count, ts, (u_long)dsize);
178	else
179		printf("# %d %s database put of key, %lu byte data",
180		    count, ts, (u_long)dsize);
181	if (secondaries)
182		printf(" with %d secondaries", secondaries);
183	printf("\n");
184	TIMER_DISPLAY(count);
185
186	if (second != NULL) {
187		for (i = 0; i < secondaries; ++i)
188			DB_BENCH_ASSERT(second[i]->close(second[i], 0) == 0);
189		free(second);
190	}
191
192	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
193	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
194
195	return (0);
196}
197
198static int
199b_put_secondary(dbp, pkey, pdata, skey)
200	DB *dbp;
201	const DBT *pkey, *pdata;
202	DBT *skey;
203{
204	skey->data = pkey->data;
205	skey->size = pkey->size;
206
207	COMPQUIET(dbp, NULL);
208	COMPQUIET(pdata, NULL);
209	return (0);
210}
211
212static int
213b_put_usage()
214{
215	(void)fprintf(stderr, "usage: b_put %s\n",
216	    "[-C cachesz] [-c count] [-d bytes] [-s secondaries] [-t type]");
217	return (EXIT_FAILURE);
218}
219