/* -*- mode: C; c-basic-offset: 4 -*- */ #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." /* Insert a bunch of stuff */ #include #include #include #include #include #include #include #include #include #if !defined(DB_YESOVERWRITE) #define DB_YESOVERWRITE 0 #endif #if !defined(DB_PRELOCKED_WRITE) #define NO_DB_PRELOCKED #define DB_PRELOCKED_WRITE 0 #endif int verbose=1; enum { SERIAL_SPACING = 1<<6 }; enum { DEFAULT_ITEMS_TO_INSERT_PER_ITERATION = 1<<20 }; enum { DEFAULT_ITEMS_PER_TRANSACTION = 1<<14 }; #define CKERR(r) if (r!=0) fprintf(stderr, "%s:%d error %d %s\n", __FILE__, __LINE__, r, db_strerror(r)); assert(r==0); /* default test parameters */ int keysize = sizeof (long long); int valsize = sizeof (long long); int pagesize = 0; long long cachesize = 128*1024*1024; int dupflags = 0; int noserial = 0; // Don't do the serial stuff int norandom = 0; // Don't do the random stuff int prelock = 0; int prelockflag = 0; int items_per_transaction = DEFAULT_ITEMS_PER_TRANSACTION; int items_per_iteration = DEFAULT_ITEMS_TO_INSERT_PER_ITERATION; int singlex = 0; // Do a single transaction int do_transactions = 0; int do_abort = 0; int n_insertions_since_txn_began=0; int env_open_flags = DB_CREATE|DB_PRIVATE|DB_INIT_MPOOL; u_int32_t put_flags = DB_YESOVERWRITE; double compressibility = -1; // -1 means make it very compressible. 1 means use random bits everywhere. 2 means half the bits are random. static void do_prelock(DB* db, DB_TXN* txn) { if (prelock) { #if !defined(NO_DB_PRELOCKED) int r = db->pre_acquire_table_lock(db, txn); assert(r==0); #else db = db; txn = txn; #endif } } #define STRINGIFY2(s) #s #define STRINGIFY(s) STRINGIFY2(s) const char *dbdir = "./bench." STRINGIFY(DIRSUF); /* DIRSUF is passed in as a -D argument to the compiler. */ char *dbfilename = "bench.db"; char *dbname; DB_ENV *dbenv; DB *db; DB_TXN *tid=0; static void benchmark_setup (void) { int r; { char unlink_cmd[strlen(dbdir) + strlen("rf -rf ") + 1]; snprintf(unlink_cmd, sizeof(unlink_cmd), "rm -rf %s", dbdir); //printf("unlink_cmd=%s\n", unlink_cmd); system(unlink_cmd); } if (strcmp(dbdir, ".") != 0) { r = toku_os_mkdir(dbdir,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); assert(r == 0); } r = db_env_create(&dbenv, 0); assert(r == 0); #if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR <= 4 if (dbenv->set_lk_max) { r = dbenv->set_lk_max(dbenv, items_per_transaction*2); assert(r==0); } #endif if (dbenv->set_lk_max_locks) { r = dbenv->set_lk_max_locks(dbenv, items_per_transaction*2); assert(r == 0); } if (dbenv->set_cachesize) { r = dbenv->set_cachesize(dbenv, cachesize / (1024*1024*1024), cachesize % (1024*1024*1024), 1); if (r != 0) printf("WARNING: set_cachesize %d\n", r); } { r = dbenv->open(dbenv, dbdir, env_open_flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); assert(r == 0); } r = db_create(&db, dbenv, 0); assert(r == 0); if (do_transactions) { r=dbenv->txn_begin(dbenv, 0, &tid, 0); CKERR(r); if (singlex) do_prelock(db, tid); } if (pagesize && db->set_pagesize) { r = db->set_pagesize(db, pagesize); assert(r == 0); } if (dupflags) { r = db->set_flags(db, dupflags); assert(r == 0); } r = db->open(db, tid, dbfilename, NULL, DB_BTREE, DB_CREATE, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (r!=0) fprintf(stderr, "errno=%d, %s\n", errno, strerror(errno)); assert(r == 0); if (do_transactions) { if (singlex) do_prelock(db, tid); else { r=tid->commit(tid, 0); assert(r==0); } } } static void benchmark_shutdown (void) { int r; if (do_transactions && singlex) { r = (do_abort ? tid->abort(tid) : tid->commit(tid, 0)); assert(r==0); } r = db->close(db, 0); assert(r == 0); r = dbenv->close(dbenv, 0); assert(r == 0); } static void long_long_to_array (unsigned char *a, int array_size, unsigned long long l) { int i; for (i=0; i<8 && i>(56-8*i))&0xff; } static DBT *fill_dbt(DBT *dbt, const void *data, int size) { memset(dbt, 0, sizeof *dbt); dbt->size = size; dbt->data = (void *) data; return dbt; } // Fill array with 0's if compressibilty==-1, otherwise fill array with data that is likely to compress by a factor of compressibility. static void fill_array (unsigned char *data, int size) { memset(data, 0, size); if (compressibility>0) { int i; for (i=0; iput(db, tid, fill_dbt(&kt, kc, keysize), fill_dbt(&vt, vc, valsize), put_flags); CKERR(r); if (do_transactions) { if (n_insertions_since_txn_began>=items_per_transaction && !singlex) { n_insertions_since_txn_began=0; r = tid->commit(tid, 0); assert(r==0); r=dbenv->txn_begin(dbenv, 0, &tid, 0); assert(r==0); do_prelock(db, tid); n_insertions_since_txn_began=0; } n_insertions_since_txn_began++; } } static void serial_insert_from (long long from) { long long i; if (do_transactions && !singlex) { int r = dbenv->txn_begin(dbenv, 0, &tid, 0); assert(r==0); do_prelock(db, tid); { DBT k,v; r=db->put(db, tid, fill_dbt(&k, "a", 1), fill_dbt(&v, "b", 1), put_flags); CKERR(r); } } for (i=0; icommit(tid, 0); assert(r==0); tid=0; } } static long long llrandom (void) { return (((long long)(random()))<<32) + random(); } static void random_insert_below (long long below) { long long i; if (do_transactions && !singlex) { int r = dbenv->txn_begin(dbenv, 0, &tid, 0); assert(r==0); do_prelock(db, tid); } for (i=0; icommit(tid, 0); assert(r==0); tid=0; } } static double tdiff (struct timeval *a, struct timeval *b) { return (a->tv_sec-b->tv_sec)+1e-6*(a->tv_usec-b->tv_usec); } static void biginsert (long long n_elements, struct timeval *starttime) { long long i; struct timeval t1,t2; int iteration; for (i=0, iteration=0; i= argc) return print_usage(argv[0]); if (atoi(argv[++i])) env_open_flags |= DB_INIT_TXN; else env_open_flags &= ~DB_INIT_TXN; } else if (strcmp(arg, "--DB_INIT_LOG") == 0) { if (atoi(argv[++i])) env_open_flags |= DB_INIT_LOG; else env_open_flags &= ~DB_INIT_LOG; } else if (strcmp(arg, "--DB_INIT_LOCK") == 0) { if (atoi(argv[++i])) env_open_flags |= DB_INIT_LOCK; else env_open_flags &= ~DB_INIT_LOCK; } else if (strcmp(arg, "--noserial") == 0) { noserial=1; } else if (strcmp(arg, "--norandom") == 0) { norandom=1; } else if (strcmp(arg, "--compressibility") == 0) { compressibility = atof(argv[++i]); } else if (strcmp(arg, "--singlex") == 0) { do_transactions = 1; singlex = 1; } else if (strcmp(arg, "--xcount") == 0) { if (i+1 >= argc) return print_usage(argv[0]); items_per_transaction = strtoll(argv[++i], 0, 10); } else if (strcmp(arg, "--abort") == 0) { do_abort = 1; } else if (strcmp(arg, "--periter") == 0) { if (i+1 >= argc) return print_usage(argv[0]); items_per_iteration = strtoll(argv[++i], 0, 10); } else if (strcmp(arg, "--cachesize") == 0) { if (i+1 >= argc) return print_usage(argv[0]); cachesize = strtoll(argv[++i], 0, 10); } else if (strcmp(arg, "--keysize") == 0) { if (i+1 >= argc) return print_usage(argv[0]); keysize = atoi(argv[++i]); } else if (strcmp(arg, "--valsize") == 0) { if (i+1 >= argc) return print_usage(argv[0]); valsize = atoi(argv[++i]); } else if (strcmp(arg, "--pagesize") == 0) { if (i+1 >= argc) return print_usage(argv[0]); pagesize = atoi(argv[++i]); } else if (strcmp(arg, "--dupsort") == 0) { dupflags = DB_DUP + DB_DUPSORT; continue; } else if (strcmp(arg, "--env") == 0) { if (i+1 >= argc) return print_usage(argv[0]); dbdir = argv[++i]; } else if (strcmp(arg, "--prelock") == 0) { prelock=1; } else if (strcmp(arg, "--prelockflag") == 0) { prelock=1; prelockflag=1; } else { return print_usage(argv[0]); } } if (do_transactions) { env_open_flags |= DB_INIT_TXN | DB_INIT_LOG | DB_INIT_LOCK; } if (do_transactions && prelockflag) { put_flags |= DB_PRELOCKED_WRITE; } if (i