1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9// test_dbstl.cpp : A test program which tests all container's all methods, 10// by verify the result is identical to expected value, or by doing paralell 11// operations with corresponding container of STL and verify the result of 12// both containers are identical after the same operations. Also, it tests 13// multithreaded test 14// 15#include "db_config.h" 16#include "db_int.h" 17 18#include "test.h" 19#include "test_util.h" 20#include "test_vector.h" 21#include "test_assoc.h" 22#include "test_mt.h" 23 24int main(int argc, char *argv[]) 25{ 26 int c, i, j, ret; 27 int nreader = 5, nwriter = 3; 28 char *mode = NULL; 29 int flags = DB_THREAD, setflags = 0, EXPLICIT_TXN = 0; 30 int TEST_AUTOCOMMIT = 1, totalinsert = 100, verbose = 0; 31 DBTYPE dbtype = DB_BTREE; 32 int gi, shortest = 50, longest = 200, loop_count = 1; 33 bool multionly = false; 34 u_int32_t sflags = 0, oflags = 0; 35 u_int32_t cachesize = 8 * 1024 * 1024; 36 db_threadid_t tid; 37 string contname; 38 DbEnv *penv = NULL; 39 Db *dbstrv = NULL; 40 __os_id(0, 0, &tid); 41 42 TestParam *ptp = new TestParam; 43 ContainerType contypes[] = { 44 ct_vector, 45 ct_map, 46 ct_multimap, 47 ct_set, 48 ct_multiset, 49 ct_none 50 }; 51 52 while ((c = getopt(argc, argv, "MT:c:hk:l:m:n:r:s:t:vw:")) != EOF) { 53 switch (c) { 54 case 'M': 55 multionly = true; 56 break; 57 case 'T': 58 totalinsert = atoi(optarg); 59 break; 60 case 'c': 61 cachesize = atoi(optarg); 62 break; 63 case 'h': 64 usage(); 65 return 0; 66 break; 67 case 'k': 68 shortest = atoi(optarg); 69 break; 70 case 'l': 71 longest = atoi(optarg); 72 break; 73 case 'm': 74 mode = optarg; 75 break; 76 case 'n': 77 loop_count = atoi(optarg); 78 break; 79 case 'r': 80 nreader = atoi(optarg); 81 break; 82 case 's': // db type for associative containers 83 if (*optarg == 'h') // hash db type 84 dbtype = DB_HASH; 85 else if (*optarg == 'b') 86 dbtype = DB_BTREE; 87 else 88 usage(); 89 break; 90 case 't': 91 EXPLICIT_TXN = 1; 92 if (*optarg == 'a') 93 setflags = DB_AUTO_COMMIT; 94 else if (*optarg == 'e') // explicit txn 95 TEST_AUTOCOMMIT = 0; 96 else 97 usage(); 98 break; 99 case 'v': 100 verbose = 1; 101 break; 102 case 'w': 103 nwriter = atoi(optarg); 104 break; 105 default: 106 usage(); 107 break; 108 } 109 } 110 111 if (nwriter < 3) 112 nwriter = 3; 113 114 if (mode == NULL) 115 flags |= 0; 116 else if (*mode == 'c') //cds 117 flags |= DB_INIT_CDB; 118 else if (*mode == 't') 119 flags |= DB_INIT_TXN | DB_RECOVER 120 | DB_INIT_LOG | DB_INIT_LOCK; 121 else 122 flags |= 0; 123 g_test_start_txn = TEST_AUTOCOMMIT * EXPLICIT_TXN; 124 ptp->EXPLICIT_TXN = EXPLICIT_TXN; 125 ptp->flags = flags; 126 ptp->dbtype = dbtype; 127 ptp->setflags = setflags; 128 ptp->TEST_AUTOCOMMIT = TEST_AUTOCOMMIT; 129 ptp->dboflags = DB_THREAD; 130 131 // This may fail because there is already dbenv. 132 __os_mkdir(NULL, "dbenv", 0777); 133 if (!multionly){ 134 if (loop_count <= 0) 135 loop_count = 1; 136 dbstl_startup(); 137 for (; loop_count > 0; loop_count--){ 138 rmdir_rcsv("dbenv", true); 139 BDBOP(__os_mkdir(NULL, "dbenv/data", 0777), ret);// This should not fail. 140 penv = new DbEnv(DB_CXX_NO_EXCEPTIONS); 141 BDBOP(penv->set_flags(setflags, 1), ret); 142 BDBOP(penv->set_cachesize(0, cachesize, 1), ret); 143 BDBOP(penv->set_data_dir("data"), ret); 144 145 // Methods of containers returning a reference costs 146 // locker/object/lock slots. 147 penv->set_lk_max_lockers(10000); 148 penv->set_lk_max_objects(10000); 149 penv->set_lk_max_locks(10000); 150 151 penv->set_flags(DB_TXN_NOSYNC, 1); 152 penv->log_set_config(DB_LOG_IN_MEMORY, 1); 153 penv->set_lg_bsize(128 * 1024 * 1024); 154 155 BDBOP(penv->open("dbenv", flags | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0777), ret); 156 register_db_env(penv); 157 // CDS dose not need deadlock detection 158 if (penv->get_open_flags(&oflags) == 0 && ((oflags & DB_INIT_TXN) != 0)) { 159 penv->set_lk_detect(DB_LOCK_RANDOM); 160 penv->set_timeout(1000000, DB_SET_LOCK_TIMEOUT); 161 162 } 163 164 ptp->dbenv = penv; 165 g_env = penv; 166 TestVector testvector(ptp); 167 testvector.start_test(); 168 TestAssoc testassoc(ptp); 169 testassoc.start_test(); 170 171 close_all_dbs(); 172 //close_db_env(penv); 173 close_all_db_envs(); 174 cerr<<"\n\nOne round of dbstl test is run to completion successfully!\n\n"; 175 } 176 } 177 else { 178 dbstl_startup(); 179 rmdir_rcsv("dbenv", true); 180 BDBOP(__os_mkdir(NULL, "dbenv/data", 0777), ret);// This should not fail. 181 penv = new DbEnv(DB_CXX_NO_EXCEPTIONS); 182 BDBOP(penv->set_flags(setflags, 1), ret); 183 BDBOP(penv->set_cachesize(0, cachesize, 1), ret); 184 BDBOP(penv->set_data_dir("data"), ret); 185 186 // Multi-CPU machines requires larger lockers/locks/objects because of 187 // the higher concurrency, more iterators can be opened at the same time. 188 // This setting was required by the stahp05 8-cpu machine, not others. 189 BDBOP(penv->set_lk_max_lockers(100000), ret); 190 BDBOP(penv->set_lk_max_locks(100000), ret); 191 BDBOP(penv->set_lk_max_objects(100000), ret); 192 193 penv->set_flags(DB_TXN_NOSYNC, 1); 194 penv->log_set_config(DB_LOG_IN_MEMORY, 1); 195 penv->set_lg_bsize(128 * 1024 * 1024); 196 197 BDBOP(penv->open("dbenv", flags | DB_CREATE | DB_INIT_MPOOL | DB_PRIVATE, 0777), ret); 198 register_db_env(penv); 199 // CDS dose not need deadlock detection 200 if (penv->get_open_flags(&oflags) == 0 && ((oflags & DB_INIT_TXN) != 0)) { 201 penv->set_lk_detect(DB_LOCK_RANDOM); 202 penv->set_timeout(1000000, DB_SET_LOCK_TIMEOUT); 203 } 204 205 ptp->dbenv = penv; 206 g_env = penv; 207 208 ThreadMgr thrds, insthrds; 209 vector<wt_job> jobs; 210 jobs.push_back(wt_insert); 211 jobs.push_back(wt_update); 212 jobs.push_back(wt_delete); 213 srand ((unsigned int)tid); 214 215 for (i = 3; i < nwriter; i++) { 216 j = rand() % 3; 217 switch (j) { 218 case 0: jobs.push_back(wt_insert); break; 219 case 1: jobs.push_back(wt_update); break; 220 case 2: jobs.push_back(wt_delete); break; 221 } 222 } 223 224 vector<WorkerThread *> vctthrds; 225 WorkerThread *pwthrd; 226 for (gi = 0; contypes[gi] != ct_none; gi++) { 227 228 switch (contypes[gi]) { 229 case ct_vector: contname = "db_vector"; break; 230 case ct_map: contname = "db_map"; break; 231 case ct_multimap: contname = "db_multimap"; break; 232 case ct_set: contname = "db_set"; break; 233 case ct_multiset: contname = "db_multiset"; break; 234 default: throw "unexpected container type!"; break; 235 } 236 cout<<endl<<contname<<" multi-threaded tests:\n"; 237 238 g_StopInsert = 0; 239 WorkerThread par; 240 memset(&par, 0, sizeof(par)); 241 par.total_insert = totalinsert; 242 par.verbose = verbose != 0; 243 par.strlenmax = longest; 244 par.strlenmin = shortest; 245 par.cntnr_type = contypes[gi]; 246 par.penv = penv; 247 if (par.cntnr_type != ct_vector) { 248 if (par.cntnr_type == ct_map || 249 par.cntnr_type == ct_set) 250 sflags = 0; 251 else if (par.cntnr_type == ct_multimap || 252 par.cntnr_type == ct_multiset) 253 sflags = DB_DUP; 254 par.pdb = dbstl:: 255 open_db(penv, "db_mt_map.db", 256 ptp->dbtype, DB_CREATE | ptp->dboflags, sflags); 257 } else if (par.cntnr_type == ct_vector) { 258 if (NULL == dbstrv) 259 dbstrv = dbstl::open_db(penv, "dbstr.db", 260 DB_RECNO, DB_CREATE | ptp->dboflags, DB_RENUMBER); 261 par.pdb = dbstrv; 262 } 263 264 par.txnal = ptp->EXPLICIT_TXN != 0; 265 for (j = 0; j < nwriter; j++) { 266 par.job = jobs[j]; 267 pwthrd = new WorkerThread(par); 268 if (par.job == wt_insert) { 269 insthrds.create_thread(pwthrd); 270 } else { 271 thrds.create_thread(pwthrd); 272 } 273 274 vctthrds.push_back(pwthrd); 275 if (j == 0) 276 __os_yield(NULL, 3, 0);// sleep 3 secs 277 } 278 279 par.job = wt_read; 280 for (i = 0; i < nreader; i++) { 281 pwthrd = new WorkerThread(par); 282 thrds.create_thread(pwthrd); 283 vctthrds.push_back(pwthrd); 284 } 285 286 thrds.join_all(); 287 288 g_StopInsert = 1; 289 insthrds.join_all(); 290 for (vector<WorkerThread *>::size_type ui = 0; ui < vctthrds.size(); ui++) 291 delete vctthrds[ui]; 292 vctthrds.clear(); 293 if (ptp->EXPLICIT_TXN && !TEST_AUTOCOMMIT) 294 dbstl::begin_txn(0, penv); 295 dbstl::close_db(par.pdb); 296 penv->dbremove(dbstl::current_txn(penv), "db_mt_map.db", NULL, 0); 297 if (ptp->EXPLICIT_TXN && !TEST_AUTOCOMMIT) 298 dbstl::commit_txn(penv); 299 thrds.clear(); 300 insthrds.clear(); 301 cout.flush(); 302 303 } // for (int gi 304 305 306 } // else 307 308 delete ptp; 309 dbstl_exit(); 310 311 if (penv) 312 delete penv; 313} 314