• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src/router/db-4.8.30/build_vxworks/test_micro/
1/*
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2005-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9#include "bench.h"
10
11#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0
12/*
13 * The in-memory tests don't run on early releases of Berkeley DB.
14 */
15#undef	MEGABYTE
16#define	MEGABYTE	(1024 * 1024)
17
18u_int32_t bulkbufsize = 4 * MEGABYTE;
19u_int32_t cachesize = 32 * MEGABYTE;
20u_int32_t datasize = 32;
21u_int32_t keysize = 8;
22u_int32_t logbufsize = 8 * MEGABYTE;
23u_int32_t numitems;
24u_int32_t pagesize = 32 * 1024;
25
26FILE *fp;
27
28static void b_inmem_op_ds __P((u_int, int));
29static void b_inmem_op_ds_bulk __P((u_int, u_int *));
30static void b_inmem_op_tds __P((u_int, int, u_int32_t, u_int32_t));
31static int  b_inmem_usage __P((void));
32
33static void
34b_inmem_op_ds(u_int ops, int update)
35{
36	DB_ENV *dbenv;
37	char *letters = "abcdefghijklmnopqrstuvwxuz";
38	DB *dbp;
39	DBT key, data;
40	char *keybuf, *databuf;
41	DB_MPOOL_STAT  *gsp;
42
43	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
44	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL);
45
46	memset(&key, 0, sizeof(key));
47	memset(&data, 0, sizeof(data));
48	key.data = keybuf;
49	key.size = keysize;
50	memset(keybuf, 'a', keysize);
51
52	data.data = databuf;
53	data.size = datasize;
54	memset(databuf, 'b', datasize);
55
56	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
57	dbenv = dbp->dbenv;
58	dbp->set_errfile(dbp, stderr);
59
60	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
61	DB_BENCH_ASSERT(dbp->open(
62	    dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
63
64	(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);
65
66	if (update) {
67		TIMER_START;
68		for (; ops > 0; --ops) {
69			keybuf[(ops % keysize)] = letters[(ops % 26)];
70			DB_BENCH_ASSERT(
71			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
72		}
73		TIMER_STOP;
74	} else {
75		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
76		TIMER_START;
77		for (; ops > 0; --ops)
78			DB_BENCH_ASSERT(
79			    dbp->get(dbp, NULL, &key, &data, 0) == 0);
80		TIMER_STOP;
81	}
82
83	if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
84		DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
85
86	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
87}
88
89static void
90b_inmem_op_ds_bulk(u_int ops, u_int *totalp)
91{
92	DB_ENV *dbenv;
93	DB *dbp;
94	DBC *dbc;
95	DBT key, data;
96	u_int32_t len, klen;
97	u_int i, total;
98	char *keybuf, *databuf;
99	void *pointer, *dp, *kp;
100	DB_MPOOL_STAT  *gsp;
101
102	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
103	DB_BENCH_ASSERT((databuf = malloc(bulkbufsize)) != NULL);
104
105	memset(&key, 0, sizeof(key));
106	memset(&data, 0, sizeof(data));
107	key.data = keybuf;
108	key.size = keysize;
109
110	data.data = databuf;
111	data.size = datasize;
112	memset(databuf, 'b', datasize);
113
114	DB_BENCH_ASSERT(db_create(&dbp, NULL, 0) == 0);
115	dbenv = dbp->dbenv;
116	dbp->set_errfile(dbp, stderr);
117
118	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
119	DB_BENCH_ASSERT(dbp->set_cachesize(dbp, 0, cachesize, 1) == 0);
120	DB_BENCH_ASSERT(
121	    dbp->open(dbp, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
122
123	for (i = 1; i <= numitems; ++i) {
124		(void)snprintf(keybuf, keysize, "%7d", i);
125		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
126	}
127
128#if 0
129	fp = fopen("before", "w");
130	dbp->set_msgfile(dbp, fp);
131	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0);
132#endif
133
134	DB_BENCH_ASSERT(dbp->cursor(dbp, NULL, &dbc, 0) == 0);
135
136	data.ulen = bulkbufsize;
137	data.flags = DB_DBT_USERMEM;
138
139	(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);
140
141	TIMER_START;
142	for (total = 0; ops > 0; --ops) {
143		DB_BENCH_ASSERT(dbc->c_get(
144		    dbc, &key, &data, DB_FIRST | DB_MULTIPLE_KEY) == 0);
145		DB_MULTIPLE_INIT(pointer, &data);
146		while (pointer != NULL) {
147			DB_MULTIPLE_KEY_NEXT(pointer, &data, kp, klen, dp, len);
148			if (kp != NULL)
149				++total;
150		}
151	}
152	TIMER_STOP;
153	*totalp = total;
154
155	if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
156	    DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
157
158#if 0
159	fp = fopen("before", "w");
160	dbp->set_msgfile(dbp, fp);
161	DB_BENCH_ASSERT (dbp->stat_print(dbp, DB_STAT_ALL) == 0);
162#endif
163
164	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
165
166	COMPQUIET(dp, NULL);
167	COMPQUIET(klen, 0);
168	COMPQUIET(len, 0);
169}
170
171static void
172b_inmem_op_tds(u_int ops, int update, u_int32_t env_flags, u_int32_t log_flags)
173{
174	DB *dbp;
175	DBT key, data;
176	DB_ENV *dbenv;
177	DB_MPOOL_STAT  *gsp;
178	DB_TXN *txn;
179	char *keybuf, *databuf;
180
181	DB_BENCH_ASSERT((keybuf = malloc(keysize)) != NULL);
182	DB_BENCH_ASSERT((databuf = malloc(datasize)) != NULL);
183
184	memset(&key, 0, sizeof(key));
185	memset(&data, 0, sizeof(data));
186	key.data = keybuf;
187	key.size = keysize;
188	memset(keybuf, 'a', keysize);
189
190	data.data = databuf;
191	data.size = datasize;
192	memset(databuf, 'b', datasize);
193
194	DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0);
195
196	dbenv->set_errfile(dbenv, stderr);
197
198	/* General environment configuration. */
199#ifdef DB_AUTO_COMMIT
200	DB_BENCH_ASSERT(dbenv->set_flags(dbenv, DB_AUTO_COMMIT, 1) == 0);
201#endif
202	if (env_flags != 0)
203		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, env_flags, 1) == 0);
204
205	/* Logging configuration. */
206	if (log_flags != 0)
207#if DB_VERSION_MINOR >= 7
208		DB_BENCH_ASSERT(
209		    dbenv->log_set_config(dbenv, log_flags, 1) == 0);
210#else
211		DB_BENCH_ASSERT(dbenv->set_flags(dbenv, log_flags, 1) == 0);
212#endif
213#ifdef DB_LOG_INMEMORY
214	if (!(log_flags & DB_LOG_INMEMORY))
215#endif
216#ifdef DB_LOG_IN_MEMORY
217	if (!(log_flags & DB_LOG_IN_MEMORY))
218#endif
219		DB_BENCH_ASSERT(dbenv->set_lg_max(dbenv, logbufsize * 10) == 0);
220	DB_BENCH_ASSERT(dbenv->set_lg_bsize(dbenv, logbufsize) == 0);
221
222	DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR",
223	    DB_CREATE | DB_PRIVATE | DB_INIT_LOCK |
224	    DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0666) == 0);
225
226	DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0);
227	DB_BENCH_ASSERT(dbp->set_pagesize(dbp, pagesize) == 0);
228	DB_BENCH_ASSERT(dbp->open(
229	    dbp, NULL, TESTFILE, NULL, DB_BTREE, DB_CREATE, 0666) == 0);
230
231	if (update) {
232		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);
233
234		TIMER_START;
235		for (; ops > 0; --ops)
236			DB_BENCH_ASSERT(
237			    dbp->put(dbp, NULL, &key, &data, 0) == 0);
238		TIMER_STOP;
239
240		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
241			DB_BENCH_ASSERT(gsp->st_page_out == 0);
242	} else {
243		DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0);
244		(void)dbenv->memp_stat(dbenv, &gsp, NULL, DB_STAT_CLEAR);
245
246		TIMER_START;
247		for (; ops > 0; --ops) {
248			DB_BENCH_ASSERT(
249			    dbenv->txn_begin(dbenv, NULL, &txn, 0) == 0);
250			DB_BENCH_ASSERT(
251			    dbp->get(dbp, NULL, &key, &data, 0) == 0);
252			DB_BENCH_ASSERT(txn->commit(txn, 0) == 0);
253		}
254		TIMER_STOP;
255
256		if (dbenv->memp_stat(dbenv, &gsp, NULL, 0) == 0)
257			DB_BENCH_ASSERT(gsp->st_cache_miss == 0);
258	}
259
260	DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0);
261	DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0);
262}
263
264#define	DEFAULT_OPS	1000000
265
266int
267b_inmem(int argc, char *argv[])
268{
269	extern char *optarg;
270	extern int optind, __db_getopt_reset;
271	u_int ops, total;
272	int ch;
273
274	if ((progname = strrchr(argv[0], '/')) == NULL)
275		progname = argv[0];
276	else
277		++progname;
278
279	ops = 0;
280	__db_getopt_reset = 1;
281	while ((ch = getopt(argc, argv, "b:C:d:k:l:o:P:")) != EOF)
282		switch (ch) {
283		case 'b':
284			bulkbufsize = (u_int32_t)atoi(optarg);
285			break;
286		case 'C':
287			cachesize = (u_int32_t)atoi(optarg);
288			break;
289		case 'd':
290			datasize = (u_int)atoi(optarg);
291			break;
292		case 'k':
293			keysize = (u_int)atoi(optarg);
294			break;
295		case 'l':
296			logbufsize = (u_int32_t)atoi(optarg);
297			break;
298		case 'o':
299			ops = (u_int)atoi(optarg);
300			break;
301		case 'P':
302			pagesize = (u_int32_t)atoi(optarg);
303			break;
304		case '?':
305		default:
306			return (b_inmem_usage());
307		}
308	argc -= optind;
309	argv += optind;
310
311	if (argc != 1)
312		return (b_inmem_usage());
313
314	numitems = (cachesize / (keysize + datasize - 1)) / 2;
315
316	if (strcasecmp(argv[0], "read") == 0) {
317		if (ops == 0)
318			ops = DEFAULT_OPS;
319		b_inmem_op_ds(ops, 0);
320		printf(
321	"# %u in-memory Btree database reads of %u/%u byte key/data pairs\n",
322		    ops, keysize, datasize);
323	} else if (strcasecmp(argv[0], "bulk") == 0) {
324		if (keysize < 8) {
325			fprintf(stderr,
326		    "%s: bulk read requires a key size >= 10\n", progname);
327			return (EXIT_FAILURE);
328		}
329		/*
330		 * The ops value is the number of bulk operations, not key get
331		 * operations.  Reduce the value so the test doesn't take so
332		 * long, and use the returned number of retrievals as the ops
333		 * value for timing purposes.
334		 */
335		if (ops == 0)
336			ops = 100000;
337		b_inmem_op_ds_bulk(ops, &total);
338		ops = total;
339		printf(
340    "# %u bulk in-memory Btree database reads of %u/%u byte key/data pairs\n",
341		    ops, keysize, datasize);
342	} else if (strcasecmp(argv[0], "write") == 0) {
343		if (ops == 0)
344			ops = DEFAULT_OPS;
345		b_inmem_op_ds(ops, 1);
346		printf(
347	"# %u in-memory Btree database writes of %u/%u byte key/data pairs\n",
348		    ops, keysize, datasize);
349	} else if (strcasecmp(argv[0], "txn-read") == 0) {
350		if (ops == 0)
351			ops = DEFAULT_OPS;
352		b_inmem_op_tds(ops, 0, 0, 0);
353		printf(
354		"# %u transactional in-memory Btree database reads of %u/%u %s",
355		    ops, keysize, datasize, "byte key/data pairs\n");
356	} else if (strcasecmp(argv[0], "txn-write") == 0) {
357		if (ops == 0)
358			ops = DEFAULT_OPS;
359#if defined(DB_LOG_INMEMORY) || defined(DB_LOG_IN_MEMORY)
360#if defined(DB_LOG_INMEMORY)
361		b_inmem_op_tds(ops, 1, 0, DB_LOG_INMEMORY);
362#else
363		b_inmem_op_tds(ops, 1, 0, DB_LOG_IN_MEMORY);
364#endif
365		printf(
366	"# %u transactional in-memory logging Btree database writes of %u/%u%s",
367		    ops, keysize, datasize, " byte key/data pairs\n");
368#else
369		return (EXIT_SUCCESS);
370#endif
371	} else if (strcasecmp(argv[0], "txn-nosync") == 0) {
372		if (ops == 0)
373			ops = DEFAULT_OPS;
374		b_inmem_op_tds(ops, 1, DB_TXN_NOSYNC, 0);
375		printf(
376	"# %u transactional nosync logging Btree database writes of %u/%u %s",
377		    ops, keysize, datasize, "byte key/data pairs\n");
378	} else if (strcasecmp(argv[0], "txn-write-nosync") == 0) {
379		if (ops == 0)
380			ops = DEFAULT_OPS;
381#ifdef DB_TXN_WRITE_NOSYNC
382		b_inmem_op_tds(ops, 1, DB_TXN_WRITE_NOSYNC, 0);
383		printf(
384  "# %u transactional OS-write/nosync logging Btree database writes of %u/%u%s",
385		    ops, keysize, datasize, " byte key/data pairs\n");
386#else
387		return (EXIT_SUCCESS);
388#endif
389	} else if (strcasecmp(argv[0], "txn-sync") == 0) {
390		/*
391		 * Flushing to disk takes a long time, reduce the number of
392		 * default ops.
393		 */
394		if (ops == 0)
395			ops = 100000;
396		b_inmem_op_tds(ops, 1, 0, 0);
397		printf(
398	"# %u transactional logging Btree database writes of %u/%u %s",
399		    ops, keysize, datasize, "byte key/data pairs\n");
400	} else {
401		fprintf(stderr, "%s: unknown keyword %s\n", progname, argv[0]);
402		return (EXIT_FAILURE);
403	}
404
405	TIMER_DISPLAY(ops);
406	return (EXIT_SUCCESS);
407}
408
409static int
410b_inmem_usage()
411{
412	fprintf(stderr, "usage: %s %s%s%s%s",
413	    progname, "[-b bulkbufsz] [-C cachesz]\n\t",
414	    "[-d datasize] [-k keysize] [-l logbufsz] [-o ops] [-P pagesz]\n\t",
415	    "[read | bulk | write | txn-read |\n\t",
416	    "txn-write | txn-nosync | txn-write-nosync | txn-sync]\n");
417	return (EXIT_FAILURE);
418}
419#else
420int
421b_inmem(int argc, char *argv[])
422{
423	COMPQUIET(argc, 0);
424	COMPQUIET(argv, NULL);
425	return (0);
426}
427#endif
428