1/*
2 * $Id: b_load.c,v 1.13 2007/12/21 13:58:30 bostic Exp $
3 */
4#include "bench.h"
5
6static int usage(void);
7
8int
9b_load(int argc, char *argv[])
10{
11	extern char *optarg;
12	extern int optind;
13	DB *dbp;
14	DBTYPE type;
15	DBT key, data;
16	db_recno_t recno;
17	u_int32_t cachesize;
18	int ch, i, count, duplicate;
19	char *ts, buf[32];
20
21	type = DB_BTREE;
22	cachesize = MEGABYTE;
23	count = 100000;
24	duplicate = 0;
25	ts = "Btree";
26	while ((ch = getopt(argc, argv, "C:c:dt:")) != EOF)
27		switch (ch) {
28		case 'C':
29			cachesize = (u_int32_t)atoi(optarg);
30			break;
31		case 'c':
32			count = atoi(optarg);
33			break;
34		case 'd':
35			duplicate = 1;
36			break;
37		case 't':
38			switch (optarg[0]) {
39			case 'B': case 'b':
40				ts = "Btree";
41				type = DB_BTREE;
42				break;
43			case 'H': case 'h':
44				if (b_util_have_hash())
45					return (0);
46				ts = "Hash";
47				type = DB_HASH;
48				break;
49			case 'Q': case 'q':
50				if (b_util_have_queue())
51					return (0);
52				ts = "Queue";
53				type = DB_QUEUE;
54				break;
55			case 'R': case 'r':
56				ts = "Recno";
57				type = DB_RECNO;
58				break;
59			default:
60				return (usage());
61			}
62			break;
63		case '?':
64		default:
65			return (usage());
66		}
67	argc -= optind;
68	argv += optind;
69	if (argc != 0)
70		return (usage());
71
72	/* Usage. */
73	if (duplicate && (type == DB_QUEUE || type == DB_RECNO)) {
74		fprintf(stderr,
75		    "b_load: Queue an Recno don't support duplicates\n");
76		return (usage());
77	}
78
79#if DB_VERSION_MAJOR < 3 || DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1
80	/*
81	 * DB versions prior to 3.1.17 didn't have off-page duplicates, so
82	 * this test can run forever.
83	 */
84	if (duplicate)
85		return (0);
86#endif
87
88	/* Create the database. */
89	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
90	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 0) == 0);
91	if (duplicate)
92		DB_BENCH_ASSERT(dbp->set_flags(dbp, DB_DUP) == 0);
93	dbp->set_errfile(dbp, stderr);
94
95	/* Set record length for Queue. */
96	if (type == DB_QUEUE)
97		DB_BENCH_ASSERT(dbp->set_re_len(dbp, 20) == 0);
98
99#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1
100	DB_BENCH_ASSERT(
101	    dbp->open(dbp, NULL, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
102#else
103	DB_BENCH_ASSERT(
104	    dbp->open(dbp, TESTFILE, NULL, type, DB_CREATE, 0666) == 0);
105#endif
106
107	/* Initialize the data. */
108	memset(&key, 0, sizeof(key));
109	memset(&data, 0, sizeof(data));
110
111	/* Insert count in-order key/data pairs. */
112	TIMER_START;
113	if (duplicate) {
114		key.size = 10;
115		key.data = "01234567890123456789";
116		data.data = buf;
117		data.size = 20;
118		for (i = 0; i < count; ++i) {
119			(void)snprintf(buf, sizeof(buf), "%020d", i);
120			DB_BENCH_ASSERT(
121			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
122		}
123	} else {
124		data.data = buf;
125		data.size = 20;
126		if (type == DB_BTREE || type == DB_HASH) {
127			key.size = 10;
128			key.data = buf;
129			for (i = 0; i < count; ++i) {
130				(void)snprintf(buf, sizeof(buf), "%010d", i);
131				DB_BENCH_ASSERT(
132				    dbp->put(dbp, NULL, &key, &data, 0) == 0);
133			}
134		} else {
135			key.data = &recno;
136			key.size = sizeof(recno);
137			for (i = 0, recno = 1; i < count; ++i, ++recno)
138				DB_BENCH_ASSERT(
139				    dbp->put(dbp, NULL, &key, &data, 0) == 0);
140		}
141	}
142
143	TIMER_STOP;
144
145	printf("# %d %s database in-order put of 10/20 byte key/data %sitems\n",
146	    count, ts, duplicate ? "duplicate " : "");
147	TIMER_DISPLAY(count);
148
149	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
150
151	return (0);
152}
153
154static int
155usage()
156{
157	(void)fprintf(stderr,
158	    "usage: b_load [-d] [-C cachesz] [-c count] [-t type]\n");
159	return (EXIT_FAILURE);
160}
161