/*- * Public Domain 2014-2016 MongoDB, Inc. * Public Domain 2008-2014 WiredTiger, Inc. * * This is free and unencumbered software released into the public domain. * * Anyone is free to copy, modify, publish, use, compile, sell, or * distribute this software, either in source code form or as a compiled * binary, for any purpose, commercial or non-commercial, and by any * means. * * In jurisdictions that recognize copyright laws, the author or authors * of this software dedicate any and all copyright interest in the * software to the public domain. We make this dedication for the benefit * of the public at large and to the detriment of our heirs and * successors. We intend this dedication to be an overt act of * relinquishment in perpetuity of all present and future rights to this * software under copyright law. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include "cursor_order.h" static char home[512]; /* Program working dir */ static char *progname; /* Program name */ static FILE *logfp; /* Log file */ static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); static void onint(int); static void shutdown(void); static int usage(void); static void wt_connect(SHARED_CONFIG *, char *); static void wt_shutdown(SHARED_CONFIG *); extern int __wt_optind; extern char *__wt_optarg; void (*custom_die)(void) = NULL; int main(int argc, char *argv[]) { SHARED_CONFIG _cfg, *cfg; int ch, cnt, runs; char *config_open, *working_dir; if ((progname = strrchr(argv[0], DIR_DELIM)) == NULL) progname = argv[0]; else ++progname; cfg = &_cfg; config_open = NULL; working_dir = NULL; runs = 1; /* * Explicitly initialize the shared configuration object before * parsing command line options. */ cfg->append_inserters = 1; cfg->conn = NULL; cfg->ftype = ROW; cfg->max_nops = 1000000; cfg->multiple_files = false; cfg->nkeys = 1000; cfg->reverse_scanners = 5; cfg->reverse_scan_ops = 10; cfg->thread_finish = false; cfg->vary_nops = false; while ((ch = __wt_getopt( progname, argc, argv, "C:Fk:h:l:n:R:r:t:vw:W:")) != EOF) switch (ch) { case 'C': /* wiredtiger_open config */ config_open = __wt_optarg; break; case 'F': /* multiple files */ cfg->multiple_files = true; break; case 'h': working_dir = __wt_optarg; break; case 'k': /* rows */ cfg->nkeys = (uint64_t)atol(__wt_optarg); break; case 'l': /* log */ if ((logfp = fopen(__wt_optarg, "w")) == NULL) { fprintf(stderr, "%s: %s\n", __wt_optarg, strerror(errno)); return (EXIT_FAILURE); } break; case 'n': /* operations */ cfg->max_nops = (uint64_t)atol(__wt_optarg); break; case 'R': cfg->reverse_scanners = (uint64_t)atol(__wt_optarg); break; case 'r': /* runs */ runs = atoi(__wt_optarg); break; case 't': switch (__wt_optarg[0]) { case 'f': cfg->ftype = FIX; break; case 'r': cfg->ftype = ROW; break; case 'v': cfg->ftype = VAR; break; default: return (usage()); } break; case 'v': /* vary operation count */ cfg->vary_nops = true; break; case 'w': cfg->reverse_scan_ops = (uint64_t)atol(__wt_optarg); break; case 'W': cfg->append_inserters = (uint64_t)atol(__wt_optarg); break; default: return (usage()); } argc -= __wt_optind; argv += __wt_optind; if (argc != 0) return (usage()); testutil_work_dir_from_path(home, 512, working_dir); if (cfg->vary_nops && !cfg->multiple_files) { fprintf(stderr, "Variable op counts only supported with multiple tables\n"); return (usage()); } /* Clean up on signal. */ (void)signal(SIGINT, onint); printf("%s: process %" PRIu64 "\n", progname, (uint64_t)getpid()); for (cnt = 1; runs == 0 || cnt <= runs; ++cnt) { printf( " %d: %" PRIu64 " reverse scanners, %" PRIu64 " writers\n", cnt, cfg->reverse_scanners, cfg->append_inserters); shutdown(); /* Clean up previous runs */ wt_connect(cfg, config_open); /* WiredTiger connection */ if (ops_start(cfg)) return (EXIT_FAILURE); wt_shutdown(cfg); /* WiredTiger shut down */ } return (0); } /* * wt_connect -- * Configure the WiredTiger connection. */ static void wt_connect(SHARED_CONFIG *cfg, char *config_open) { static WT_EVENT_HANDLER event_handler = { handle_error, handle_message, NULL, NULL /* Close handler. */ }; int ret; char config[512]; size_t print_count; testutil_clean_work_dir(home); testutil_make_work_dir(home); print_count = (size_t)snprintf(config, sizeof(config), "create,statistics=(all),error_prefix=\"%s\",%s%s", progname, config_open == NULL ? "" : ",", config_open == NULL ? "" : config_open); if (print_count >= sizeof(config)) testutil_die(EINVAL, "Config string too long"); if ((ret = wiredtiger_open( home, &event_handler, config, &cfg->conn)) != 0) testutil_die(ret, "wiredtiger_open"); } /* * wt_shutdown -- * Flush the file to disk and shut down the WiredTiger connection. */ static void wt_shutdown(SHARED_CONFIG *cfg) { WT_CONNECTION *conn; WT_SESSION *session; int ret; conn = cfg->conn; if ((ret = conn->open_session(conn, NULL, NULL, &session)) != 0) testutil_die(ret, "conn.session"); if ((ret = session->checkpoint(session, NULL)) != 0) testutil_die(ret, "session.checkpoint"); if ((ret = conn->close(conn, NULL)) != 0) testutil_die(ret, "conn.close"); } /* * shutdown -- * Clean up from previous runs. */ static void shutdown(void) { testutil_clean_work_dir(home); } static int handle_error(WT_EVENT_HANDLER *handler, WT_SESSION *session, int error, const char *errmsg) { (void)(handler); (void)(session); (void)(error); return (fprintf(stderr, "%s\n", errmsg) < 0 ? -1 : 0); } static int handle_message(WT_EVENT_HANDLER *handler, WT_SESSION *session, const char *message) { (void)(handler); (void)(session); if (logfp != NULL) return (fprintf(logfp, "%s\n", message) < 0 ? -1 : 0); return (printf("%s\n", message) < 0 ? -1 : 0); } /* * onint -- * Interrupt signal handler. */ static void onint(int signo) { (void)(signo); shutdown(); fprintf(stderr, "\n"); exit(EXIT_FAILURE); } /* * usage -- * Display usage statement and exit failure. */ static int usage(void) { fprintf(stderr, "usage: %s " "[-FLv] [-C wiredtiger-config] [-k keys] [-l log]\n\t" "[-n ops] [-R reverse_scanners] [-r runs] [-t f|r|v] " "[-W append_inserters]\n", progname); fprintf(stderr, "%s", "\t-C specify wiredtiger_open configuration arguments\n" "\t-F create a file per thread\n" "\t-k set number of keys to load\n" "\t-L log print per operation\n" "\t-l specify a log file\n" "\t-n set number of operations each thread does\n" "\t-R set number of reverse scanner threads\n" "\t-r set number of runs (0 for continuous)\n" "\t-t set a file type (fix | row | var)\n" "\t-v do a different number of operations on different tables\n" "\t-w set number of items to walk in a reverse scan\n" "\t-W set number of threads doing append inserts\n"); return (EXIT_FAILURE); }