Пример #1
0
/*
 * b_util_dir_setup --
 *	Create the test directory.
 */
int
b_util_dir_setup()
{
	int ret;

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 3
	if ((ret = __os_mkdir(NULL, TESTDIR, 0755)) != 0) {
#else
	if ((ret = mkdir(TESTDIR, 0755)) != 0) {
#endif
		fprintf(stderr,
		    "%s: %s: %s\n", progname, TESTDIR, db_strerror(ret));
		return (1);
	}
	return (0);
}

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 4
#define	OS_EXISTS(a, b, c)	__os_exists(a, b, c)
#else
#define	OS_EXISTS(a, b, c)	__os_exists(b, c)
#endif

/*
 * b_util_dir_teardown
 *	Clean up the test directory.
 */
int
b_util_dir_teardown()
{
	int ret;

	if (OS_EXISTS(NULL, TESTFILE, NULL) == 0 &&
	    (ret = b_util_unlink(TESTFILE)) != 0) {
		fprintf(stderr,
		    "%s: %s: %s\n", progname, TESTFILE, db_strerror(ret));
		return (1);
	}
	return (testdir_remove(TESTDIR) ? 1 : 0);
}
Пример #2
0
// Create test directory.
inline int dir_setup(const char *testdir)
{
	int ret;

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 3
	if ((ret = __os_mkdir(NULL, testdir, 0755)) != 0) {
#else
	if ((ret = mkdir(testdir, 0755)) != 0) {
#endif
		fprintf(stderr,
		    "dir_setup: Creating directory %s: %s\n", 
		    testdir, db_strerror(ret));
		return (1);
	}
	return (0);
}

inline int os_unlink(const char *path)
{
#if DB_VERSION_MAJOR < 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR < 7
	return (__os_unlink(NULL, path));
#else
	return (__os_unlink(NULL, path, 0));
#endif
}

#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 4
#define	OS_EXISTS(a, b, c)	__os_exists(a, b, c)
#else
#define	OS_EXISTS(a, b, c)	__os_exists(b, c)
#endif

// Remove contents in specified directory recursively(in DB versions earlier 
// than 4.6, don't recursively), and optionally remove the directory itself.
int rmdir_rcsv(const char *dir, bool keep_this_dir)
{
	int cnt, i, isdir, ret;
	char buf[1024], **names;

	ret = 0;

	/* If the directory doesn't exist, we're done. */
	if (OS_EXISTS(NULL, dir, &isdir) != 0)
		return (0);

	/* Get a list of the directory contents. */
#if DB_VERSION_MAJOR > 4 || DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 6
	if ((ret = __os_dirlist(NULL, dir, 1, &names, &cnt)) != 0)
		return (ret);
#else
	if ((ret = __os_dirlist(NULL, dir, &names, &cnt)) != 0)
		return (ret);
#endif
	/* Go through the file name list, remove each file in the list */
	for (i = 0; i < cnt; ++i) {
		(void)snprintf(buf, sizeof(buf),
		    "%s%c%s", dir, PATH_SEPARATOR[0], names[i]);
		if ((ret = OS_EXISTS(NULL, buf, &isdir)) != 0)
			goto file_err;
		if (!isdir && (ret = os_unlink(buf)) != 0) {
file_err:		fprintf(stderr, 
			    "os_unlink: Error unlinking file: %s: %s\n",
			    buf, db_strerror(ret));
			break;
		}
		if (isdir && rmdir_rcsv(buf, false) != 0)
			goto file_err;
	}

	__os_dirfree(NULL, names, cnt);

	/*
	 * If we removed the contents of the directory and we don't want to
	 * keep this directory, remove the directory itself.
	 */
	if (i == cnt && !keep_this_dir && (ret = rmdir(dir)) != 0)
		fprintf(stderr,
		    "rmdir_rcsv(%s): %s\n", dir, db_strerror(errno));
	return (ret);
} // rmdir_rcsv
Пример #3
0
int main(int argc, char *argv[])
{
	int c, i, j, ret;
	int nreader = 5, nwriter = 3;
	char *mode = NULL;
	int flags = DB_THREAD, setflags = 0, EXPLICIT_TXN = 0;
	int TEST_AUTOCOMMIT = 1, totalinsert = 100, verbose = 0;
	DBTYPE dbtype = DB_BTREE;
	int gi, shortest = 50, longest = 200, loop_count = 1;
	bool multionly = false;
	u_int32_t sflags = 0, oflags = 0;
	u_int32_t cachesize = 8 * 1024 * 1024;
	db_threadid_t tid;
	string contname;
	DbEnv *penv = NULL;
	Db *dbstrv = NULL;
	__os_id(0, 0, &tid);

	TestParam *ptp = new TestParam;
	ContainerType contypes[] = {
		ct_vector, 
		ct_map, 
		ct_multimap, 
		ct_set, 
		ct_multiset, 
		ct_none
	};

	while ((c = getopt(argc, argv, "MT:c:hk:l:m:n:r:s:t:vw:")) != EOF) {
		switch (c) {
			case 'M':
				multionly = true;
				break;
			case 'T':
				totalinsert = atoi(optarg);
				break;
			case 'c':
				cachesize = atoi(optarg);
				break;
			case 'h':
				usage();
				return 0;
				break;
			case 'k':
				shortest = atoi(optarg);
				break;
			case 'l':
				longest = atoi(optarg);
				break;
			case 'm':
				mode = optarg;
				break;
			case 'n':
				loop_count = atoi(optarg);
				break;
			case 'r':
				nreader = atoi(optarg);
				break;
			case 's': // db type for associative containers
				if (*optarg == 'h') // hash db type
					dbtype = DB_HASH;
				else if (*optarg == 'b')
					dbtype = DB_BTREE;
				else
					usage();
				break;
			case 't':
				EXPLICIT_TXN = 1;
				if (*optarg == 'a') 
					setflags = DB_AUTO_COMMIT;
				else if (*optarg == 'e') // explicit txn
					TEST_AUTOCOMMIT = 0;
				else 
					usage();
				break;
			case 'v':
				verbose = 1;
				break;
			case 'w':
				nwriter = atoi(optarg);
				break;
			default:
				usage();
				break;
		}
	}

	if (nwriter < 3)
		nwriter = 3;

	if (mode == NULL) 
		flags |= 0;
	else if (*mode == 'c') //cds
		flags |= DB_INIT_CDB;
	else if (*mode == 't')
		flags |= DB_INIT_TXN | DB_RECOVER 
		    | DB_INIT_LOG | DB_INIT_LOCK;
	else
		flags |= 0;
	g_test_start_txn = TEST_AUTOCOMMIT * EXPLICIT_TXN;
	ptp->EXPLICIT_TXN = EXPLICIT_TXN;
	ptp->flags = flags;
	ptp->dbtype = dbtype;
	ptp->setflags = setflags;
	ptp->TEST_AUTOCOMMIT = TEST_AUTOCOMMIT;
	ptp->dboflags = DB_THREAD;

	// This may fail because there is already dbenv.
	__os_mkdir(NULL, "dbenv", 0777);
	if (!multionly){
		if (loop_count <= 0)
			loop_count = 1;
		dbstl_startup();
		for (; loop_count > 0; loop_count--){
			rmdir_rcsv("dbenv", true);
			BDBOP(__os_mkdir(NULL, "dbenv/data", 0777), ret);// This should not fail.
			penv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
			BDBOP(penv->set_flags(setflags, 1), ret);
			BDBOP(penv->set_cachesize(0, cachesize, 1), ret);
			BDBOP(penv->set_data_dir("data"), ret);

			// Methods of containers returning a reference costs 
			// locker/object/lock slots.
			penv->set_lk_max_lockers(10000); 
			penv->set_lk_max_objects(10000);
			penv->set_lk_max_locks(10000);

			penv->set_flags(DB_TXN_NOSYNC, 1);
			penv->log_set_config(DB_LOG_IN_MEMORY, 1);
			penv->set_lg_bsize(128 * 1024 * 1024);

			BDBOP(penv->open("dbenv", flags | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0777), ret);
			register_db_env(penv);
			// CDS dose not need deadlock detection
			if (penv->get_open_flags(&oflags) == 0 && ((oflags & DB_INIT_TXN) != 0)) {
				penv->set_lk_detect(DB_LOCK_RANDOM);
				penv->set_timeout(1000000, DB_SET_LOCK_TIMEOUT);

			}

			ptp->dbenv = penv;
			g_env = penv;
			TestVector testvector(ptp);
			testvector.start_test();
			TestAssoc testassoc(ptp);
			testassoc.start_test();
			
			close_all_dbs();
			//close_db_env(penv);
			close_all_db_envs();
			cerr<<"\n\nOne round of dbstl test is run to completion successfully!\n\n";
		}
	}
	else {
		dbstl_startup();
		rmdir_rcsv("dbenv", true);
		BDBOP(__os_mkdir(NULL, "dbenv/data", 0777), ret);// This should not fail.
		penv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
		BDBOP(penv->set_flags(setflags, 1), ret);
		BDBOP(penv->set_cachesize(0, cachesize, 1), ret);
		BDBOP(penv->set_data_dir("data"), ret);

		// Multi-CPU machines requires larger lockers/locks/objects because of 
		// the higher concurrency, more iterators can be opened at the same time. 
		// This setting was required by the stahp05 8-cpu machine, not others.
                BDBOP(penv->set_lk_max_lockers(100000), ret);
                BDBOP(penv->set_lk_max_locks(100000), ret);
                BDBOP(penv->set_lk_max_objects(100000), ret);

		penv->set_flags(DB_TXN_NOSYNC, 1);
		penv->log_set_config(DB_LOG_IN_MEMORY, 1);
		penv->set_lg_bsize(128 * 1024 * 1024);

		BDBOP(penv->open("dbenv", flags | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0777), ret);
		register_db_env(penv);
		// CDS dose not need deadlock detection
		if (penv->get_open_flags(&oflags) == 0 && ((oflags & DB_INIT_TXN) != 0)) {
			penv->set_lk_detect(DB_LOCK_RANDOM);
			penv->set_timeout(1000000, DB_SET_LOCK_TIMEOUT);
		}

		ptp->dbenv = penv;
		g_env = penv;
		
		ThreadMgr thrds, insthrds;
		vector<wt_job> jobs;
		jobs.push_back(wt_insert);
		jobs.push_back(wt_update);
		jobs.push_back(wt_delete);
		srand ((unsigned int)tid);

		for (i = 3; i < nwriter; i++) {
			j = rand() % 3;
			switch (j) {
				case 0: jobs.push_back(wt_insert); break;
				case 1: jobs.push_back(wt_update); break;
				case 2: jobs.push_back(wt_delete); break;
			}
		}

		vector<WorkerThread *> vctthrds;
		WorkerThread *pwthrd;
		for (gi = 0; contypes[gi] != ct_none; gi++) {

			switch (contypes[gi]) {
			case ct_vector: contname = "db_vector"; break;
			case ct_map: contname = "db_map"; break;
			case ct_multimap: contname = "db_multimap"; break;
			case ct_set: contname = "db_set"; break;
			case ct_multiset: contname = "db_multiset"; break;
			default: throw "unexpected container type!"; break;
			}
			cout<<endl<<contname<<" multi-threaded tests:\n";

			g_StopInsert = 0;
			WorkerThread par;
			memset(&par, 0, sizeof(par));
			par.total_insert = totalinsert;
			par.verbose = verbose != 0;
			par.strlenmax = longest;
			par.strlenmin = shortest;
			par.cntnr_type = contypes[gi];
			par.penv = penv;
			if (par.cntnr_type != ct_vector) {
				if (par.cntnr_type == ct_map || 
				    par.cntnr_type == ct_set)
					sflags = 0;
				else	if (par.cntnr_type == ct_multimap || 
				    par.cntnr_type == ct_multiset)
					sflags = DB_DUP;
				par.pdb = dbstl::
				    open_db(penv, "db_mt_map.db", 
				    ptp->dbtype, DB_CREATE | ptp->dboflags, sflags);
			} else if (par.cntnr_type == ct_vector) {
				if (NULL == dbstrv)
					dbstrv = dbstl::open_db(penv, "dbstr.db", 
				    DB_RECNO, DB_CREATE | ptp->dboflags, DB_RENUMBER);
				par.pdb = dbstrv;
			}

			par.txnal = ptp->EXPLICIT_TXN != 0;
			for (j = 0; j < nwriter; j++) {
				par.job = jobs[j];
				pwthrd = new WorkerThread(par);
				if (par.job == wt_insert) {
					insthrds.create_thread(pwthrd);
				} else {
					thrds.create_thread(pwthrd); 
				}
				
				vctthrds.push_back(pwthrd);
				if (j == 0)
					__os_yield(NULL, 3, 0);// sleep 3 secs
			}
		
			par.job = wt_read;
			for (i = 0; i < nreader; i++) {
				pwthrd = new WorkerThread(par);
				thrds.create_thread(pwthrd);
				vctthrds.push_back(pwthrd);
			}
			
			thrds.join_all();

			g_StopInsert = 1;
			insthrds.join_all();
			for (vector<WorkerThread *>::size_type ui = 0; ui < vctthrds.size(); ui++)
				delete vctthrds[ui];
			vctthrds.clear();
			if (ptp->EXPLICIT_TXN && !TEST_AUTOCOMMIT)
				dbstl::begin_txn(0, penv);
			dbstl::close_db(par.pdb);
			penv->dbremove(dbstl::current_txn(penv), "db_mt_map.db", NULL, 0);
			if (ptp->EXPLICIT_TXN && !TEST_AUTOCOMMIT)
				dbstl::commit_txn(penv);
			thrds.clear();
			insthrds.clear();
			cout.flush();
			
		} // for (int gi
		
		
	} // else

	delete ptp;
	dbstl_exit();

	if (penv) 
		delete penv;
}