📄 b_workload.c
字号:
/* * $Id: b_workload.c,v 1.13 2007/06/21 17:43:17 bostic Exp $ */#include "bench.h"#include "b_workload.h"/* * General TODO list: * * The workload type. Might work better as a bitmask than the current enum. * * Improve the verbose stats, so they can be easily parsed. * * Think about doing automatic btree/hash comparison in here. */intmain(argc, argv) int argc; char *argv[];{ CONFIG conf; DB *dbp; DB_ENV *dbenv; int ch, ffactor, ksz; dbenv = NULL; cleanup_test_dir(); memset(&conf, 0, sizeof(conf)); conf.seed = 124087; srand(conf.seed); conf.pcount = 100000; conf.ts = "Btree"; conf.type = DB_BTREE; conf.dsize = 20; conf.presize = 0; conf.workload = T_PUT_GET_DELETE; while ((ch = getopt(argc, argv, "b:c:d:e:g:ik:m:op:r:t:vw:")) != EOF) switch (ch) { case 'b': conf.cachesz = atoi(optarg); break; case 'c': conf.pcount = atoi(optarg); break; case 'd': conf.dsize = atoi(optarg); break; case 'e': conf.cursor_del = atoi(optarg); break; case 'g': conf.gcount = atoi(optarg); break; case 'i': conf.presize = 1; break; case 'k': conf.ksize = atoi(optarg); break; case 'm': conf.message = optarg; break; case 'o': conf.orderedkeys = 1; break; case 'p': conf.pagesz = atoi(optarg); break; case 'r': conf.num_dups = atoi(optarg); break; case 't': switch (optarg[0]) { case 'B': case 'b': conf.ts = "Btree"; conf.type = DB_BTREE; break; case 'H': case 'h': conf.ts = "Hash"; conf.type = DB_HASH; break; default: return (usage()); } break; case 'v': conf.verbose = 1; break; case 'w': switch (optarg[0]) { case 'A': conf.workload = T_PUT_GET_DELETE; break; case 'B': conf.workload = T_GET; break; case 'C': conf.workload = T_PUT; break; case 'D': conf.workload = T_DELETE; break; case 'E': conf.workload = T_PUT_GET; break; case 'F': conf.workload = T_PUT_DELETE; break; case 'G': conf.workload = T_GET_DELETE; break; case 'H': conf.workload = T_MIXED; break; default: return (usage()); } break; case '?': default: fprintf(stderr, "Invalid option: %c\n", ch); return (usage()); } argc -= optind; argv += optind; if (argc != 0) return (usage()); /* * Validate the input parameters if specified. */ if (conf.pagesz != 0) DB_BENCH_ASSERT(conf.pagesz >= 512 && conf.pagesz <= 65536 && ((conf.pagesz & (conf.pagesz - 1)) == 0)); if (conf.cachesz != 0) DB_BENCH_ASSERT(conf.cachesz > 20480); DB_BENCH_ASSERT(conf.ksize == 0 || conf.orderedkeys == 0); /* Create the environment. */ DB_BENCH_ASSERT(db_env_create(&dbenv, 0) == 0); dbenv->set_errfile(dbenv, stderr); if (conf.cachesz != 0) DB_BENCH_ASSERT( dbenv->set_cachesize(dbenv, 0, conf.cachesz, 0) == 0);#if DB_VERSION_MAJOR == 3 && DB_VERSION_MINOR < 1 DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", NULL, DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);#else DB_BENCH_ASSERT(dbenv->open(dbenv, "TESTDIR", DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0666) == 0);#endif /* * Create the database. */ DB_BENCH_ASSERT(db_create(&dbp, dbenv, 0) == 0); if (conf.pagesz != 0) DB_BENCH_ASSERT( dbp->set_pagesize(dbp, conf.pagesz) == 0); if (conf.presize != 0 && conf.type == DB_HASH) { ksz = (conf.orderedkeys != 0) ? sizeof(u_int32_t) : conf.ksize; if (ksz == 0) ksz = 10; ffactor = (conf.pagesz - 32)/(ksz + conf.dsize + 8); fprintf(stderr, "ffactor: %d\n", ffactor); DB_BENCH_ASSERT( dbp->set_h_ffactor(dbp, ffactor) == 0); DB_BENCH_ASSERT( dbp->set_h_nelem(dbp, conf.pcount*10) == 0); }#if DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 1 DB_BENCH_ASSERT( dbp->open(dbp, NULL, "a", NULL, conf.type, DB_CREATE | DB_TRUNCATE, 0666) == 0);#else DB_BENCH_ASSERT( dbp->open(dbp, "a", NULL, conf.type, DB_CREATE, 0666) == 0);#endif if (conf.workload == T_MIXED) run_mixed_workload(dbp, &conf); else run_std_workload(dbp, &conf); if (is_put_workload(conf.workload) == 0) timespecadd(&conf.tot_time, &conf.put_time); if (is_get_workload(conf.workload) == 0) timespecadd(&conf.tot_time, &conf.get_time); if (is_del_workload(conf.workload) == 0) timespecadd(&conf.tot_time, &conf.del_time); /* Ensure data is flushed for following measurements. */ DB_BENCH_ASSERT(dbp->sync(dbp, 0) == 0); if (conf.verbose != 0) dump_verbose_stats(dbp, &conf); DB_BENCH_ASSERT(dbp->close(dbp, 0) == 0); DB_BENCH_ASSERT(dbenv->close(dbenv, 0) == 0); /* * Construct a string for benchmark output. * * Insert HTML in-line to make the output prettier -- ugly, but easy. */ printf("# workload test: %s: %s<br>%lu ops", conf.ts, workload_str(conf.workload), (u_long)conf.pcount); if (conf.ksize != 0) printf(", key size: %lu", (u_long)conf.ksize); if (conf.dsize != 0) printf(", data size: %lu", (u_long)conf.dsize); if (conf.pagesz != 0) printf(", page size: %lu", (u_long)conf.pagesz); else printf(", page size: default"); if (conf.cachesz != 0) printf(", cache size: %lu", (u_long)conf.cachesz); else printf(", cache size: default"); printf(", %s keys", conf.orderedkeys == 1 ? "ordered" : "unordered"); printf(", num dups: %lu", (u_long)conf.num_dups); printf("\n"); if (conf.workload != T_MIXED) { if (conf.message != NULL) printf("%s %s ", conf.message, conf.ts); TIME_DISPLAY(conf.pcount, conf.tot_time); } else TIMER_DISPLAY(conf.pcount); return (0);}ints(dbp, pkey, pdata, skey) DB *dbp; const DBT *pkey, *pdata; DBT *skey;{ skey->data = pkey->data; skey->size = pkey->size; return (0);}/* * The mixed workload is designed to simulate a somewhat real * usage scenario. * NOTES: * rand is used to decide on the current operation. This will * be repeatable, since the same seed is always used. * * All added keys are stored in a FIFO queue, this is not very * space efficient, but is the best way I could come up with to * insert random key values, and be able to retrieve/delete them. * * TODO: the workload will currently only work with unordered * fixed length keys. */#define GET_PROPORTION 90#define PUT_PROPORTION 7#define DEL_PROPORTION 3intrun_mixed_workload(dbp, config) DB *dbp; CONFIG *config;{ DBT key, data; size_t next_op, i, ioff; char kbuf[10]; struct bench_q operation_queue; /* Having ordered insertion does not make sense here */ DB_BENCH_ASSERT(config->orderedkeys == 0); srand(config->seed); memset(&operation_queue, 0, sizeof(struct bench_q)); ioff = 0; INIT_KEY(key, config); memset(&data, 0, sizeof(data)); DB_BENCH_ASSERT( (data.data = malloc(data.size = config->dsize)) != NULL); /* * Add an initial sample set of data to the DB. * This should add some stability, and reduce the likelihood * of deleting all of the entries in the DB. */ for (i = 0; i < 100000; ++i) { GET_KEY_NEXT(key, config, kbuf, i); BENCH_Q_TAIL_INSERT(operation_queue, kbuf); DB_BENCH_ASSERT(dbp->put(dbp, NULL, &key, &data, 0) == 0); } TIMER_START; for (i = 0; i < config->pcount; ++i) { next_op = rand()%100; if (next_op < GET_PROPORTION ) { BENCH_Q_POP_PUSH(operation_queue, kbuf); key.data = kbuf; key.size = sizeof(kbuf); dbp->get(dbp, NULL, &key, &data, 0); } else if (next_op < GET_PROPORTION+PUT_PROPORTION) { GET_KEY_NEXT(key, config, kbuf, i); BENCH_Q_TAIL_INSERT(operation_queue, kbuf); dbp->put(dbp, NULL, &key, &data, 0); } else { BENCH_Q_POP(operation_queue, kbuf); key.data = kbuf; key.size = sizeof(kbuf); dbp->del(dbp, NULL, &key, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -