1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 * $Id$ 7 */ 8 9#include "test.h" 10// This function tests all member functions in the four assocative 11// containers and their iterators. The containers are db_map, 12// db_multimap, db_set, db_multiset . They are equivalent to std::map, 13// hash_map, std::multimap, hash_multimap, std::set, hash_set, 14// std::multiset, hash_multiset respectively---passing btree db handles, 15// they are equivalent to std assocative container; passing hash db handles 16// they are hash associative containers 17// 18// This function tests the classes also in pair with std/hash counterparts, 19// but the result of some operations are checked not by comparing contents 20// after operation, but by self-check, often use another member function of 21// the same class to verify. Also, only the four container types in std is 22// used, the hash containers are not standarized, so not used, although 23// hash db type can be passed in, so the db_containers can be of hash type 24// 25// Most of the algorithms in std are targeting at a sequential range, while 26// ranges in associative containers are not, so only some read only 27// algorithms are applied to the db_map container. 28// 29// This function also tests some advanced features, like using containers 30// with secondary db, bulk retrieval, varying length records storage/load, 31// storing native char*/wchar_t* strings, etc 32// 33 34static int hcmp_def(Db *pdb, const Dbt *dbt1, const Dbt *dbt2) 35{ 36 u_int32_t sz1 = dbt1->get_size(), sz2 = dbt2->get_size(); 37 38 int ret = memcmp(dbt1->get_data(), dbt2->get_data(), sz1 < sz2 ? sz1 : sz2); 39 ret = (ret == 0) ? (sz1 - sz2) : ret; 40 41 return ret; 42} 43 44class TestAssoc 45{ 46public: 47 typedef map<int, int> m_int_t; 48 typedef ptint tpint; 49 ~TestAssoc(); 50 TestAssoc(void *param1); 51 void start_test() 52 { 53 tb.begin("db_map"); 54 test_map_member_functions(); 55 test_map_std_functions(); 56 test_hot_dbclose(); 57 test_arbitrary_object_storage(); 58 test_storing_std_strings(); 59 test_secondary_containers(); 60 tb.end(); 61 62 tb.begin("db_multimap"); 63 test_mmap_member_functions(); 64 tb.end(); 65 66 tb.begin("db_set"); 67 test_set_member_functions(); 68 tb.end(); 69 70 tb.begin("db_multiset"); 71 test_mset_member_functions(); 72 tb.end(); 73 74 tb.begin("Special functionalities of all dbstl containers."); 75 test_char_star_string_storage(); 76 test_fixed_len_obj_storage(); 77 test_arbitray_sequence_storage(); 78 test_bulk_retrieval_read(); 79 test_nested_txns(); 80 test_etc(); 81 tb.end(); 82 83 84 } 85private: 86 // Test all member functions of db_map<> 87 void test_map_member_functions(); 88 89 // Use std functions to manipulate db_map containers. 90 void test_map_std_functions(); 91 92 // Close a live container's db handle then open it again and 93 // reassign to the same container, verify the container works. 94 void test_hot_dbclose(); 95 96 // Use two ways to store an object of arbitrary length. The object 97 // contains some varying length members, char* string for example. 98 void test_arbitrary_object_storage(); 99 100 void test_storing_std_strings(); 101 102 // Open a secondary db H and associate it with an exisitng db handle 103 // which is being used by a container C1, then use H to create another 104 // container C2, verify we can get C1's data via C2. 105 // This technique works for all types of db and containers. 106 void test_secondary_containers(); 107 108 // Test all member functions of db_multimap<>. 109 void test_mmap_member_functions(); 110 111 // Test all member functions of db_set<>. 112 void test_set_member_functions(); 113 114 // Test all member functions of db_multiset<>. 115 void test_mset_member_functions(); 116 117 // Test direct storage of char* strings. 118 void test_char_star_string_storage(); 119 120 // Testing storage of fixed length objects. 121 void test_fixed_len_obj_storage(); 122 123 // Testing storage of arbitrary element type of sequence. 124 void test_arbitray_sequence_storage(); 125 126 // Testing reading with bulk retrieval flag. 127 void test_bulk_retrieval_read(); 128 129 // Testing nested transaction implementation. 130 void test_nested_txns(); 131 132 // Testing miscellaneous functions. 133 void test_etc(); 134 135 int flags, setflags, EXPLICIT_TXN, TEST_AUTOCOMMIT, n; 136 DBTYPE dbtype; 137 dm_int_t::difference_type oddcnt; 138 Db *dmdb1, *dmdb2, *dmmdb1, *dmmdb2, *dmsdb1, 139 *dmsdb2, *dmmsdb1, *dmmsdb2, *dbstrv; 140 Db *dbp3; 141 Db *dmdb6; 142 Db *dbp3sec; 143 Db *dmmdb4, *dbstrmap; 144 Db *dmstringdb; 145 DbEnv *penv; 146 u_int32_t dboflags; 147 148 test_block tb; 149 map<int, int> m1; 150 multimap<int, int> mm1; 151}; 152 153TestAssoc::~TestAssoc() 154{ 155 dbstl::close_db_cursors(this->dmsdb2); 156 dbstl::close_db_cursors(this->dmdb1); 157 dbstl::close_db_cursors(this->dmdb2); 158 dbstl::close_db_cursors(this->dmdb6); 159 dbstl::close_db_cursors(this->dmmdb1); 160} 161 162TestAssoc::TestAssoc(void *param1) 163{ 164 check_expr(param1 != NULL); 165 TestParam *param = (TestParam*)param1; 166 TestParam *ptp = param; 167 168 flags = 0, setflags = 0, EXPLICIT_TXN = 1, TEST_AUTOCOMMIT = 0; 169 dbtype = DB_BTREE; 170 penv = param->dbenv; 171 dmdb1 = dmdb2 = dmmdb1 = dmmdb2 = dmsdb1 = dmsdb2 = dmmsdb1 = 172 dmmsdb2 = dbstrv = NULL; 173 flags = param->flags; 174 dbtype = param->dbtype; 175 setflags = param->setflags; 176 TEST_AUTOCOMMIT = param->TEST_AUTOCOMMIT; 177 EXPLICIT_TXN = param->EXPLICIT_TXN; 178 dboflags = ptp->dboflags; 179 n = 10; 180 181 dmdb1 = dbstl::open_db(penv, "db_map.db", 182 dbtype, DB_CREATE | ptp->dboflags, 0); 183 dmdb2 = dbstl::open_db(penv, "db_map2.db", 184 dbtype, DB_CREATE | ptp->dboflags, 0); 185 dmdb6 = dbstl::open_db(penv, "db_map6.db", 186 dbtype, DB_CREATE | ptp->dboflags, 0); 187 188 dmmdb1 = dbstl::open_db(penv, 189 "db_multimap.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); 190 dmmdb2 = dbstl::open_db(penv, 191 "db_multimap2.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); 192 193 dmsdb1 = dbstl::open_db(penv, "db_set.db", 194 dbtype, DB_CREATE | ptp->dboflags, 0); 195 dmsdb2 = dbstl::open_db(penv, "db_set2.db", 196 dbtype, DB_CREATE | ptp->dboflags, 0); 197 198 dmmsdb1 = dbstl::open_db(penv, 199 "db_multiset.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); 200 dmmsdb2 = dbstl::open_db(penv, 201 "db_multiset2.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); 202 203 dbstrv = dbstl::open_db(penv, "dbstr.db", 204 DB_RECNO, DB_CREATE | ptp->dboflags, DB_RENUMBER); 205 dbp3sec = dbstl::open_db(penv, "db_map_sec.db", 206 dbtype, DB_CREATE | ptp->dboflags, DB_DUP); 207 208 dmmdb4 = dbstl::open_db(penv, 209 "db_multimap4.db", dbtype, DB_CREATE | dboflags, DB_DUPSORT); 210 dbstrmap = dbstl::open_db(penv, "dbstrmap.db", 211 DB_BTREE, DB_CREATE, 0); 212 213 dmstringdb = dbstl::open_db(penv, "db_map_stringdb.db", 214 dbtype, DB_CREATE | dboflags, 0); 215 dbp3 = NULL; 216 217} 218 219void TestAssoc::test_map_member_functions() 220{ 221 int i; 222 223 if (EXPLICIT_TXN) 224 dbstl::begin_txn(0, penv); 225 226 dm_int_t dm1(dmdb1, penv); 227 const dm_int_t& cnstdm1 = dm1; 228 dm_int_t simple_map; 229 map<ptint, ptint> ssimple_map; 230 map<ptint, ptint>::iterator sitr, sitr1; 231 232 for (i = 0; i < n; i++) { 233 dm1[i] = ptint(i); 234 ssimple_map[i] = ptint(i); 235 } 236 237 for (i = 0; i < n; i++) { 238 dm_int_t::const_iterator citr, citr1; 239 dm_int_t::iterator itr; 240 241 citr = dm1.find(i); 242 check_expr(citr->second == dm1.find(i)->second); 243 itr = citr; 244 check_expr(*citr == *itr); 245 itr->second = i * 2 + 1; 246 citr1 = itr; 247 check_expr(*citr == *itr); 248 check_expr(*citr == *citr1); 249 check_expr(citr->second == dm1.find(i)->second); 250 } 251 252 for (i = 0; i < n; i++) { 253 dm_int_t::const_iterator citr = dm1.find(i); 254 check_expr(citr->second == dm1.find(i)->second); 255 dm_int_t::iterator itr = citr; 256 check_expr(*citr == *itr); 257 itr->second = i * 2 + 1; 258 dm_int_t::const_iterator citr1 = itr; 259 check_expr(*citr == *itr); 260 check_expr(*citr == *citr1); 261 check_expr(citr->second == dm1.find(i)->second); 262 } 263 264 for (i = 0; i < n; i++) { 265 dm_int_t::iterator ncitr, ncitr1; 266 dm_int_t::const_iterator citr, citr1; 267 268 ncitr = cnstdm1.find(i); 269 check_expr(ncitr->second == cnstdm1.find(i)->second); 270 citr = ncitr; 271 check_expr(*citr == *ncitr); 272 //*ncitr = i * 2 + 1; 273 citr1 = ncitr; 274 ncitr1 = citr1; 275 check_expr(*citr == *ncitr); 276 check_expr(*citr == *ncitr1); 277 check_expr(*citr == *citr1); 278 check_expr(citr->second == cnstdm1.find(i)->second); 279 } 280 281 for (i = 0; i < n; i++) { 282 283 dm_int_t::iterator ncitr = cnstdm1.find(i); 284 check_expr(ncitr->second == cnstdm1.find(i)->second); 285 dm_int_t::const_iterator citr = ncitr; 286 check_expr(*citr == *ncitr); 287 //*itr = i * 2 + 1; 288 dm_int_t::const_iterator citr1 = ncitr; 289 dm_int_t::iterator ncitr1 = citr1; 290 291 check_expr(*citr == *ncitr); 292 check_expr(*citr == *ncitr1); 293 check_expr(*citr == *citr1); 294 check_expr(citr->second == cnstdm1.find(i)->second); 295 } 296 297 if (dm1.is_hash() == false) 298 { 299 dm1.clear(); 300 ssimple_map.clear(); 301 for (i = 0; i < n; i++) { 302 dm1[i] = ptint(i); 303 ssimple_map[i] = ptint(i); 304 } 305 dm_int_t::iterator ncitr = dm1.end(); 306 dm_int_t::iterator ncrend = --dm1.begin(); 307 map<ptint, ptint>::iterator sitr = ssimple_map.end(); 308 for (sitr--, --ncitr; ncitr != ncrend; ncitr--, sitr--) { 309 ncitr.refresh(true); // not needed because by default we are using direct db get, only for test purpose. 310 check_expr(*sitr == *ncitr); 311 } 312 ncitr.close_cursor(); 313 314 const dm_int_t&cnstdm1 = dm1; 315 dm_int_t::const_iterator citr = cnstdm1.end(); 316 dm_int_t::const_iterator crend = --cnstdm1.begin(); 317 map<ptint, ptint>::iterator sitr2; 318 map<ptint, ptint>::reverse_iterator rsitr; 319 320 sitr = ssimple_map.end(); 321 for (sitr--, --citr; citr!= crend; sitr--, citr--) { 322 citr.refresh(true); // not needed because by default we are using direct db get, only for test purpose. 323 check_expr(*sitr == *citr); 324 } 325 326 for (sitr2 = --ssimple_map.begin(), citr = crend; citr != cnstdm1.end();) { 327 citr++; 328 sitr2++; 329 check_expr(*sitr2 == *citr); 330 } 331 332 simple_map.insert(simple_map.begin(), *ssimple_map.begin()); 333 check_expr(*simple_map.begin() == *ssimple_map.begin()); 334 crend = --cnstdm1.begin(); 335 --(--crend); 336 ++crend; 337 check_expr(*crend == *cnstdm1.begin()); 338 citr.close_cursor(); 339 340 simple_map.clear(); 341 simple_map.insert(cnstdm1.begin(), cnstdm1.end()); 342 rsitr = ssimple_map.rbegin(); 343 for (dm_int_t::reverse_iterator itrr1 = simple_map.rbegin(); itrr1 != simple_map.rend(); ++itrr1, ++rsitr) 344 check_expr(*itrr1 == *rsitr); 345 346 const dm_int_t &csimple_map = simple_map; 347 rsitr = ssimple_map.rbegin(); 348 for (dm_int_t::const_reverse_iterator citrr1 = csimple_map.rbegin(); citrr1 != csimple_map.rend(); ++citrr1, ++rsitr) 349 check_expr((citrr1->first == rsitr->first) && (citrr1->second == rsitr->second)); 350 351 for (sitr = ssimple_map.begin(); sitr != ssimple_map.end(); ++sitr) 352 check_expr(csimple_map[sitr->first] == sitr->second); 353 354 simple_map.erase(simple_map.end()); 355 check_expr(simple_map.size() == ssimple_map.size()); 356 check_expr(csimple_map.find(123) == csimple_map.end()); 357 358 check_expr(*csimple_map.lower_bound(1) == *ssimple_map.lower_bound(1)); 359 check_expr(*csimple_map.upper_bound(5) == *ssimple_map.upper_bound(5)); 360 pair<dm_int_t::const_iterator, dm_int_t::const_iterator> cnsteqrg = csimple_map.equal_range(3); 361 check_expr(cnsteqrg.first->first == 3 && cnsteqrg.second->first == ssimple_map.equal_range(3).second->first); 362 363 } 364 dm1.clear(); 365 ssimple_map.clear(); 366 367 if (!dm1.is_hash()) { 368 for (i = 0; i < n; i++) { 369 dm1[i] = ptint(i); 370 ssimple_map[i] = ptint(i); 371 } 372 dm_int_t::iterator itr, itr1; 373 374 itr = dm1.find(3); 375 itr1 = dm1.find(8); 376 sitr = ssimple_map.find(3); 377 sitr1 = ssimple_map.find(8); 378 379 dm1.erase(itr, itr1); 380 ssimple_map.erase(sitr, sitr1); 381 pprint(dm1, "dm1 after erasing range: "); 382 check_expr(is_equal(dm1, ssimple_map)); 383 dm1.clear(); 384 ssimple_map.clear(); 385 } 386 for (i = 0; i < 10; i++) { 387 simple_map.insert(make_pair(ptint(i), ptint(i))); 388 ssimple_map.insert(make_pair(ptint(i), ptint(i))); 389 } 390 for (i = 0; i < 10; i++) 391 check_expr(simple_map[i] == ssimple_map[i]); 392 393 dm1.clear(); 394 // db_map<>::empty 395 check_expr(dm1.empty()); 396 fill(dm1, m1, i = 3, n = 5); 397 check_expr(!dm1.empty()); 398 399 dm_int_t::iterator dmi, dmi2; 400 m_int_t::iterator mi; 401 dm_int_t::reverse_iterator dmri; 402 m_int_t::reverse_iterator mri; 403 ptint ptmp; 404 int itmp; 405 406 407 // db_map<>::find, count 408 for (dmi = dm1.begin(), mi = m1.begin(), i = 3; dmi != dm1.end() && 409 mi !=m1.end(); dmi++, mi++, i++) { 410 // check_expr both contain 411 check_expr((dm1.find(i) != dm1.end()) && 412 (m1.find(i) != m1.end())); 413 414 pair<dm_int_t::iterator, dm_int_t::iterator> erp = 415 dm1.equal_range(i); 416 int jc = 0; 417 dm_int_t::iterator jj; 418 for (jj = erp.first, jc = 0; 419 jj != erp.second; jj++, jc++) 420 check_expr((*jj).second == ptint(i)); 421 check_expr(jc == 1); 422 if (i < 7 && !dm1.is_hash()) {// 7 is last element 423 check_expr((*(dm1.upper_bound(i))).second == i + 1); 424 check_expr((*(dm1.lower_bound(i))).second == i); 425 } 426 else if (i == 7 && !dm1.is_hash()) { 427 check_expr(dm1.upper_bound(i) == dm1.end()); 428 check_expr((*(dm1.lower_bound(i))).second == i); 429 } else if (!dm1.is_hash()) 430 check_expr(false); 431 432 check_expr(dm1.count(i) == 1); 433 check_expr(dm1.count(-i) == 0); 434 check_expr((ptmp = dm1[i]) == (itmp = m1[i])); 435 436 // order of elements in hash can not be expected 437 if (!dm1.is_hash()) 438 check_expr((*dmi).second == (*mi).second); 439 if (i == 3 + n - 1) {// last element 440 441 for (; dmi != dm1.end(); mi--, i--) { 442 // check_expr both contains 443 check_expr((*(dm1.find(i))).second == i); 444 check_expr((ptmp = dm1[i]) == (itmp = m1[i])); 445 // order of elements in hash can not be 446 // expected 447 if (!dm1.is_hash()) 448 check_expr((*dmi).second == (*mi).second); 449 if (i % 2) 450 dmi--; 451 else 452 --dmi; 453 } 454 break; 455 } 456 457 } 458 for (dmri = dm1.rbegin(), mri = m1.rbegin(), i = 3; 459 dmri != dm1.rend() && mri != m1.rend(); dmri++, mri++, i++) { 460 check_expr((dm1.find(i) != dm1.end()) && 461 (m1.find(i) != m1.end()));// check_expr both contain 462 463 check_expr(dm1[i] == m1[i]); 464 if (!dm1.is_hash()) 465 check_expr((*dmri).second == (*mri).second); 466 if (i == 3 + n - 1) {// last element 467 468 for (; dmri != dm1.rend(); mri--, i--) { 469 // check_expr both contain 470 check_expr((*(dm1.find(i))).second == i); 471 // order of elements in hash can not be expected 472 if (!dm1.is_hash()) 473 check_expr((*dmri).second == (*mri).second); 474 check_expr((ptmp = dm1[i]) == (itmp = m1[i])); 475 if (i % 2) 476 dmri--; 477 else 478 --dmri; 479 if (i == 3) 480 break; 481 } 482 break; 483 } 484 485 } 486 for (dmi = dm1.begin(), mi = m1.begin(), i = 3; dmi != dm1.end() && 487 mi !=m1.end(); ++dmi, mi++) 488 i++; 489 check_expr(i == 3 + n);// i must have been incremented to 8 490 for (dmri = dm1.rbegin(), mri = m1.rbegin(), i = 3; 491 dmri != dm1.rend() && mri !=m1.rend(); ++dmri, mri++) 492 i++; 493 check_expr(i == 3 + n);// i must have been incremented to 8 494 495 496 if (EXPLICIT_TXN) 497 commit_txn(penv); 498 if (!TEST_AUTOCOMMIT) 499 begin_txn(0, penv); 500 dm_int_t dm2(dmdb2, penv); 501 dm2.clear(); 502 if (!TEST_AUTOCOMMIT) 503 commit_txn(penv); 504 if (EXPLICIT_TXN) 505 begin_txn(0, penv); 506 dm2.insert(dm1.begin(), dm1.end()); 507 if (EXPLICIT_TXN) 508 commit_txn(penv); 509 if (!TEST_AUTOCOMMIT) 510 begin_txn(0, penv); 511 dm_int_t dm3 = dm2; 512 if (!TEST_AUTOCOMMIT) 513 commit_txn(penv); 514 if (EXPLICIT_TXN) 515 begin_txn(0, penv); 516 check_expr(dm3 == dm2); 517 if (EXPLICIT_TXN) 518 commit_txn(penv); 519 if (!TEST_AUTOCOMMIT) 520 begin_txn(0, penv); 521 dm3 = dm1; 522 if (!TEST_AUTOCOMMIT) 523 commit_txn(penv); 524 if (EXPLICIT_TXN) 525 begin_txn(0, penv); 526 check_expr(dm3 == dm1); 527 // this test case should be fine for hash because hash config is 528 // identical in dm1 and dm2 529 for (dmi = dm1.begin(), dmi2 = dm2.begin(); dmi != dm1.end() && 530 dmi2 != dm2.end(); ++dmi, dmi2++) 531 check_expr(*dmi == *dmi2); 532 int arr1[] = {33, 44, 55, 66, 77}; 533 534 for (dmi = dm1.begin(), i = 0; dmi != dm1.end(); dmi++, i++) 535 (*dmi).second = tpint(arr1[i]); 536 537 for (dmi = dm1.begin(), dmi2 = dm2.begin(), i = 0; 538 dmi != dm1.end() && dmi2 != dm2.end(); dmi++, i++, dmi2++) { 539 check_expr((*dmi).second == tpint(arr1[i])); 540 dmi2->second = dmi->second; 541 check_expr(*dmi == *dmi2); 542 } 543 // db_map<>::insert(const value_type&). the range insert is already 544 // tested in fill 545 // 546 pair<dm_int_t::iterator, bool> res = 547 dm1.insert(make_pair(3, tpint(33))); 548 check_expr((*(res.first)).first == 3 && res.second == false); 549 // we don't know which value is assigned to key 3 on hash 550 if (!dm1.is_hash()) 551 check_expr((*(res.first)).second == 33); 552 553 // db_map<>::count, insert, erase, find 554 check_expr(dm1.count(3) == 1); 555 check_expr(dm1.size() == (size_t)n);// n is 5 556 check_expr(dm1.count(9) == 0); 557 res = dm1.insert(make_pair(9, tpint(99))); 558 check_expr((*(res.first)).second == 99 && (*(res.first)).first == 9 && 559 res.second == true); 560 check_expr(dm1.count(9) == 1); 561 check_expr(dm1.size() == (size_t)n + 1); 562 563 if (EXPLICIT_TXN) 564 dbstl::commit_txn(penv); 565 566 if (!TEST_AUTOCOMMIT) 567 dbstl::begin_txn(0, penv); 568 dm1.erase(9); 569 if (!TEST_AUTOCOMMIT) 570 commit_txn(penv); 571 if (EXPLICIT_TXN) 572 begin_txn(0, penv); 573 574 check_expr(dm1.size() == (size_t)n); 575 check_expr(dm1.count(9) == 0); 576 dm1.erase(dm1.find(3)); 577 check_expr(dm1.size() == (size_t)n - 1); 578 check_expr(dm1.count(3) == 0); 579 dm2.erase(dm2.begin(), dm2.end()); 580 check_expr(dm2.size() == 0); 581 check_expr(dm2.empty()); 582 583 dmi = dm1.begin(); 584 dmi++; 585 dmi2 = dmi; 586 dmi2++; 587 dmi2++; 588 589 if (dm1.is_hash()) { 590 check_expr(dm1.key_eq()(3, 4) == false); 591 check_expr(dm1.key_eq()(3, 3) == true); 592 check_expr(dm1.bucket_count() != 0); 593 } else 594 check_expr(dm1.key_comp()(3, 4)); 595 596 if (dm1.is_hash()) { 597 check_expr(dm1.key_eq()(3, 4) == false); 598 check_expr(dm1.key_eq()(3, 3) == true); 599 } else { 600 check_expr(dm1.key_comp()(3, 4)); 601 } 602 603 check_expr(dm1.value_comp()(*dmi, *dmi2)); 604 if (dm1.is_hash()) 605 cout<<"hash value for key = 3 is: " 606 <<dm1.hash_funct()(3); 607 608 dm2.insert(dmi, dmi2);// 2 recs inserted, [dmi, dmi2) 609 check_expr(dm2.size() == 2); 610 for (dmi = dm1.begin(); dmi != dm1.end(); dmi++) 611 cout<<'\t'<<dmi->first<<'\t'<<dmi->second<<endl; 612 if (EXPLICIT_TXN) 613 commit_txn(penv); 614 615 if (!TEST_AUTOCOMMIT) { 616 begin_txn(0, penv); 617 } 618 dm1.swap(dm2); 619 if (!TEST_AUTOCOMMIT) { 620 commit_txn(penv); 621 } 622 if (EXPLICIT_TXN) 623 begin_txn(0, penv); 624 size_t dm1sz, dm2sz; 625 check_expr((dm1sz = dm1.size()) == 2 && 626 (dm2sz = dm2.size()) == (size_t)n - 1); 627 if (EXPLICIT_TXN) 628 dbstl::commit_txn(penv); 629 630 if (!TEST_AUTOCOMMIT) { 631 begin_txn(0, penv); 632 } 633 dm1.clear(); 634 dm2.clear(); 635 dm3.clear(); 636 if (!TEST_AUTOCOMMIT) { 637 commit_txn(penv); 638 } 639 if (EXPLICIT_TXN) 640 begin_txn(0, penv); 641 fill(dm1, m1, i = 3, n = 5); 642 dm1sz = dm1.size(); 643 for (i = (int)dm1sz -1; i >0; i--) { 644 dm1[i - 1] = dm1[i]; 645 m1[i - 1] = m1[i]; 646 } 647 if (!dm1.is_hash()) 648 check_expr (is_equal(dm1, m1)); 649 dm1[421] = 421; 650 check_expr(dm1.count(421) == 1); 651 m1[421] = 421; 652 int j; 653 for (i = 0; i < 100; i++) { 654 j = rand() ; 655 dm1[i] = i * j; 656#ifdef TEST_PRIMITIVE 657 m1[i] = ((ptint)dm1[i]); 658#else 659 m1[i] = ((ptint)dm1[i]).v; 660#endif 661 } 662 check_expr(dm1.size() == m1.size()); 663 if (!dm1.is_hash()) 664 check_expr (is_equal(dm1, m1)); 665 666 for (i = 0; i < 99; i++) { 667 dm1[i] = dm1[i + 1]; 668 m1[i] = m1[i + 1]; 669 } 670 if (!dm1.is_hash()) 671 check_expr (is_equal(dm1, m1)); 672 dm1.clear(); 673 m1.clear(); 674 if (EXPLICIT_TXN) 675 commit_txn(penv); 676} // test_map_member_functions 677 678void TestAssoc::test_map_std_functions() 679{ 680 int i; 681 682 if (EXPLICIT_TXN) 683 begin_txn(0, penv); 684 dm_int_t dm1(dmdb1, penv); 685 // the following test assumes dm1 and m1 contains 686 // (6,6), (7,7),...(14,14) 687 for(i = 6; i < 15; i++) { 688 dm1[i] = i; 689 m1[i] = i; 690 } 691 dm_int_t::iterator mpos, mpos2; 692 dm_int_t::reverse_iterator mrpos, mrpos2; 693// for_each 694 cout<<"\n_testing std algorithms applied to db_map...\n"; 695 cout<<"\nfor_each begin to end\n"; 696 for_each(dm1.begin(), dm1.end(), square_pair<dm_int_t::value_type_wrap>); 697 cout<<endl; 698 for_each(m1.begin(), m1.end(), square_pair2<map<int, int>::value_type>); 699 cout<<"\nfor_each begin +1 to end\n"; 700 for_each(dm1.begin() ++, (dm1.begin()--)--, square_pair<dm_int_t::value_type_wrap>); 701 cout<<endl; 702 for_each(m1.begin() ++, (m1.begin() --)--, square_pair2<map<int, int>::value_type>); 703 704 //find 705 ptint tgt(12); 706 mpos = find(dm1.begin(), dm1.end(), make_pair(tgt, tgt)); 707 check_expr(mpos != dm1.end() && ((mpos->second) == tgt)); 708 mpos = find(++(dm1.begin() ++), --(dm1.end() --), make_pair(tgt, tgt)); 709 check_expr(mpos != dm1.end() && ((mpos->second) == tgt)); 710 tgt = -123; 711 mpos = find(dm1.begin(), dm1.end(), make_pair(tgt, tgt)); 712 check_expr(mpos == dm1.end()); 713 pair<int, int>* subseq3 = new pair<int, int>[3]; 714 subseq3[0] = make_pair(8, 8); 715 subseq3[1] = make_pair(9, 9); 716 subseq3[2] = make_pair(10, 10); 717 pair<int, int>* subseq4 = new pair<int, int>[4]; 718 subseq4[0] = make_pair(9, 9); 719 subseq4[1] = make_pair(8, 8); 720 subseq4[2] = make_pair(10, 10); 721 subseq4[3] = make_pair(11, 11); 722 // find_end 723 if (!dm1.is_hash()) { 724#ifdef WIN32 725 mpos = find_end(dm1.begin(), dm1.end(), dm1.begin(), ++(dm1.begin()) ); 726 check_expr(mpos == dm1.begin()); 727 mpos = find_end(dm1.begin(), dm1.end(), mpos2 = ++(++(dm1.begin()++)), 728 --(--(dm1.end()--))); 729 check_expr(mpos == mpos2); 730 731 mpos = find_end(++dm1.begin(), dm1.end(), subseq3, subseq3 + 3); 732 check_expr(mpos == ++(++(dm1.begin()))); 733#endif 734 // find_first_of 735 mpos = find_first_of(dm1.begin(), dm1.end(), dm1.begin(), 736 ++dm1.begin()); 737 check_expr(mpos == dm1.begin()); 738 739 mpos = find_first_of(++dm1.begin(), --dm1.end(), 740 subseq4, subseq4 + 4); 741 check_expr(mpos == ++(++dm1.begin())); 742 mpos = find_first_of(--(--dm1.end()), dm1.end(), 743 subseq4, subseq4 + 4); 744 check_expr(mpos == dm1.end()); 745 746 // mismatch 747 748 pair<dm_int_t::iterator , pair<int, int>*> resmm2 = mismatch(dm1.begin(), 749 ++(++(++dm1.begin())), subseq3); 750 check_expr(resmm2.first == dm1.begin() && resmm2.second == subseq3); 751 752 //search 753 mpos = search(dm1.begin(), dm1.end(), dm1.begin(), ++dm1.begin()); 754 check_expr(mpos == dm1.begin()); 755 mpos = search(++dm1.begin(), dm1.end(), subseq3, subseq3 + 3); 756 check_expr(mpos == ++(++dm1.begin())); 757 //equal 758 mpos2 = dm1.begin(); 759 mpos2.move_to(8); 760 check_expr (equal(dm1.begin(), mpos2, subseq3) == false); 761 mpos = mpos2; mpos.move_to(11); 762 check_expr(equal(mpos2, mpos, subseq3) == true); 763 mpos.move_to(10); 764 check_expr(equal(mpos2, mpos, subseq3) == true); 765 } 766 delete [] subseq4; 767 delete [] subseq3; 768 //find_if 769 mpos = find_if(dm1.begin(), dm1.end(), is2digits_pair); 770 check_expr(ptint(mpos->second) == 10); 771 772 // count_if 773 oddcnt = count_if(dm1.begin(), dm1.end(), is_odd_pair); 774 check_expr(oddcnt == 4); 775 oddcnt = count_if(dm1.begin(), dm1.begin(), is_odd_pair); 776 check_expr(oddcnt == 0); 777 778 779 if ( EXPLICIT_TXN) 780 dbstl::commit_txn(penv); 781 782 783} // test_map_std_functions 784 785void TestAssoc::test_hot_dbclose() 786{ 787 int i; 788 map<ptint, ptint> m2; 789 dm_int_t dm2(dmdb2, penv); 790 791 if (!TEST_AUTOCOMMIT) 792 dbstl::begin_txn(0, penv); 793 dm2.clear();// can be auto commit 794 if (!TEST_AUTOCOMMIT) 795 dbstl::commit_txn(penv); 796 797 if (EXPLICIT_TXN) 798 begin_txn(0, penv); 799 for (i = 0; i < 5; i++) { 800 dm2[i] = i; 801 m2[i] = i; 802 } 803 804 if (EXPLICIT_TXN) 805 dbstl::commit_txn(penv); 806 dm_int_t dm1(dmdb1, penv); 807 dbstl::close_db(dm1.get_db_handle()); 808 if (EXPLICIT_TXN) 809 dbstl::begin_txn(0, penv); 810 811 dm1.set_db_handle(dbp3 = dbstl::open_db(penv, "db_map.db", 812 dbtype, DB_CREATE | dboflags, 0)); 813 if (!dm1.is_hash()) 814 check_expr (is_equal(dm1, m1)); 815 dm1.clear(); 816 if (EXPLICIT_TXN) 817 commit_txn(penv); 818} // test_hot_dbclose 819 820void TestAssoc::test_arbitrary_object_storage() 821{ 822 int i; 823 824 if (EXPLICIT_TXN) 825 begin_txn(0, penv); 826 // varying length objects test 827 cout<<"\n_testing arbitary object storage using Dbt..\n"; 828 829 rand_str_dbt smsdbt; 830 DbstlDbt dbt, dbtmsg; 831 string msgstr; 832 SMSMsg *smsmsgs[10]; 833 834 dbtmsg.set_flags(DB_DBT_USERMEM); 835 dbt.set_data(DbstlMalloc(256)); 836 dbt.set_flags(DB_DBT_USERMEM); 837 dbt.set_ulen(256); 838 db_map<int, DbstlDbt> msgmap(dbp3, penv); 839 for (i = 0; i < 10; i++) { 840 smsdbt(dbt, msgstr, 10, 200); 841 SMSMsg *pmsg = SMSMsg::make_sms_msg(time(NULL), 842 (char *)dbt.get_data(), i); 843 smsmsgs[i] = SMSMsg::make_sms_msg(time(NULL), 844 (char *)dbt.get_data(), i); 845 dbtmsg.set_data(pmsg); 846 dbtmsg.set_ulen((u_int32_t)(pmsg->mysize)); 847 dbtmsg.set_size((u_int32_t)(pmsg->mysize)); 848 dbtmsg.set_flags(DB_DBT_USERMEM); 849 msgmap.insert(make_pair(i, dbtmsg)); 850 free(pmsg); 851 memset(&dbtmsg, 0, sizeof(dbtmsg)); 852 } 853 dbtmsg.set_data(NULL); 854 // check that retrieved data is identical to stored data 855 SMSMsg *psmsmsg; 856 for (i = 0; i < 10; i++) { 857 db_map<int, DbstlDbt>::data_type_wrap msgref = msgmap[i]; 858 psmsmsg = (SMSMsg *)msgref.get_data(); 859 860 check_expr(memcmp(smsmsgs[i], psmsmsg, 861 smsmsgs[i]->mysize) == 0); 862 } 863 864 i = 0; 865 for (db_map<int, DbstlDbt>::iterator msgitr = msgmap.begin(ReadModifyWriteOption:: 866 read_modify_write()); msgitr != msgmap.end(); ++msgitr, i++) { 867 db_map<int, DbstlDbt>::reference smsmsg = *msgitr; 868 (((SMSMsg*)(smsmsg.second.get_data())))->when = time(NULL); 869 smsmsg.second._DB_STL_StoreElement(); 870 871 } 872 873 for (i = 0; i < 10; i++) 874 free(smsmsgs[i]); 875 876 msgmap.clear(); 877 878 879 cout<<"\n_testing arbitary object(sparse, varying length) storage support using registered callbacks...\n"; 880 db_map<int, SMSMsg2> msgmap2(dbp3, penv); 881 SMSMsg2 smsmsgs2[10]; 882 DbstlElemTraits<SMSMsg2>::instance()->set_copy_function(SMSMsgCopy); 883 DbstlElemTraits<SMSMsg2>::instance()->set_size_function(SMSMsgSize); 884 DbstlElemTraits<SMSMsg2>::instance()->set_restore_function(SMSMsgRestore); 885 // use new technique to store varying length and inconsecutive objs 886 for (i = 0; i < 10; i++) { 887 smsdbt(dbt, msgstr, 10, 200); 888 SMSMsg2 msg2(time(NULL), msgstr.c_str(), i); 889 smsmsgs2[i] = msg2; 890 891 msgmap2.insert(make_pair(i, msg2)); 892 893 } 894 895 // check that retrieved data is identical to stored data 896 SMSMsg2 tmpmsg2; 897 for (i = 0; i < 10; i++) { 898 tmpmsg2 = msgmap2[i]; 899 check_expr(smsmsgs2[i] == tmpmsg2); 900 } 901 for (db_map<int, SMSMsg2>::iterator msgitr = msgmap2.begin(ReadModifyWriteOption:: 902 read_modify_write()); msgitr != msgmap2.end(); msgitr++) { 903 db_map<int, SMSMsg2>::reference smsmsg = *msgitr; 904 smsmsg.second.when = time(NULL); 905 smsmsg.second._DB_STL_StoreElement(); 906 907 } 908 msgmap2.clear(); 909 if (EXPLICIT_TXN) 910 commit_txn(penv); 911} // test_arbitrary_object_storage 912 913// std::string persistent test. 914void TestAssoc::test_storing_std_strings() 915{ 916 string kstring = "hello world", *sstring = new string("hi there"); 917 if (EXPLICIT_TXN) 918 begin_txn(0, penv); 919 920 db_map<string, string> pmap(dmstringdb, NULL); 921 922 pmap[kstring] = *sstring + "!"; 923 *sstring = pmap[kstring]; 924 map<string, string> spmap; 925 spmap.insert(make_pair(kstring, *sstring)); 926 cout<<"sstring append ! is : "<<pmap[kstring]<<" ; *sstring is : "<<*sstring; 927 delete sstring; 928 for (db_map<string, string>::iterator ii = pmap.begin(); 929 ii != pmap.end(); 930 ++ii) { 931 cout << (*ii).first << ": " << (*ii).second << endl; 932 } 933 close_db(dmstringdb); 934 935 dmstringdb = dbstl::open_db(penv, "db_map_stringdb.db", 936 dbtype, DB_CREATE | dboflags, 0); 937 db_map<string, string> pmap2(dmstringdb, NULL); 938 for (db_map<string, string>::iterator ii = pmap2.begin(); 939 ii != pmap2.end(); 940 ++ii) { 941 cout << (*ii).first << ": " << (*ii).second << endl; 942 // assert key/data pair set equal 943 check_expr((spmap.count(ii->first) == 1) && (spmap[ii->first] == ii->second)); 944 } 945 if (EXPLICIT_TXN) 946 commit_txn(penv); 947 948 db_vector<string> strvctor(10); 949 vector<string> sstrvctor(10); 950 for (int i = 0; i < 10; i++) { 951 strvctor[i] = "abc"; 952 sstrvctor[i] = strvctor[i]; 953 } 954 check_expr(is_equal(strvctor, sstrvctor)); 955} 956 957void TestAssoc::test_secondary_containers() 958{ 959 int i; 960 961 if (EXPLICIT_TXN) 962 begin_txn(0, penv); 963 // test secondary db 964 cout<<"\n_testing db container backed by secondary database..."; 965 966 dbp3->associate(dbstl::current_txn(penv), dbp3sec, 967 get_dest_secdb_callback, DB_CREATE); 968 typedef db_multimap<int, BaseMsg> sec_mmap_t; 969 sec_mmap_t secmmap(dbp3sec, penv);// index "to" field 970 db_map<int, BaseMsg> basemsgs(dbp3, penv); 971 basemsgs.clear(); 972 BaseMsg tmpmsg; 973 multiset<BaseMsg> bsmsgs, bsmsgs2; 974 multiset<BaseMsg>::iterator bsitr1, bsitr2; 975 // populate primary and sec db 976 for (i = 0; i < 10; i++) { 977 tmpmsg.when = time(NULL); 978 tmpmsg.to = 100 - i % 3;// sec index multiple 979 tmpmsg.from = i + 20; 980 bsmsgs.insert( tmpmsg); 981 basemsgs.insert(make_pair(i, tmpmsg)); 982 983 } 984 check_expr(basemsgs.size() == 10); 985 // check retrieved data is identical to those fed in 986 sec_mmap_t::iterator itrsec; 987 for (itrsec = secmmap.begin(ReadModifyWriteOption::no_read_modify_write(), true); 988 itrsec != secmmap.end(); itrsec++) { 989 bsmsgs2.insert(itrsec->second); 990 } 991 for (bsitr1 = bsmsgs.begin(), bsitr2 = bsmsgs2.begin(); 992 bsitr1 != bsmsgs.end() && bsitr2 != bsmsgs2.end(); bsitr1++, bsitr2++) { 993 check_expr(*bsitr1 == *bsitr2); 994 } 995 check_expr(bsitr1 == bsmsgs.end() && bsitr2 == bsmsgs2.end()); 996 997 // search using sec index, check the retrieved data is expected 998 // and exists in bsmsgs 999 check_expr(secmmap.size() == 10); 1000 pair<sec_mmap_t::iterator, sec_mmap_t::iterator> secrg = 1001 secmmap.equal_range(98); 1002 1003 for (itrsec = secrg.first; itrsec != secrg.second; itrsec++) { 1004 check_expr(itrsec->second.to == 98 && 1005 bsmsgs.count(itrsec->second) > 0); 1006 } 1007 // delete via sec db 1008 size_t nersd = secmmap.erase(98); 1009 check_expr(10 - nersd == basemsgs.size()); 1010 secrg = secmmap.equal_range(98); 1011 check_expr(secrg.first == secrg.second); 1012 1013 if (EXPLICIT_TXN) 1014 dbstl::commit_txn(penv); 1015 1016} // test_secondary_containers 1017 1018void TestAssoc::test_mmap_member_functions() 1019{ 1020 // db_multimap<> 1021 int i; 1022 1023 if (EXPLICIT_TXN) 1024 dbstl::begin_txn(0, penv); 1025 dmm_int_t dmm1(dmmdb1, penv); 1026 1027 dmm1.clear(); 1028 // db_multimap<>::empty 1029 check_expr(dmm1.empty()); 1030 { 1031 size_t sz0, szeq1, szeq2; 1032 1033 fill(dmm1, mm1, i = 3, n = 5, 4); 1034 const dmm_int_t &cdmm1 = dmm1; 1035 dmm_int_t dmmn(NULL, penv); 1036 dmmn.insert(cdmm1.begin(), cdmm1.end()); 1037 check_expr(!(dmmn != cdmm1)); 1038 1039 pair<dmm_int_t::const_iterator, dmm_int_t::const_iterator> cnstrg, ceqrgend; 1040 pair<dmm_int_t::iterator, dmm_int_t::iterator> nceqrg, eqrgend; 1041 1042 for (i = 3; i < 8; i++) { 1043 cnstrg = cdmm1.equal_range(i); 1044 nceqrg = dmm1.equal_range(i); 1045 dmm_int_t::const_iterator cmmitr; 1046 dmm_int_t::iterator mmitr; 1047 for (sz0 = 0, cmmitr = cnstrg.first, mmitr = nceqrg.first; mmitr != nceqrg.second; mmitr++, cmmitr++, sz0++) 1048 check_expr(*cmmitr == *mmitr); 1049 check_expr(cmmitr == cnstrg.second); 1050 if (i < 7) 1051 check_expr(*(cdmm1.upper_bound(i)) == *(dmm1.upper_bound(i))); 1052 cnstrg = cdmm1.equal_range_N(i, szeq1); 1053 nceqrg = dmm1.equal_range_N(i, szeq2); 1054 check_expr(szeq1 == szeq2 && szeq2 == sz0); 1055 } 1056 eqrgend = dmm1.equal_range(65535); 1057 check_expr(eqrgend.first == dmm1.end() && eqrgend.second == dmm1.end()); 1058 eqrgend = dmm1.equal_range_N(65535, szeq1); 1059 check_expr(eqrgend.first == dmm1.end() && eqrgend.second == dmm1.end() && szeq1 == 0); 1060 ceqrgend = cdmm1.equal_range(65535); 1061 check_expr(ceqrgend.first == cdmm1.end() && ceqrgend.second == cdmm1.end()); 1062 ceqrgend = cdmm1.equal_range_N(65535, szeq1); 1063 check_expr(ceqrgend.first == cdmm1.end() && ceqrgend.second == cdmm1.end() && szeq1 == 0); 1064 if (!dmm1.is_hash()) { 1065 eqrgend = dmm1.equal_range(2); 1066 check_expr((((eqrgend.first))->first == 3) && ((eqrgend.second))->first == 3); 1067 ceqrgend = cdmm1.equal_range(2); 1068 check_expr(((ceqrgend.first))->first == 3 && ((ceqrgend.second))->first == 3); 1069 eqrgend = dmm1.equal_range_N(2, szeq1); 1070 check_expr((eqrgend.first)->first == 3 && ((eqrgend.second))->first == 3 && szeq1 == 0); 1071 ceqrgend = cdmm1.equal_range_N(2, szeq1); 1072 check_expr((ceqrgend.first)->first == 3 && ((ceqrgend.second))->first == 3 && szeq1 == 0); 1073 1074 check_expr(((dmm1.upper_bound(2)))->first == 3); 1075 check_expr(((cdmm1.upper_bound(2)))->first == 3); 1076 check_expr(dmm1.upper_bound(65535) == dmm1.end()); 1077 check_expr(cdmm1.upper_bound(65535) == cdmm1.end()); 1078 check_expr(dmm1.lower_bound(65535) == dmm1.end()); 1079 check_expr(cdmm1.lower_bound(65535) == cdmm1.end()); 1080 check_expr(dmm1.count(65535) == 0); 1081 check_expr(dmm1.find(65535) == dmm1.end()); 1082 check_expr(cdmm1.find(65535) == cdmm1.end()); 1083 1084 dmm_int_t tmpdmm0(dmm1); 1085 dmm1.erase(dmm1.end()); 1086 check_expr(dmm1 == tmpdmm0); 1087 nceqrg = tmpdmm0.equal_range(5); 1088 1089 for (dmm_int_t::iterator itr0 = nceqrg.first; itr0 != nceqrg.second; ++itr0) 1090 itr0->second *= 2; 1091 check_expr(tmpdmm0 != dmm1); 1092 tmpdmm0.insert(dmm1.begin(), ++(++dmm1.begin())); 1093 check_expr(tmpdmm0 != dmm1); 1094 } 1095 dmm1.clear(); 1096 mm1.clear(); 1097 } 1098 fill(dmm1, mm1, i = 3, n = 5, 4); 1099 check_expr(!dmm1.empty()); 1100 1101 typedef multimap<int, int> mm_int_t; 1102 dmm_int_t::iterator dmmi, dmmi2; 1103 mm_int_t::iterator mmi; 1104 dmm_int_t::reverse_iterator dmmri; 1105 mm_int_t::reverse_iterator mmri; 1106 1107 print_mm(dmm1, dmmi); 1108 // db_multimap<>::find, count 1109 for (dmmi = dmm1.begin(), mmi = mm1.begin(), i = 3; 1110 dmmi != dmm1.end() && 1111 mmi !=mm1.end(); dmmi++, mmi++, i++) { 1112 // check_expr both contain 1113 check_expr((*(dmm1.find(i))).second == i); 1114 1115 pair<dmm_int_t::iterator, dmm_int_t::iterator> erp1 = 1116 dmm1.equal_range(i); 1117 int jc = 0; 1118 dmm_int_t::iterator jj; 1119 for (jj = erp1.first, jc = 0; 1120 jj != erp1.second; jj++, jc++) 1121 check_expr((*jj).second == ptint(i)); 1122 1123 check_expr((size_t)jc == g_count[i]); // g_count[i] duplicates 1124 if (i < 7 && !dmm1.is_hash()) {// 7 is last element 1125 check_expr((*(dmm1.upper_bound(i))).second == i + 1); 1126 check_expr((*(dmm1.lower_bound(i))).second == i); 1127 } 1128 else if (i == 7 && !dmm1.is_hash()) { 1129 check_expr(dmm1.upper_bound(i) == dmm1.end()); 1130 check_expr((*(dmm1.lower_bound(i))).second == i); 1131 } else if (!dmm1.is_hash()) 1132 check_expr(false); 1133 1134 check_expr(dmm1.count(i) == g_count[i]); 1135 check_expr(dmm1.count(-i) == 0); 1136 if (!dmm1.is_hash()) 1137 check_expr((*dmmi).second == (*mmi).second); 1138 if (i == 3 + n - 1) {// last element 1139 1140 for (; dmmi != dmm1.end(); mmi--, i--) { 1141 // check_expr both contains 1142 check_expr((*(dmm1.find(i))).second == i); 1143 if (!dmm1.is_hash()) 1144 check_expr((*dmmi).second == (*mmi).second); 1145 if (i % 2) 1146 dmmi--; 1147 else 1148 --dmmi; 1149 } 1150 break; 1151 } 1152 1153 } 1154 for (dmmri = dmm1.rbegin(), mmri = mm1.rbegin(), i = 3; 1155 dmmri != dmm1.rend() && mmri !=mm1.rend(); dmmri++, mmri++, i++) { 1156 check_expr((dmm1.find(i) != dmm1.end()) && 1157 (mm1.find(i) != mm1.end()));// check_expr both contain 1158 if (dmm1.is_hash() == false) 1159 check_expr((*dmmri).second == (*mmri).second); 1160 if (i == 3 + n - 1) {// last element 1161 1162 for (; dmmri != dmm1.rend() && mmri != mm1.rend(); i--) { 1163 // check_expr both contain 1164 check_expr((*(dmm1.find(i))).second == i); 1165 if (!dmm1.is_hash()) 1166 check_expr((*dmmri).second == (*mmri).second); 1167 if (i % 2) 1168 dmmri--; 1169 else 1170 --dmmri; 1171 if (i > 3) // MS STL bug: when msri points to last element, it can not go back 1172 mmri--; 1173 1174 } 1175 break; 1176 } 1177 1178 } 1179 for (dmmi = dmm1.begin(), mmi = mm1.begin(), i = 3; 1180 dmmi != dmm1.end() && 1181 mmi !=mm1.end(); ++dmmi, mmi++) 1182 i++; 1183 check_expr((size_t)i == 3 + g_sum(3, 8)); 1184 for (dmmri = dmm1.rbegin(), mmri = mm1.rbegin(), i = 3; 1185 dmmri != dmm1.rend() && mmri !=mm1.rend(); ++dmmri, mmri++) 1186 i++; 1187 check_expr((size_t)i == 3 + g_sum(3, 8)); 1188 1189 dmm_int_t dmm2(dmmdb2, penv); 1190 dmm2.clear(); 1191 dmmi = dmm1.begin(); 1192 dmmi2 = dmm1.end(); 1193 dmm2.insert(dmmi, dmmi2); 1194 if (EXPLICIT_TXN) 1195 dbstl::commit_txn(penv); 1196 1197 if (!TEST_AUTOCOMMIT) 1198 dbstl::begin_txn(0, penv); 1199 dmm_int_t dmm3 = dmm2; 1200 if (!TEST_AUTOCOMMIT) 1201 dbstl::commit_txn(penv); 1202 1203 if (EXPLICIT_TXN) 1204 dbstl::begin_txn(0, penv); 1205 check_expr(dmm3 == dmm2); 1206 if (EXPLICIT_TXN) 1207 dbstl::commit_txn(penv); 1208 1209 if (!TEST_AUTOCOMMIT) 1210 dbstl::begin_txn(0, penv); 1211 dmm3 = dmm1; 1212 if (!TEST_AUTOCOMMIT) 1213 dbstl::commit_txn(penv); 1214 1215 if (EXPLICIT_TXN) 1216 dbstl::begin_txn(0, penv); 1217 check_expr(dmm3 == dmm1); 1218 1219 for (dmmi = dmm1.begin(), dmmi2 = dmm2.begin(); dmmi != dmm1.end() && 1220 dmmi2 != dmm2.end(); ++dmmi, dmmi2++) 1221 check_expr(*dmmi == *dmmi2); 1222 1223 // content of dmm1 and dmm2 are changed since now 1224 int arr1[] = {33, 44, 55, 66, 77}; 1225 int arr11[] = {33, 44, 55, 66, 77}; 1226 for (dmmi = dmm1.begin(), i = 0; dmmi != dmm1.end(); dmmi++, i++) 1227 (*dmmi).second = tpint(arr11[i % 5]); 1228 1229 for (dmmi = dmm1.begin(), dmmi2 = dmm2.begin(), i = 0; 1230 dmmi != dmm1.end() && dmmi2 != dmm2.end(); 1231 dmmi++, i++, dmmi2++) { 1232 check_expr((*dmmi).second == tpint(arr1[i % 5])); 1233 dmmi2->second = dmmi->second; 1234 check_expr(*dmmi == *dmmi2); 1235 } 1236 1237 // db_multimap<>::insert(const value_type&). the range insert is already 1238 // tested in fill 1239 // 1240 dmm_int_t::iterator iitr = dmm1.insert(make_pair(3, tpint(33))); 1241 check_expr(iitr->first == 3); 1242 // the returned iitr points to any rec with key==3, not necessarily 1243 // the newly inserted rec, so not sure of the value on hash 1244 if (dmm1.is_hash() == false) 1245 check_expr(iitr->second == 33); 1246 1247 dmm1.clear(); 1248 mm1.clear(); 1249 fill(dmm1, mm1, i = 3, n = 5, 4); 1250 // db_multimap<>::count, insert, erase, find 1251 size_t sizet1; 1252 check_expr(dmm1.count(3) == g_count[3]); 1253 check_expr(dmm1.size() == (sizet1 = g_sum(3, 8)));// sum of recs from 3 to 8 1254 check_expr(dmm1.count(9) == 0); 1255 dmm_int_t::iterator iitr2 = dmm1.insert(make_pair(9, tpint(99))); 1256 check_expr(iitr2->first == 9 && iitr2->second == 99); 1257 check_expr(dmm1.count(9) == 1); 1258 check_expr(dmm1.size() == sizet1 + 1); 1259 dmm1.erase(9); 1260 check_expr(dmm1.size() == (sizet1 = g_sum(3, 8))); 1261 check_expr(dmm1.count(9) == 0); 1262 dmm1.erase(dmm1.find(3)); 1263 check_expr(dmm1.size() == g_sum(3, 8) - 1); 1264 check_expr(dmm1.count(3) == (g_count[3] - 1 > 0 ? g_count[3] - 1 : 0)); 1265 dmm2.erase(dmm2.begin(), dmm2.end()); 1266 check_expr(dmm2.size() == 0); 1267 check_expr(dmm2.empty()); 1268 1269 dmmi = dmm1.begin(); 1270 dmmi++; 1271 dmmi2 = dmmi; 1272 dmmi2++; 1273 dmmi2++; 1274 size_t sizet2; 1275 dmm2.insert(dmmi, dmmi2);// 2 recs inserted, [dmi, dmi2) 1276 check_expr((sizet2 = dmm2.size()) == 2); 1277 if (EXPLICIT_TXN) 1278 dbstl::commit_txn(penv); 1279 1280 if (!TEST_AUTOCOMMIT) 1281 dbstl::begin_txn(0, penv); 1282 1283 dmm1.swap(dmm2); 1284 if (!TEST_AUTOCOMMIT) 1285 dbstl::commit_txn(penv); 1286 1287 if (EXPLICIT_TXN) 1288 dbstl::begin_txn(0, penv); 1289 1290 size_t dmm1sz, dmm2sz; 1291 check_expr((dmm1sz = dmm1.size()) == 2 && (dmm2sz = 1292 dmm2.size()) == sizet1 - 1); 1293 if (EXPLICIT_TXN) 1294 dbstl::commit_txn(penv); 1295 1296 if (!TEST_AUTOCOMMIT) 1297 dbstl::begin_txn(0, penv); 1298 dmm1.clear(); 1299 dmm2.clear(); 1300 dmm3.clear(); 1301 if (!TEST_AUTOCOMMIT) 1302 dbstl::commit_txn(penv); 1303 1304 if (EXPLICIT_TXN) 1305 dbstl::begin_txn(0, penv); 1306 1307 dmm_int_t dmm4(dmmdb4, penv); 1308 dmm4.clear(); 1309 multimap<ptint, ptint> mm4; 1310 int jj; 1311 for (i = 0; i < 10; i++) { 1312 sizet2 = abs(rand() % 20) + 1; 1313 for (jj = 0; jj < (int)sizet2; jj++) { 1314 dmm4.insert(make_pair(i, jj)); 1315 mm4.insert(make_pair(i, jj)); 1316 } 1317 } 1318 pair<dmm_int_t::iterator, dmm_int_t::iterator> eqrgdmm; 1319 pair<multimap<ptint, ptint>::iterator, multimap<ptint, ptint>::iterator> 1320 eqrgmm; 1321 dmm_int_t::iterator dmmitr; 1322 multimap<ptint, ptint>::iterator mmitr; 1323 for (i = 0; i < 10; i++) { 1324 eqrgdmm = dmm4.equal_range(i); 1325 eqrgmm = mm4.equal_range(i); 1326 for (dmmitr = eqrgdmm.first, mmitr = eqrgmm.first; dmmitr != 1327 eqrgdmm.second && mmitr != eqrgmm.second; dmmitr++, mmitr++) 1328 check_expr(*dmmitr == *mmitr); 1329 check_expr((dmmitr == eqrgdmm.second) && (mmitr == eqrgmm.second)); 1330 } 1331 if (EXPLICIT_TXN) 1332 dbstl::commit_txn(penv); 1333 1334} // test_mmap_member_functions 1335 1336void TestAssoc::test_set_member_functions() 1337{ 1338// db_set<> 1339 int i; 1340 int arr1[] = {33, 44, 55, 66, 77}; 1341 1342 if (EXPLICIT_TXN) 1343 dbstl::begin_txn(0, penv); 1344 dms_int_t dms1(dmsdb1, penv); 1345 const dms_int_t& cnstdms1 = dms1; 1346 set<ptint> ms1; 1347 1348 n = 10; 1349 for (i = 0; i < n; i++) 1350 dms1.insert(i); 1351 1352 for (i = 0; i < n; i++) { 1353 dms_int_t::const_iterator citr, citr1; 1354 citr = dms1.find(i); 1355 check_expr(*citr == *dms1.find(i)); 1356 dms_int_t::iterator itr = citr; 1357 check_expr(*citr == *itr); 1358 *itr = i; 1359 itr = dms1.find(i); 1360 citr = itr; 1361 citr1 = itr; 1362 check_expr(*citr == *itr); 1363 check_expr(*citr == *citr1); 1364 check_expr(*citr == *dms1.find(i)); 1365 } 1366 1367 for (i = 0; i < n; i++) { 1368 dms_int_t::const_iterator citr = dms1.find(i); 1369 check_expr(*citr == *dms1.find(i)); 1370 dms_int_t::iterator itr = citr; 1371 check_expr(*citr == *itr); 1372 *itr = i; 1373 itr = dms1.find(i); 1374 citr = itr; 1375 dms_int_t::const_iterator citr1 = itr; 1376 check_expr(*citr == *itr); 1377 check_expr(*citr == *citr1); 1378 check_expr(*citr == *dms1.find(i)); 1379 } 1380 1381 for (i = 0; i < n; i++) { 1382 dms_int_t::iterator ncitr, ncitr1; 1383 dms_int_t::const_iterator citr, citr1; 1384 1385 ncitr = cnstdms1.find(i); 1386 check_expr(*ncitr == *cnstdms1.find(i)); 1387 citr = ncitr; 1388 check_expr(*citr == *ncitr); 1389 //*ncitr = i * 2 + 1; 1390 citr1 = ncitr; 1391 ncitr1 = citr1; 1392 check_expr(*citr == *ncitr); 1393 check_expr(*citr == *ncitr1); 1394 check_expr(*citr == *citr1); 1395 check_expr(*citr == *cnstdms1.find(i)); 1396 } 1397 1398 for (i = 0; i < n; i++) { 1399 1400 dms_int_t::iterator ncitr = cnstdms1.find(i); 1401 check_expr(*ncitr == *cnstdms1.find(i)); 1402 dms_int_t::const_iterator citr = ncitr; 1403 check_expr(*citr == *ncitr); 1404 //*itr = i * 2 + 1; 1405 dms_int_t::const_iterator citr1 = ncitr; 1406 dms_int_t::iterator ncitr1 = citr1; 1407 1408 check_expr(*citr == *ncitr); 1409 check_expr(*citr == *ncitr1); 1410 check_expr(*citr == *citr1); 1411 check_expr(*citr == *cnstdms1.find(i)); 1412 } 1413 1414 if (dms1.is_hash() == false) 1415 { 1416 ms1.clear(); 1417 dms1.clear(); 1418 for (i = 0; i < n; i++) { 1419 dms1.insert(ptint(i)); 1420 ms1.insert(ptint(i)); 1421 } 1422 1423 const dms_int_t &cnstdms1 = dms1; 1424 dms_int_t tmpdms0; 1425 1426 tmpdms0.insert(cnstdms1.begin(), cnstdms1.end()); 1427 dms_int_t::const_iterator citr = dms1.end(), citr2 = --dms1.begin(), itr2; 1428 set<ptint>::const_iterator scitr = ms1.end(), scitr2 = --ms1.begin(); 1429 for (citr--, scitr--; citr != citr2; --citr, --scitr) { 1430 check_expr(*citr == *scitr); 1431 } 1432 check_expr(scitr == scitr2); 1433 1434 db_set<ptype<int> > dmspt; 1435 dmspt.insert(cnstdms1.begin(), cnstdms1.end()); 1436 1437 db_set<ptype<int> >::const_iterator itrpt; 1438 db_set<ptype<int> >::iterator itrpt2; 1439 1440 for (itrpt = dmspt.begin(), citr = dms1.begin(); itrpt != dmspt.end(); ++itrpt, ++citr) { 1441 itrpt.refresh(true); 1442 check_expr(itrpt->v == *citr); 1443 } 1444 1445 for (itrpt2 = dmspt.begin(), itr2 = dms1.begin(); itrpt2 != dmspt.end(); ++itrpt2, ++itr2) { 1446 itrpt2.refresh(true); 1447 check_expr(itrpt2->v == *itr2); 1448 } 1449 1450 dms_int_t dmstmp(dms1); 1451 check_expr(dms1 == dmstmp); 1452 dms1.insert(dms1.begin(), 101); 1453 check_expr(dms1 != dmstmp); 1454 1455 ms1.clear(); 1456 dms1.clear(); 1457 } 1458 dms1.clear(); 1459 // db_map<>::empty 1460 check_expr(dms1.empty()); 1461 fill(dms1, ms1, i = 3, n = 5); 1462 check_expr(!dms1.empty()); 1463 1464 typedef set<int> ms_int_t; 1465 dms_int_t::iterator dmsi, dmsi2; 1466 ms_int_t::iterator msi; 1467 dms_int_t::reverse_iterator dmsri; 1468 ms_int_t::reverse_iterator msri; 1469 1470 // db_set<>::find, count 1471 for (dmsi = dms1.begin(), msi = ms1.begin(), i = 3; dmsi != dms1.end() && 1472 msi !=ms1.end(); dmsi++, msi++, i++) { 1473 // check_expr both contain 1474 check_expr(*(dms1.find(i)) == i); 1475 1476 pair<dms_int_t::iterator, dms_int_t::iterator> erp = 1477 dms1.equal_range(i); 1478 int jc = 0; 1479 dms_int_t::iterator jj; 1480 for (jj = erp.first, jc = 0; 1481 jj != erp.second; jj++, jc++) 1482 check_expr((*jj) == ptint(i)); 1483 check_expr(jc == 1); 1484 if (i < 7 && !dms1.is_hash()) {// 7 is last element 1485 check_expr((*(dms1.upper_bound(i))) == i + 1); 1486 check_expr((*(dms1.lower_bound(i))) == i); 1487 } 1488 else if (i == 7 && !dms1.is_hash()) { 1489 check_expr(dms1.upper_bound(i) == dms1.end()); 1490 check_expr((*(dms1.lower_bound(i))) == i); 1491 } else if (!dms1.is_hash()) 1492 check_expr(false); 1493 1494 check_expr(dms1.count(i) == 1); 1495 check_expr(dms1.count(-i) == 0); 1496 if (!dms1.is_hash()) { 1497 check_expr((*dmsi) == (*msi)); 1498 check_expr((*dmsi) == (*msi)); 1499 } 1500 if (i == 3 + n - 1) {// last element 1501 if (!dms1.is_hash()) 1502 check_expr((*dmsi) == (*msi)); 1503 for (; dmsi != dms1.end() && (*dmsi) == (*msi); i--) { 1504 // check_expr both contains 1505 if (!dms1.is_hash()) 1506 check_expr((*dmsi) == (*msi)); 1507 check_expr((*(dms1.find(i)) == i)); 1508 1509 if (i % 2) 1510 dmsi--; 1511 else 1512 --dmsi; 1513 msi--; 1514 } 1515 break; 1516 } 1517 1518 } 1519 for (dmsri = dms1.rbegin(), msri = ms1.rbegin(), i = 3; 1520 dmsri != dms1.rend() && msri != ms1.rend(); dmsri++, msri++, i++) { 1521 check_expr((*(dms1.find(i)) == i)); 1522 if (!dms1.is_hash()) 1523 check_expr((*dmsri) == (*msri)); 1524 if (i == 3 + n - 1) {// last element 1525 1526 for (; dmsri != dms1.rend() && msri != ms1.rend(); i--) { 1527 // check_expr both contain 1528 check_expr((dms1.find(i) != dms1.end()) && 1529 (ms1.find(i) != ms1.end())); 1530 if (!dms1.is_hash()) 1531 check_expr((*dmsri) == (*msri)); 1532 1533 if (i % 2) 1534 dmsri--; 1535 else 1536 --dmsri; 1537 if (i > 3) // MS STL bug: when msri points to last element, it can not go back 1538 msri--; 1539 1540 } 1541 break; 1542 } 1543 1544 } 1545 for (dmsi = dms1.begin(), msi = ms1.begin(), i = 3; dmsi != dms1.end() && 1546 msi !=ms1.end(); ++dmsi, msi++) 1547 i++; 1548 check_expr(i == 3 + n); 1549 1550 for (dmsri = dms1.rbegin(), msri = ms1.rbegin(), i = 3; 1551 dmsri != dms1.rend() && msri !=ms1.rend(); ++dmsri, msri++) 1552 i++; 1553 check_expr(i == 3 + n); 1554 1555 dms_int_t dms2(dmsdb2, penv); 1556 dms2.clear(); 1557 dms2.insert(dms1.begin(), dms1.end()); 1558 if (EXPLICIT_TXN) 1559 dbstl::commit_txn(penv); 1560 1561 if (!TEST_AUTOCOMMIT) 1562 dbstl::begin_txn(0, penv); 1563 dms_int_t dms3 = dms2; 1564 if (!TEST_AUTOCOMMIT) 1565 dbstl::commit_txn(penv); 1566 1567 if (EXPLICIT_TXN) 1568 dbstl::begin_txn(0, penv); 1569 1570 check_expr(dms3 == dms2); 1571 dms3 = dms1; 1572 if (!TEST_AUTOCOMMIT) 1573 dbstl::commit_txn(penv); 1574 1575 if (EXPLICIT_TXN) 1576 dbstl::begin_txn(0, penv); 1577 1578 check_expr(dms3 == dms1); 1579 1580 for (dmsi = dms1.begin(), dmsi2 = dms2.begin(); dmsi != dms1.end() && 1581 dmsi2 != dms2.end(); ++dmsi, dmsi2++) 1582 check_expr(*dmsi == *dmsi2); 1583 1584 /* !!!XXX 1585 set keys are not supposed to be mutated, so this is an extra functionality, just like 1586 the set iterator assignment in ms's stl library. Here we must use i < dms1.size() to 1587 limit the number of loops because after each assignment, dmsi will be positioned to 1588 the element which is immediately next to the old key it sits on before the assignment, 1589 thus it may take more loops to go to the end() position. 1590 */ 1591 pprint(dms1, "dms1 before iterator assignment : \n"); 1592 dms_int_t::size_type ui; 1593 for (dmsi = dms1.begin(), ui = 0; dmsi != dms1.end() && ui < dms1.size(); dmsi++, ui++) { 1594 (*dmsi) = tpint(arr1[ui]); 1595 pprint(dms1, "\ndms1 after one element assignment : "); 1596 } 1597 if (dms1.is_hash() == false) { 1598 pprint(dms1, "dms1 after iterator assignment : \n"); 1599 for (dmsi = dms1.begin(), dmsi2 = dms2.begin(), i = 0; 1600 dmsi != dms1.end() && dmsi2 != dms2.end(); dmsi++, i++, dmsi2++) { 1601 check_expr((*dmsi) == tpint(arr1[i])); 1602 *dmsi2 = *dmsi; 1603 // check_expr(*dmsi == *dmsi2); dmsi2 is invalidated by the assignment, so can't compare here. 1604 } 1605 // Compare here. 1606 for (dmsi = dms1.begin(), dmsi2 = dms2.begin(), i = 0; 1607 dmsi != dms1.end() && dmsi2 != dms2.end(); dmsi++, i++, dmsi2++) 1608 check_expr(*dmsi2 == *dmsi); 1609 } 1610 1611 dms1.clear(); 1612 //dms2.clear(); 1613 fill(dms1, ms1, i = 3, n = 5); 1614 // db_set<>::insert(const value_type&). the range insert is already 1615 // tested in fill 1616 // 1617 pair<dms_int_t::iterator, bool> ress = 1618 dms1.insert(tpint(3)); 1619 check_expr((*(ress.first)) == 3 && ress.second == false); 1620 1621 // db_set<>::count, insert, erase, find 1622 check_expr(dms1.count(3) == 1); 1623 check_expr(dms1.size() == (size_t)n);// n is 5 1624 check_expr(dms1.count(9) == 0); 1625 ress = dms1.insert(tpint(9)); 1626 check_expr((*(ress.first)) == 9 && ress.second == true); 1627 check_expr(dms1.count(9) == 1); 1628 check_expr(dms1.size() == (size_t)n + 1); 1629 dms1.erase(9); 1630 check_expr(dms1.size() == (size_t)n); 1631 check_expr(dms1.count(9) == 0); 1632 dms1.erase(dms1.find(3)); 1633 check_expr(dms1.size() == (size_t)n - 1); 1634 check_expr(dms1.count(3) == 0); 1635 dms2.erase(dms2.begin(), dms2.end()); 1636 check_expr(dms2.size() == 0); 1637 check_expr(dms2.empty()); 1638 1639 dmsi = dms1.begin(); 1640 dmsi++; 1641 dmsi2 = dmsi; 1642 dmsi2++; 1643 dmsi2++; 1644 dms2.insert(dmsi, dmsi2);// 2 recs inserted, [dmsi, dmsi2) 1645 check_expr(dms2.size() == 2); 1646 if (EXPLICIT_TXN) 1647 dbstl::commit_txn(penv); 1648 1649 if (!TEST_AUTOCOMMIT) 1650 dbstl::begin_txn(0, penv); 1651 dms1.swap(dms2); 1652 if (!TEST_AUTOCOMMIT) 1653 dbstl::commit_txn(penv); 1654 1655 if (EXPLICIT_TXN) 1656 dbstl::begin_txn(0, penv); 1657 size_t dms1sz, dms2sz; 1658 check_expr((dms1sz = dms1.size()) == 2 && (dms2sz = dms2.size()) == (size_t)n - 1); 1659 dms1.clear(); 1660 dms2.clear(); 1661 dms3.clear(); 1662 1663 if (EXPLICIT_TXN) 1664 dbstl::commit_txn(penv); 1665 1666} // test_set_member_functions 1667 1668void TestAssoc::test_mset_member_functions() 1669{ 1670// db_multiset<> 1671 int i; 1672 size_t sizet1; 1673 1674 if (EXPLICIT_TXN) 1675 dbstl::begin_txn(0, penv); 1676 1677 dmms_int_t dmms1(dmmsdb1, penv); 1678 multiset<int> mms1; 1679 1680 dmms1.clear(); 1681 // db_multiset<>::empty 1682 check_expr(dmms1.empty()); 1683 fill(dmms1, mms1, i = 3, n = 5, 4); 1684 check_expr(!dmms1.empty()); 1685 dmms_int_t tmpmms0; 1686 const dmms_int_t &cnstmms = dmms1; 1687 dmms_int_t tmpmms1; 1688 tmpmms1.insert(dmms1.begin(), dmms1.end()); 1689 tmpmms0.insert(cnstmms.begin(), cnstmms.end()); 1690 tmpmms0.insert(tmpmms0.begin(), *(--tmpmms0.end())); 1691 check_expr(tmpmms0 != tmpmms1); 1692 1693 typedef multiset<int> mms_int_t; 1694 dmms_int_t::iterator dmmsi, dmmsi2; 1695 mms_int_t::iterator mmsi; 1696 dmms_int_t::reverse_iterator dmmsri; 1697 mms_int_t::reverse_iterator mmsri; 1698 1699 // db_multiset<>::find, count 1700 for (dmmsi = dmms1.begin(), mmsi = mms1.begin(), i = 3; 1701 dmmsi != dmms1.end() && 1702 mmsi !=mms1.end(); dmmsi++, mmsi++, i++) { 1703 // check_expr both contain 1704 check_expr((*(dmms1.find(i))) == i); 1705 1706 pair<dmms_int_t::iterator, dmms_int_t::iterator> erp1 = 1707 dmms1.equal_range(i); 1708 int jc = 0; 1709 dmms_int_t::iterator jj; 1710 for (jj = erp1.first, jc = 0; 1711 jj != erp1.second; jj++, jc++) { 1712 // there is bug so this line can be reached 1713 if ((size_t)jc == g_count[i]) { 1714 jj == erp1.second;// cmp again to debug it 1715 dmms1.get_db_handle()->stat_print(DB_STAT_ALL); 1716 } 1717 check_expr((*jj) == ptint(i)); 1718 } 1719 check_expr((size_t)jc == g_count[i]); // g_count[i] duplicates 1720 if (i < 7 && !dmms1.is_hash()) {// 7 is last element 1721 check_expr((*(dmms1.upper_bound(i))) == i + 1); 1722 check_expr((*(dmms1.lower_bound(i))) == i); 1723 } 1724 else if (i == 7 && !dmms1.is_hash()) { 1725 check_expr(dmms1.upper_bound(i) == dmms1.end()); 1726 check_expr((*(dmms1.lower_bound(i))) == i); 1727 } else if (!dmms1.is_hash()) 1728 check_expr(false); 1729 1730 check_expr(dmms1.count(i) == g_count[i]); 1731 check_expr(dmms1.count(-i) == 0); 1732 if (!dmms1.is_hash()) 1733 check_expr((*dmmsi) == (*mmsi)); 1734 if (i == 3 + n - 1) {// last element 1735 1736 for (; dmmsi != dmms1.end(); mmsi--, i--) { 1737 // check_expr both contains 1738 check_expr((*(dmms1.find(i))) == i); 1739 if (!dmms1.is_hash()) 1740 check_expr((*dmmsi) == (*mmsi)); 1741 if (i % 2) 1742 dmmsi--; 1743 else 1744 --dmmsi; 1745 } 1746 break; 1747 } 1748 1749 } 1750 for (dmmsri = dmms1.rbegin(), mmsri = mms1.rbegin(), i = 3; 1751 dmmsri != dmms1.rend() && mmsri !=mms1.rend(); dmmsri++, mmsri++, i++) { 1752 check_expr((dmms1.find(i) != dmms1.end()) && 1753 (mms1.find(i) != mms1.end()));// check_expr both contain 1754 if (dmms1.is_hash() == false) 1755 check_expr((*dmmsri) == (*mmsri)); 1756 if (i == 3 + n - 1) {// last element 1757 1758 for (; dmmsri != dmms1.rend() && mmsri != mms1.rend(); i--) { 1759 // check_expr both contain 1760 check_expr((*(dmms1.find(i))) == i); 1761 if (!dmms1.is_hash()) 1762 check_expr((*dmmsri) == (*mmsri)); 1763 if (i % 2) 1764 dmmsri--; 1765 else 1766 --dmmsri; 1767 if (i > 3) // MS STL bug: when msri points to last element, it can not go back 1768 mmsri--; 1769 } 1770 break; 1771 } 1772 1773 } 1774 for (dmmsi = dmms1.begin(), mmsi = mms1.begin(), i = 3; 1775 dmmsi != dmms1.end() && 1776 mmsi !=mms1.end(); ++dmmsi, mmsi++) 1777 i++; 1778 check_expr((size_t)i == 3 + g_sum(3, 8)); 1779 for (dmmsri = dmms1.rbegin(), mmsri = mms1.rbegin(), i = 3; 1780 dmmsri != dmms1.rend() && mmsri !=mms1.rend(); ++dmmsri, mmsri++) 1781 i++; 1782 check_expr((size_t)i == 3 + g_sum(3, 8)); 1783 1784 1785 1786 1787 dmms_int_t dmms2(dmmsdb2, penv); 1788 dmms2.clear(); 1789 dmms2.insert(dmms1.begin(), dmms1.end()); 1790 if (EXPLICIT_TXN) 1791 dbstl::commit_txn(penv); 1792 1793 if (!TEST_AUTOCOMMIT) 1794 dbstl::begin_txn(0, penv); 1795 dmms_int_t dmms3 = dmms2; 1796 if (!TEST_AUTOCOMMIT) 1797 dbstl::commit_txn(penv); 1798 1799 if (EXPLICIT_TXN) 1800 dbstl::begin_txn(0, penv); 1801 cout<<"\ndmms2: \n"; 1802 for (dmms_int_t::iterator itr = dmms2.begin(); itr != dmms2.end(); ++itr) 1803 cout<<"\t"<<*itr; 1804 cout<<"\ndmms3: \n"; 1805 for (dmms_int_t::iterator itr = dmms3.begin(); itr != dmms3.end(); ++itr) 1806 cout<<"\t"<<*itr; 1807 1808 check_expr(dmms3 == dmms2); 1809 if (EXPLICIT_TXN) 1810 dbstl::commit_txn(penv); 1811 1812 if (!TEST_AUTOCOMMIT) 1813 dbstl::begin_txn(0, penv); 1814 dmms3 = dmms1; 1815 if (!TEST_AUTOCOMMIT) 1816 dbstl::commit_txn(penv); 1817 1818 if (EXPLICIT_TXN) 1819 dbstl::begin_txn(0, penv); 1820 check_expr(dmms3 == dmms1); 1821 1822 for (dmmsi = dmms1.begin(), dmmsi2 = dmms2.begin(); dmmsi != dmms1.end() && 1823 dmmsi2 != dmms2.end(); ++dmmsi, dmmsi2++) 1824 check_expr(*dmmsi == *dmmsi2); 1825 1826 // content of dmms1 and dmms2 are changed since now 1827 // int arr11[] = {33, 44, 55, 66, 77}; 1828 1829 // db_multiset<>::insert(const value_type&). the range insert is already 1830 // tested in fill 1831 // 1832 dmms_int_t::iterator iitrms = dmms1.insert(ptint (3)); 1833 check_expr(*iitrms == 3); 1834 1835 dmms1.clear(); 1836 mms1.clear(); 1837 fill(dmms1, mms1, i = 3, n = 5, 4); 1838 // db_multiset<>::count, insert, erase, find 1839 check_expr(dmms1.count(3) == g_count[3]); 1840 check_expr(dmms1.size() == (sizet1 = g_sum(3, 8)));// sum of recs from 3 to 8 1841 check_expr(dmms1.count(9) == 0); 1842 dmms_int_t::iterator iitrms2 = dmms1.insert(ptint (9)); 1843 check_expr(*iitrms2 == 9); 1844 check_expr(dmms1.count(9) == 1); 1845 check_expr(dmms1.size() == sizet1 + 1); 1846 dmms1.erase(9); 1847 check_expr(dmms1.size() == g_sum(3, 8)); 1848 check_expr(dmms1.count(9) == 0); 1849 dmms1.erase(dmms1.find(3)); 1850 check_expr(dmms1.size() == g_sum(3, 8) - 1); 1851 check_expr(dmms1.count(3) == (g_count[3] - 1 > 0 ? g_count[3] - 1 : 0)); 1852 dmms2.erase(dmms2.begin(), dmms2.end()); 1853 check_expr(dmms2.size() == 0); 1854 check_expr(dmms2.empty()); 1855 1856 dmmsi = dmms1.begin(); 1857 dmmsi++; 1858 dmmsi2 = dmmsi; 1859 dmmsi2++; 1860 dmmsi2++; 1861 dmms2.insert(dmmsi, dmmsi2);// 2 recs inserted, [dmi, dmi2) 1862 size_t sssz; 1863 check_expr((sssz = dmms2.size()) == 2); 1864 if (EXPLICIT_TXN) 1865 dbstl::commit_txn(penv); 1866 1867 if (!TEST_AUTOCOMMIT) 1868 dbstl::begin_txn(0, penv); 1869 dmms1.swap(dmms2); 1870 if (!TEST_AUTOCOMMIT) 1871 dbstl::commit_txn(penv); 1872 1873 if (EXPLICIT_TXN) 1874 dbstl::begin_txn(0, penv); 1875 size_t dmms1sz, dmms2sz; 1876 check_expr((dmms1sz = dmms1.size()) == 2 && (dmms2sz = dmms2.size()) == sizet1 - 1); 1877 1878 dmms1.clear(); 1879 dmms2.clear(); 1880 dmms3.clear(); 1881 if (EXPLICIT_TXN) 1882 dbstl::commit_txn(penv); 1883 1884} // test_mset_member_functions 1885 1886void TestAssoc::test_char_star_string_storage() 1887{ 1888 int i; 1889 // testing varying length data element storage/retrieval 1890 cout<<"\n_testing char*/wchar_t* string storage support...\n"; 1891 1892 if (EXPLICIT_TXN) 1893 dbstl::begin_txn(0, penv); 1894 // Use Dbt to wrap any object and store them. This is rarely needed, 1895 // so this piece of code is only for test purpose. 1896 db_vector<DbstlDbt> strv(dbstrv, penv); 1897 vector<string> strsv; 1898 vector<DbstlDbt> strvdbts; 1899 strv.clear(); 1900 1901 int strlenmax = 256, strlenmin = 64; 1902 string str; 1903 DbstlDbt dbt; 1904 rand_str_dbt rand_str_maker; 1905 dbt.set_flags(DB_DBT_USERMEM); 1906 dbt.set_data(DbstlMalloc(strlenmax + 10)); 1907 dbt.set_ulen(strlenmax + 10); 1908 1909 for (int jj = 0; jj < 10; jj++) { 1910 rand_str_maker(dbt, str, strlenmin, strlenmax); 1911 strsv.push_back(str); 1912 strv.push_back(dbt); 1913 } 1914 1915 cout<<"\nstrings:\n"; 1916 for (i = 0; i < 10; i++) { 1917 1918 db_vector<DbstlDbt>::value_type_wrap elemref = strv[i]; 1919 strvdbts.push_back(elemref); 1920 printf("\n%s\n%s", (char*)(strvdbts[i].get_data()), strsv[i].c_str()); 1921 check_expr(strcmp((char*)(elemref.get_data()), strsv[i].c_str()) == 0); 1922 check_expr(strcmp((char*)(strvdbts[i].get_data()), strsv[i].c_str()) == 0); 1923 } 1924 strv.clear(); 1925 1926 if (EXPLICIT_TXN) { 1927 dbstl::commit_txn(penv); 1928 dbstl::begin_txn(0, penv); 1929 } 1930 1931 // Use ordinary way to store strings. 1932 TCHAR cstr1[32], cstr2[32], cstr3[32]; 1933 strcpy(cstr1, "abc"); 1934 strcpy(cstr2, "defcd"); 1935 strcpy(cstr3, "edggsefcd"); 1936// = _T("abc"), *cstr2 = _T("defcd"), *cstr3 = _T("edggsefcd"); 1937 typedef db_map<int, TCHAR*, ElementHolder<TCHAR*> > strmap_t; 1938 strmap_t strmap(dmdb6, penv); 1939 strmap.clear(); 1940 strmap.insert(make_pair(1, cstr1)); 1941 strmap.insert(make_pair(2, cstr2)); 1942 strmap.insert(make_pair(3, cstr3)); 1943 cout<<"\n strings in strmap:\n"; 1944 for (strmap_t::const_iterator citr = strmap.begin(); citr != strmap.end(); citr++) 1945 cout<<(*citr).second<<'\t'; 1946 cout<<strmap[1]<<strmap[2]<<strmap[3]; 1947 TCHAR cstr4[32], cstr5[32], cstr6[32]; 1948 _tcscpy(cstr4, strmap[1]); 1949 _tcscpy(cstr5, strmap[2]); 1950 _tcscpy(cstr6, strmap[3]); 1951 _tprintf(_T("%s, %s, %s"), cstr4, cstr5, cstr6); 1952 strmap_t::value_type_wrap::second_type vts = strmap[1]; 1953 using_charstr(vts); 1954 vts._DB_STL_StoreElement(); 1955 _tcscpy(cstr4, _T("hello world")); 1956 vts = cstr4; 1957 vts._DB_STL_StoreElement(); 1958 cout<<"\n\nstrmap[1]: "<<strmap[1]; 1959 check_expr(_tcscmp(strmap[1], cstr4) == 0); 1960 vts[0] = _T('H');// itis wrong to do it this way 1961 vts._DB_STL_StoreElement(); 1962 check_expr(_tcscmp(strmap[1], _T("Hello world")) == 0); 1963 TCHAR *strbase = vts._DB_STL_value(); 1964 strbase[6] = _T('W'); 1965 vts._DB_STL_StoreElement(); 1966 check_expr(_tcscmp(strmap[1], _T("Hello World")) == 0); 1967 strmap.clear(); 1968 1969 typedef db_map<const char *, const char *, ElementHolder<const char *> > cstrpairs_t; 1970 cstrpairs_t strpairs(dmdb6, penv); 1971 strpairs["abc"] = "def"; 1972 strpairs["ghi"] = "jkl"; 1973 strpairs["mno"] = "pqrs"; 1974 strpairs["tuv"] = "wxyz"; 1975 cstrpairs_t::const_iterator ciitr; 1976 cstrpairs_t::iterator iitr; 1977 for (ciitr = strpairs.begin(), iitr = strpairs.begin(); iitr != strpairs.end(); ++iitr, ++ciitr) { 1978 cout<<"\n"<<iitr->first<<"\t"<<iitr->second; 1979 cout<<"\n"<<ciitr->first<<"\t"<<ciitr->second; 1980 check_expr(strcmp(ciitr->first, iitr->first) == 0 && strcmp(ciitr->second, iitr->second) == 0); 1981 } 1982 1983 typedef db_map<char *, char *, ElementHolder<char *> > strpairs_t; 1984 typedef std::map<string, string> sstrpairs_t; 1985 sstrpairs_t sstrpairs2; 1986 strpairs_t strpairs2; 1987 rand_str_dbt randstr; 1988 1989 for (i = 0; i < 100; i++) { 1990 string rdstr, rdstr2; 1991 randstr(dbt, rdstr); 1992 randstr(dbt, rdstr2); 1993 strpairs2[(char *)rdstr.c_str()] = (char *)rdstr2.c_str(); 1994 sstrpairs2[rdstr] = rdstr2; 1995 } 1996 strpairs_t::iterator itr; 1997 strpairs_t::const_iterator citr; 1998 1999 for (itr = strpairs2.begin(); itr != strpairs2.end(); ++itr) { 2000 check_expr(strcmp(strpairs2[itr->first], itr->second) == 0); 2001 check_expr(string(itr->second) == sstrpairs2[string(itr->first)]); 2002 strpairs_t::value_type_wrap::second_type&secref = itr->second; 2003 std::reverse((char *)secref, (char *)secref + strlen(secref)); 2004 secref._DB_STL_StoreElement(); 2005 std::reverse(sstrpairs2[itr->first].begin(), sstrpairs2[itr->first].end()); 2006 } 2007 2008 check_expr(strpairs2.size() == sstrpairs2.size()); 2009 for (citr = strpairs2.begin(ReadModifyWriteOption::no_read_modify_write(), 2010 true, BulkRetrievalOption::bulk_retrieval()); citr != strpairs2.end(); ++citr) { 2011 check_expr(strcmp(strpairs2[citr->first], citr->second) == 0); 2012 check_expr(string(citr->second) == sstrpairs2[string(citr->first)]); 2013 } 2014 2015 2016 if (EXPLICIT_TXN) 2017 dbstl::commit_txn(penv); 2018 2019 db_vector<const char *, ElementHolder<const char *> > csvct(10); 2020 vector<const char *> scsvct(10); 2021 const char *pconststr = "abc"; 2022 for (i = 0; i < 10; i++) { 2023 scsvct[i] = pconststr; 2024 csvct[i] = pconststr; 2025 csvct[i] = scsvct[i]; 2026 // scsvct[i] = csvct[i]; assignment won't work because scsvct 2027 // only stores pointer but do not copy the sequence, thus it 2028 // will refer to an invalid pointer when i changes. 2029 } 2030 for (i = 0; i < 10; i++) { 2031 check_expr(strcmp(csvct[i], scsvct[i]) == 0); 2032 cout<<endl<<(const char *)(csvct[i]); 2033 } 2034 2035 db_vector<const wchar_t *, ElementHolder<const wchar_t *> > wcsvct(10); 2036 vector<const wchar_t *> wscsvct(10); 2037 const wchar_t *pconstwstr = L"abc"; 2038 for (i = 0; i < 10; i++) { 2039 wscsvct[i] = pconstwstr; 2040 wcsvct[i] = pconstwstr; 2041 wcsvct[i] = wscsvct[i]; 2042 // scsvct[i] = csvct[i]; assignment won't work because scsvct 2043 // only stores pointer but do not copy the sequence, thus it 2044 // will refer to an invalid pointer when i changes. 2045 } 2046 for (i = 0; i < 10; i++) { 2047 check_expr(wcscmp(wcsvct[i], wscsvct[i]) == 0); 2048 2049 } 2050 2051} // test_char_star_string_storage 2052 2053void TestAssoc::test_fixed_len_obj_storage() 2054{ 2055 int i; 2056 map<int, sms_t> ssmsmap; 2057 2058 if (EXPLICIT_TXN) 2059 dbstl::begin_txn(0, penv); 2060 2061 typedef db_map<int, sms_t> smsmap_t; 2062 smsmap_t smsmap(dmdb6, penv); 2063 2064 sms_t smsmsg; 2065 time_t now; 2066 for (i = 0; i < 2008; i++) { 2067 smsmsg.from = 1000 + i; 2068 smsmsg.to = 10000 - i; 2069 smsmsg.sz = sizeof(smsmsg); 2070 time(&now); 2071 smsmsg.when = now; 2072 ssmsmap.insert(make_pair(i, smsmsg)); 2073 smsmap.insert(make_pair(i, smsmsg)); 2074 } 2075 smsmap.clear(); 2076 if (EXPLICIT_TXN) 2077 dbstl::commit_txn(penv); 2078} //test_var_len_obj_storage 2079 2080void TestAssoc::test_arbitray_sequence_storage() 2081{ 2082 int i, j; 2083 2084 if (EXPLICIT_TXN) 2085 dbstl::begin_txn(0, penv); 2086 // storing arbitary sequence test . 2087 cout<<endl<<"Testing arbitary type of sequence storage support...\n"; 2088 RGBB *rgbs[10], *prgb1, *prgb2; 2089 typedef db_map<int, RGBB *, ElementHolder<RGBB *> > rgbmap_t; 2090 rgbmap_t rgbsmap(dmdb6, penv); 2091 2092 map<int, RGBB *> srgbsmap; 2093 2094 DbstlElemTraits<RGBB>::instance()->set_sequence_len_function(rgblen); 2095 DbstlElemTraits<RGBB>::instance()->set_sequence_copy_function(rgbcpy); 2096 // populate srgbsmap and rgbsmap 2097 for (i = 0; i < 10; i++) { 2098 n = abs(rand()) % 10 + 2; 2099 rgbs[i] = new RGBB[n]; 2100 memset(&rgbs[i][n - 1], 0, sizeof(RGBB));//make last element 0 2101 for (j = 0; j < n - 1; j++) { 2102 rgbs[i][j].r_ = i + 128; 2103 rgbs[i][j].g_ = 256 - i; 2104 rgbs[i][j].b_ = 128 - i; 2105 rgbs[i][j].bright_ = 256 / (i + 1); 2106 2107 } 2108 rgbsmap.insert(make_pair(i, rgbs[i])); 2109 srgbsmap.insert(make_pair(i, rgbs[i])); 2110 } 2111 2112 // retrieve and assert equal, then modify and store 2113 for (i = 0; i < 10; i++) { 2114 rgbmap_t::value_type_wrap::second_type rgbelem = rgbsmap[i]; 2115 prgb1 = rgbelem; 2116 check_expr(memcmp(prgb1, prgb2 = srgbsmap[i], 2117 (n = (int)rgblen(srgbsmap[i])) * sizeof(RGBB)) == 0); 2118 for (j = 0; j < n - 1; j++) { 2119 prgb1[j].r_ = 256 - prgb1[j].r_; 2120 prgb1[j].g_ = 256 - prgb1[j].g_; 2121 prgb1[j].b_ = 256 - prgb1[j].b_; 2122 prgb2[j].r_ = 256 - prgb2[j].r_; 2123 prgb2[j].g_ = 256 - prgb2[j].g_; 2124 prgb2[j].b_ = 256 - prgb2[j].b_; 2125 } 2126 rgbelem._DB_STL_StoreElement(); 2127 } 2128 2129 // retrieve again and assert equal 2130 for (i = 0; i < 10; i++) { 2131 rgbmap_t::value_type_wrap::second_type rgbelem = rgbsmap[i]; 2132 prgb1 = rgbelem;// Can't use rgbsmap[i] here because container::operator[] is an temporary value.; 2133 check_expr(memcmp(prgb1, prgb2 = srgbsmap[i], 2134 sizeof(RGBB) * rgblen(srgbsmap[i])) == 0); 2135 } 2136 2137 rgbmap_t::iterator rmitr; 2138 map<int, RGBB *>::iterator srmitr; 2139 2140 for (rmitr = rgbsmap.begin(); 2141 rmitr != rgbsmap.end(); ++rmitr) { 2142 rgbmap_t::value_type_wrap::second_type rgbelem2 = (*rmitr).second; 2143 prgb1 = (*rmitr).second; 2144 srmitr = srgbsmap.find(rmitr->first); 2145 check_expr(memcmp(prgb1, prgb2 = srmitr->second, 2146 sizeof(RGBB) * rgblen(srmitr->second)) == 0); 2147 rmitr.refresh(); 2148 } 2149 2150 for (i = 0; i < 10; i++) 2151 delete []rgbs[i]; 2152 if (EXPLICIT_TXN) 2153 dbstl::commit_txn(penv); 2154} // test_arbitray_sequence_storage 2155 2156void TestAssoc::test_bulk_retrieval_read() 2157{ 2158 2159 int i; 2160 2161 typedef db_map<int, sms_t> smsmap_t; 2162 smsmap_t smsmap(dmdb6, penv); 2163 map<int, sms_t> ssmsmap; 2164 if (EXPLICIT_TXN) 2165 dbstl::begin_txn(0, penv); 2166 2167 cout<<"\n_testing bulk retrieval support:\n"; 2168 sms_t smsmsg; 2169 time_t now; 2170 smsmap.clear(); 2171 for (i = 0; i < 2008; i++) { 2172 smsmsg.from = 1000 + i; 2173 smsmsg.to = 10000 - i; 2174 smsmsg.sz = sizeof(smsmsg); 2175 time(&now); 2176 smsmsg.when = now; 2177 ssmsmap.insert(make_pair(i, smsmsg)); 2178 smsmap.insert(make_pair(i, smsmsg)); 2179 } 2180 2181 // bulk retrieval test. 2182 map<int, sms_t>::iterator ssmsitr = ssmsmap.begin(); 2183 i = 0; 2184 const smsmap_t &rosmsmap = smsmap; 2185 smsmap_t::const_iterator smsitr; 2186 for (smsitr = rosmsmap.begin( 2187 BulkRetrievalOption::bulk_retrieval()); 2188 smsitr != smsmap.end(); i++) { 2189 // The order may be different, so if the two key set are 2190 // identical, it is right. 2191 check_expr((ssmsmap.count(smsitr->first) == 1)); 2192 check_expr((smsitr->second == ssmsmap[smsitr->first])); 2193 if (i % 2) 2194 smsitr++; 2195 else 2196 ++smsitr; // Exercise both pre/post increment. 2197 if (i % 100 == 0) 2198 smsitr.set_bulk_buffer((u_int32_t)(smsitr.get_bulk_bufsize() * 1.1)); 2199 } 2200 2201 smsmap.clear(); 2202 ssmsmap.clear(); 2203 2204 // Using db_vector. when moving its iterator sequentially to end(), 2205 // bulk retrieval works, if moving randomly, it dose not function 2206 // for db_vector iterators. Also, note that we can create a read only 2207 // iterator when using db_vector<>::iterator rather than 2208 // db_vector<>::const_iterator. 2209 db_vector<sms_t> vctsms; 2210 db_vector<sms_t>::iterator itrv; 2211 vector<sms_t>::iterator sitrv; 2212 vector<sms_t> svctsms; 2213 for (i = 0; i < 2008; i++) { 2214 smsmsg.from = 1000 + i; 2215 smsmsg.to = 10000 - i; 2216 smsmsg.sz = sizeof(smsmsg); 2217 time(&now); 2218 smsmsg.when = now; 2219 vctsms.push_back(smsmsg); 2220 svctsms.push_back(smsmsg); 2221 } 2222 2223 for (itrv = vctsms.begin(ReadModifyWriteOption::no_read_modify_write(), 2224 true, BulkRetrievalOption::bulk_retrieval(64 * 1024)), 2225 sitrv = svctsms.begin(), i = 0; itrv != vctsms.end(); 2226 ++itrv, ++sitrv, ++i) { 2227 check_expr(*itrv == *sitrv); 2228 if (i % 100 == 0) 2229 itrv.set_bulk_buffer((u_int32_t)(itrv.get_bulk_bufsize() * 1.1)); 2230 } 2231 2232 if (EXPLICIT_TXN) 2233 dbstl::commit_txn(penv); 2234 2235 2236} //test_bulk_retrieval_read 2237 2238void TestAssoc::test_nested_txns() 2239{ 2240 int i; 2241 size_t sizet1; 2242 2243 if (!EXPLICIT_TXN) 2244 return;// nested txn tests can't be run if container not txnal 2245 2246 // nested transaction test 2247 // 1. many external txns nested, no internal txn. 2248 2249 typedef db_map<char*, char*, ElementHolder<char*> > strstrmap_t; 2250 DbTxn *txn1 = NULL, *txn2, *txn3; 2251 char kstr[10], dstr[10]; 2252 std::map<int, string> kstrs; 2253 int commit_or_abort = 0; 2254 set<int> idxset; 2255 char *keystr; 2256 2257 strstrmap_t smap(dbstrmap, penv); 2258commit_abort: 2259 2260#define _DB_STL_TEST_SET_TXN_NAME(txn) \ 2261 txn->set_name(commit_or_abort == 0 ? #txn"_commit" : #txn"_abort") 2262 2263 txn1 = begin_txn(0, penv); 2264 smap.clear(); 2265 //txn1->set_name(commit_or_abort == 0 ? "txn1_commit" : "txn1_abort"); 2266 _DB_STL_TEST_SET_TXN_NAME(txn1); 2267 memset(kstr, 0, sizeof(kstr)); 2268 memset(dstr, 0, sizeof(dstr)); 2269 for (char cc = 'a'; cc <= 'z'; cc++) { 2270 _snprintf(kstr, 10, "%c%c%c", cc, cc, cc); 2271 for (int kk = 0; kk < 9; kk++) 2272 dstr[kk] = cc; 2273 2274 i = cc - 'a'; 2275 kstrs.insert(make_pair(i, string(kstr))); 2276 switch (i) { 2277 case 3: 2278 txn2 = begin_txn(0, penv);// nest txn2 into txn1 2279 _DB_STL_TEST_SET_TXN_NAME(txn2); 2280 break; 2281 case 6:// 2282 abort_txn(penv); // abort txn2 2283 2284 for (int kk = 3; kk < 6; kk++) { 2285 keystr = const_cast<char*>(kstrs[kk].c_str()); 2286 check_expr(smap.count(keystr) == 0); 2287 } 2288 2289 txn2 = begin_txn(0, penv);// nest txn2 into txn1 2290 _DB_STL_TEST_SET_TXN_NAME(txn2); 2291 break; 2292 case 9:// 6--11: txn3 abort and txn2 commit 2293 txn3 = begin_txn(0, penv);// nest txn3 into txn2, txn2 is in txn1 2294 _DB_STL_TEST_SET_TXN_NAME(txn3); 2295 break; 2296 case 12: 2297 abort_txn(penv);// abort txn3 2298 commit_txn(penv);// commit txn2, its txn3 part is not applied 2299 for (int kk = 6; kk < 12; kk++) { 2300 keystr = const_cast<char*>(kstrs[kk].c_str()); 2301 if (kk < 9) 2302 check_expr((sizet1 = smap.count(keystr)) > 0); 2303 if (kk >= 9) 2304 check_expr(smap.count(keystr) == 0); 2305 } 2306 2307 break; 2308 case 15:// 15--18: txn3 commit and txn2 abort 2309 txn2 = begin_txn(0, penv); 2310 _DB_STL_TEST_SET_TXN_NAME(txn2); 2311 break; 2312 case 17: 2313 txn3 = begin_txn(0, penv); 2314 _DB_STL_TEST_SET_TXN_NAME(txn3); 2315 break; 2316 case 19: 2317 commit_txn(penv);// commit txn3 2318 abort_txn(penv);// abort txn2; 2319 for (int kk = 15; kk < 19; kk++) { 2320 keystr = const_cast<char*>(kstrs[kk].c_str()); 2321 check_expr(smap.count(keystr) == 0); 2322 } 2323 txn2 = begin_txn(0, penv); 2324 _DB_STL_TEST_SET_TXN_NAME(txn2); 2325 break; 2326 case 20: 2327 txn3 = begin_txn(0, penv); 2328 _DB_STL_TEST_SET_TXN_NAME(txn3); 2329 break; 2330 case 22: 2331 // txn3 is unresolved, after commit txn2, txn3 should have been commited 2332 commit_txn(penv, txn2); 2333 for (int kk = 19; kk < 22; kk++) { 2334 keystr = const_cast<char*>(kstrs[kk].c_str()); 2335 check_expr(smap.count(keystr) > 0); 2336 } 2337 txn2 = begin_txn(0, penv); 2338 _DB_STL_TEST_SET_TXN_NAME(txn2); 2339 break; 2340 case 23: 2341 txn3 = begin_txn(0, penv); 2342 _DB_STL_TEST_SET_TXN_NAME(txn3); 2343 break; 2344 case 25: 2345 // txn3 is unresolved, after abort txn2, txn3 should have been aborted 2346 abort_txn(penv, txn2); 2347 for (int kk = 22; kk < 24; kk++) { 2348 keystr = const_cast<char*>(kstrs[kk].c_str()); 2349 check_expr(smap.count(keystr) == 0); 2350 } 2351 2352 break; 2353 2354 default: 2355 break; 2356 2357 }//switch 2358 2359 smap.insert(make_pair(kstr, dstr)); 2360 }// for 2361 2362 if (commit_or_abort == 0) { 2363 2364 // if txn1 commits, 0 1 2 6 7 8 12 13 14 19 20 21 25, 26 2365 idxset.insert(0); 2366 idxset.insert(1); 2367 idxset.insert(2); 2368 idxset.insert(6); 2369 idxset.insert(7); 2370 idxset.insert(8); 2371 idxset.insert(12); 2372 idxset.insert(13); 2373 idxset.insert(14); 2374 idxset.insert(19); 2375 idxset.insert(20); 2376 idxset.insert(21); 2377 idxset.insert(25); 2378 2379 2380 2381 for (int kk = 0; kk < 26; kk++) { 2382 keystr = const_cast<char*>(kstrs[kk].c_str()); 2383 sizet1 = smap.count(keystr); 2384 if (idxset.count(kk) > 0) { 2385 check_expr(sizet1 > 0); 2386 } else { 2387 check_expr(sizet1 == 0); 2388 } 2389 } 2390 2391 commit_or_abort = 1; 2392 smap.clear(); 2393 commit_txn(penv, txn1); 2394 goto commit_abort; 2395 } 2396 2397 if (commit_or_abort != 0){ 2398 abort_txn(penv, txn1);// non could have been inserted 2399 begin_txn(0, penv);// put this call in a txnal context 2400 check_expr((sizet1 = smap.size()) == 0); 2401 commit_txn(penv); 2402 } 2403 2404 if (TEST_AUTOCOMMIT) 2405 dbstl::commit_txn(penv); 2406 2407 2408 return; 2409} // test_nested_txns 2410 2411 2412// Testing miscellaneous functions. 2413void TestAssoc::test_etc() 2414{ 2415 set_global_dbfile_suffix_number(65536); 2416 DbEnv *penvtmp = dbstl::open_env(".", 0, DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL); 2417 dbstl::close_db_env(penvtmp); 2418 db_mutex_t mtxhdl = dbstl::alloc_mutex(); 2419 lock_mutex(mtxhdl); 2420 unlock_mutex(mtxhdl); 2421 free_mutex(mtxhdl); 2422 2423 try { 2424 throw_bdb_exception("test_assoc::test_etc()", DB_LOCK_DEADLOCK); 2425 } catch (DbDeadlockException e1) 2426 {} 2427 2428 try { 2429 throw_bdb_exception("test_assoc::test_etc()", DB_LOCK_NOTGRANTED); 2430 } catch (DbLockNotGrantedException e2) 2431 {} 2432 2433 try { 2434 throw_bdb_exception("test_assoc::test_etc()", DB_REP_HANDLE_DEAD); 2435 } catch (DbRepHandleDeadException e13) 2436 {} 2437 2438 try { 2439 throw_bdb_exception("test_assoc::test_etc()", DB_RUNRECOVERY); 2440 } catch (DbRunRecoveryException e4) 2441 {} 2442 2443 try { 2444 throw_bdb_exception("test_assoc::test_etc()", 12345); 2445 } catch (DbException e1) 2446 {} 2447 2448 try { 2449 throw_bdb_exception("test_assoc::test_etc()", 54321); 2450 } catch (DbException e1) 2451 {} 2452 2453 ptint_vector vctr; 2454 vctr.set_all_flags(1, 1, 1); 2455 check_expr(vctr.get_commit_flags() == 1); 2456 check_expr(vctr.get_cursor_open_flags() == 1); 2457 check_expr(vctr.get_db_open_flags() & DB_CREATE); 2458 check_expr(vctr.get_txn_begin_flags() == 1); 2459 vctr.get_db_set_flags(); 2460 vctr.set_commit_flags(2); 2461 check_expr(vctr.get_commit_flags() == 2); 2462 vctr.set_cursor_open_flags(2); 2463 check_expr(vctr.get_cursor_open_flags() == 2); 2464 vctr.set_txn_begin_flags(2); 2465 check_expr(vctr.get_txn_begin_flags() == 2); 2466 2467 2468} 2469 2470 2471