/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2009, 2010 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ #include "StlAdvancedFeatures.h" static void usage(); class StlAdvancedFeaturesExample { public: typedef map m_int_t; typedef ptint tpint; ~StlAdvancedFeaturesExample(); StlAdvancedFeaturesExample(void *param1); void run() { arbitrary_object_storage(); storing_std_strings(); secondary_containers(); char_star_string_storage(); arbitray_sequence_storage(); bulk_retrieval_read(); primitive(); queue_stack(); } private: // Store primitive types of data into dbstl containers. void primitive(); // Use std::queue and std::stack as adapters, and dbstl::db_vector // as container, to make a queue and a stack. void queue_stack(); // Use two ways to store an object of arbitrary length. The object // contains some varying length members, char* string for example. void arbitrary_object_storage(); // Store std::string types of strings. void storing_std_strings(); // Open a secondary db H and associate it with an exisitng db handle // which is being used by a container C1, then use H to create another // container C2, verify we can get C1's data via C2. // This technique works for all types of db and containers. void secondary_containers(); // Direct storage of char* strings. void char_star_string_storage(); // Storage of arbitrary element type of sequence. void arbitray_sequence_storage(); // Reading with bulk retrieval flag. void bulk_retrieval_read(); int flags, setflags, explicit_txn, test_autocommit, n; DBTYPE dbtype; dm_int_t::difference_type oddcnt; Db *db3, *dmdb1, *dmdb2, *dmmdb1, *dmmdb2, *dmsdb1, *dmsdb2, *dmmsdb1, *dmmsdb2, *dbstrv, *pquedb, *quedb; Db *dbp3; Db *dmdb6; Db *dbp3sec; Db *dmmdb4, *dbstrmap; Db *dmstringdb; Db *dbprim; DbEnv *penv; u_int32_t dboflags; map m1; multimap mm1; }; StlAdvancedFeaturesExample::~StlAdvancedFeaturesExample() { } StlAdvancedFeaturesExample::StlAdvancedFeaturesExample(void *param1) { check_expr(param1 != NULL); TestParam *param = (TestParam*)param1; TestParam *ptp = param; flags = 0, setflags = 0, explicit_txn = 1, test_autocommit = 0; dbtype = DB_BTREE; penv = param->dbenv; dmdb1 = dmdb2 = dmmdb1 = dmmdb2 = dmsdb1 = dmsdb2 = dmmsdb1 = dmmsdb2 = dbstrv = NULL; flags = param->flags; dbtype = param->dbtype; setflags = param->setflags; test_autocommit = param->test_autocommit; explicit_txn = param->explicit_txn; dboflags = ptp->dboflags; n = 10; dmdb1 = dbstl::open_db(penv, "db_map.db", dbtype, DB_CREATE | ptp->dboflags, 0); dmdb2 = dbstl::open_db(penv, "db_map2.db", dbtype, DB_CREATE | ptp->dboflags, 0); dmdb6 = dbstl::open_db(penv, "db_map6.db", dbtype, DB_CREATE | ptp->dboflags, 0); dmmdb1 = dbstl::open_db(penv, "db_multimap.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); dmmdb2 = dbstl::open_db(penv, "db_multimap2.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); dmsdb1 = dbstl::open_db(penv, "db_set.db", dbtype, DB_CREATE | ptp->dboflags, 0); dmsdb2 = dbstl::open_db(penv, "db_set2.db", dbtype, DB_CREATE | ptp->dboflags, 0); dmmsdb1 = dbstl::open_db(penv, "db_multiset.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); dmmsdb2 = dbstl::open_db(penv, "db_multiset2.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); dbstrv = dbstl::open_db(penv, "dbstr.db", DB_RECNO, DB_CREATE | ptp->dboflags, DB_RENUMBER); dbp3sec = dbstl::open_db(penv, "db_map_sec.db", dbtype, DB_CREATE | ptp->dboflags, DB_DUP); dmmdb4 = dbstl::open_db(penv, "db_multimap4.db", dbtype, DB_CREATE | dboflags, DB_DUPSORT); dbstrmap = dbstl::open_db(penv, "dbstrmap.db", DB_BTREE, DB_CREATE, 0); dmstringdb = dbstl::open_db(penv, "db_map_stringdb.db", dbtype, DB_CREATE | dboflags, 0); db3 = dbstl::open_db(penv, "db3.db", DB_RECNO, DB_CREATE | ptp->dboflags, DB_RENUMBER); // NO DB_RENUMBER needed quedb = dbstl::open_db(penv, "dbquedb.db", DB_RECNO, DB_CREATE | ptp->dboflags | DB_THREAD, 0); pquedb = dbstl::open_db(penv, "dbpquedb.db", DB_RECNO, DB_CREATE | ptp->dboflags | DB_THREAD, DB_RENUMBER); dbprim = dbstl::open_db(penv, "dbprim.db", DB_RECNO, DB_CREATE | ptp->dboflags | DB_THREAD, DB_RENUMBER); dbp3 = dbstl::open_db(penv, "dbp3.db", dbtype, DB_CREATE | ptp->dboflags, 0); } void StlAdvancedFeaturesExample::arbitrary_object_storage() { int i; if (explicit_txn) begin_txn(0, penv); // varying length objects test cout<<"\nArbitary object storage using Dbt..\n"; rand_str_dbt smsdbt; DbstlDbt dbt, dbtmsg; string msgstr; SMSMsg *smsmsgs[10]; dbtmsg.set_flags(DB_DBT_USERMEM); dbt.set_data(DbstlMalloc(256)); dbt.set_flags(DB_DBT_USERMEM); dbt.set_ulen(256); db_map msgmap(dbp3, penv); for (i = 0; i < 10; i++) { smsdbt(dbt, msgstr, 10, 200); SMSMsg *pmsg = SMSMsg::make_sms_msg(time(NULL), (char *)dbt.get_data(), i); smsmsgs[i] = SMSMsg::make_sms_msg(time(NULL), (char *)dbt.get_data(), i); dbtmsg.set_data(pmsg); dbtmsg.set_ulen((u_int32_t)(pmsg->mysize)); dbtmsg.set_size((u_int32_t)(pmsg->mysize)); dbtmsg.set_flags(DB_DBT_USERMEM); msgmap.insert(make_pair(i, dbtmsg)); free(pmsg); memset(&dbtmsg, 0, sizeof(dbtmsg)); } dbtmsg.set_data(NULL); SMSMsg *psmsmsg; for (i = 0; i < 10; i++) { db_map::data_type_wrap msgref = msgmap[i]; psmsmsg = (SMSMsg *)msgref.get_data(); check_expr(memcmp(smsmsgs[i], psmsmsg, smsmsgs[i]->mysize) == 0); } i = 0; for (db_map::iterator msgitr = msgmap.begin(ReadModifyWriteOption:: read_modify_write()); msgitr != msgmap.end(); ++msgitr, i++) { db_map::reference smsmsg = *msgitr; (((SMSMsg*)(smsmsg.second.get_data())))->when = time(NULL); smsmsg.second._DB_STL_StoreElement(); } for (i = 0; i < 10; i++) free(smsmsgs[i]); msgmap.clear(); cout<<"\nArbitary object(sparse, varying length) storage support using registered callbacks.\n"; db_map msgmap2(dbp3, penv); SMSMsg2 smsmsgs2[10]; DbstlElemTraits::instance()->set_copy_function(SMSMsgCopy); DbstlElemTraits::instance()->set_size_function(SMSMsgSize); DbstlElemTraits::instance()->set_restore_function(SMSMsgRestore); // use new technique to store varying length and inconsecutive objs for (i = 0; i < 10; i++) { smsdbt(dbt, msgstr, 10, 200); SMSMsg2 msg2(time(NULL), msgstr.c_str(), i); smsmsgs2[i] = msg2; msgmap2.insert(make_pair(i, msg2)); } // check that retrieved data is identical to stored data SMSMsg2 tmpmsg2; for (i = 0; i < 10; i++) { tmpmsg2 = msgmap2[i]; check_expr(smsmsgs2[i] == tmpmsg2); } for (db_map::iterator msgitr = msgmap2.begin(ReadModifyWriteOption:: read_modify_write()); msgitr != msgmap2.end(); msgitr++) { db_map::reference smsmsg = *msgitr; smsmsg.second.when = time(NULL); smsmsg.second._DB_STL_StoreElement(); } msgmap2.clear(); if (explicit_txn) commit_txn(penv); } // arbitrary_object_storage // std::string persistent test. void StlAdvancedFeaturesExample::storing_std_strings() { string kstring = "hello world", *sstring = new string("hi there"); if (explicit_txn) begin_txn(0, penv); db_map pmap(dmstringdb, NULL); pmap[kstring] = *sstring + "!"; *sstring = pmap[kstring]; map spmap; spmap.insert(make_pair(kstring, *sstring)); cout<<"sstring append ! is : "<::iterator ii = pmap.begin(); ii != pmap.end(); ++ii) { cout << (*ii).first << ": " << (*ii).second << endl; } close_db(dmstringdb); dmstringdb = dbstl::open_db(penv, "db_map_stringdb.db", dbtype, DB_CREATE | dboflags, 0); db_map pmap2(dmstringdb, NULL); for (db_map::iterator ii = pmap2.begin(); ii != pmap2.end(); ++ii) { cout << (*ii).first << ": " << (*ii).second << endl; // assert key/data pair set equal check_expr((spmap.count(ii->first) == 1) && (spmap[ii->first] == ii->second)); } if (explicit_txn) commit_txn(penv); db_vector strvctor(10); vector sstrvctor(10); for (int i = 0; i < 10; i++) { strvctor[i] = "abc"; sstrvctor[i] = strvctor[i]; } check_expr(is_equal(strvctor, sstrvctor)); } void StlAdvancedFeaturesExample::secondary_containers() { int i; if (explicit_txn) begin_txn(0, penv); // test secondary db cout<<"\ndb container backed by secondary database."; dbp3->associate(dbstl::current_txn(penv), dbp3sec, get_dest_secdb_callback, DB_CREATE); typedef db_multimap sec_mmap_t; sec_mmap_t secmmap(dbp3sec, penv);// index "to" field db_map basemsgs(dbp3, penv); basemsgs.clear(); BaseMsg tmpmsg; multiset bsmsgs, bsmsgs2; multiset::iterator bsitr1, bsitr2; // populate primary and sec db for (i = 0; i < 10; i++) { tmpmsg.when = time(NULL); tmpmsg.to = 100 - i % 3;// sec index multiple tmpmsg.from = i + 20; bsmsgs.insert( tmpmsg); basemsgs.insert(make_pair(i, tmpmsg)); } check_expr(basemsgs.size() == 10); // check retrieved data is identical to those fed in sec_mmap_t::iterator itrsec; for (itrsec = secmmap.begin( ReadModifyWriteOption::no_read_modify_write(), true); itrsec != secmmap.end(); itrsec++) { bsmsgs2.insert(itrsec->second); } for (bsitr1 = bsmsgs.begin(), bsitr2 = bsmsgs2.begin(); bsitr1 != bsmsgs.end() && bsitr2 != bsmsgs2.end(); bsitr1++, bsitr2++) { check_expr(*bsitr1 == *bsitr2); } check_expr(bsitr1 == bsmsgs.end() && bsitr2 == bsmsgs2.end()); // search using sec index, check the retrieved data is expected // and exists in bsmsgs check_expr(secmmap.size() == 10); pair secrg = secmmap.equal_range(98); for (itrsec = secrg.first; itrsec != secrg.second; itrsec++) { check_expr(itrsec->second.to == 98 && bsmsgs.count(itrsec->second) > 0); } // delete via sec db size_t nersd = secmmap.erase(98); check_expr(10 - nersd == basemsgs.size()); secrg = secmmap.equal_range(98); check_expr(secrg.first == secrg.second); if (explicit_txn) dbstl::commit_txn(penv); } // secondary_containers void StlAdvancedFeaturesExample::char_star_string_storage() { int i; // Varying length data element storage/retrieval cout<<"\nchar*/wchar_t* string storage support...\n"; if (explicit_txn) dbstl::begin_txn(0, penv); // Use Dbt to wrap any object and store them. This is rarely needed, // so this piece of code is only for test purpose. db_vector strv(dbstrv, penv); vector strsv; vector strvdbts; strv.clear(); int strlenmax = 256, strlenmin = 64; string str; DbstlDbt dbt; rand_str_dbt rand_str_maker; dbt.set_flags(DB_DBT_USERMEM); dbt.set_data(DbstlMalloc(strlenmax + 10)); dbt.set_ulen(strlenmax + 10); for (int jj = 0; jj < 10; jj++) { rand_str_maker(dbt, str, strlenmin, strlenmax); strsv.push_back(str); strv.push_back(dbt); } cout<<"\nstrings:\n"; for (i = 0; i < 10; i++) { db_vector::value_type_wrap elemref = strv[i]; strvdbts.push_back(elemref); printf("\n%s\n%s", (char*)(strvdbts[i].get_data()), strsv[i].c_str()); check_expr(strcmp((char*)(elemref.get_data()), strsv[i].c_str()) == 0); check_expr(strcmp((char*)(strvdbts[i].get_data()), strsv[i].c_str()) == 0); } strv.clear(); if (explicit_txn) { dbstl::commit_txn(penv); dbstl::begin_txn(0, penv); } // Use ordinary way to store strings. TCHAR cstr1[32], cstr2[32], cstr3[32]; strcpy(cstr1, "abc"); strcpy(cstr2, "defcd"); strcpy(cstr3, "edggsefcd"); typedef db_map > strmap_t; strmap_t strmap(dmdb6, penv); strmap.clear(); strmap.insert(make_pair(1, cstr1)); strmap.insert(make_pair(2, cstr2)); strmap.insert(make_pair(3, cstr3)); cout<<"\n strings in strmap:\n"; for (strmap_t::const_iterator citr = strmap.begin(); citr != strmap.end(); citr++) cout<<(*citr).second<<'\t'; cout< > cstrpairs_t; cstrpairs_t strpairs(dmdb6, penv); strpairs["abc"] = "def"; strpairs["ghi"] = "jkl"; strpairs["mno"] = "pqrs"; strpairs["tuv"] = "wxyz"; cstrpairs_t::const_iterator ciitr; cstrpairs_t::iterator iitr; for (ciitr = strpairs.begin(), iitr = strpairs.begin(); iitr != strpairs.end(); ++iitr, ++ciitr) { cout<<"\n"<first<<"\t"<second; cout<<"\n"<first<<"\t"<second; check_expr(strcmp(ciitr->first, iitr->first) == 0 && strcmp(ciitr->second, iitr->second) == 0); } typedef db_map > strpairs_t; typedef std::map sstrpairs_t; sstrpairs_t sstrpairs2; strpairs_t strpairs2; rand_str_dbt randstr; for (i = 0; i < 100; i++) { string rdstr, rdstr2; randstr(dbt, rdstr); randstr(dbt, rdstr2); strpairs2[(char *)rdstr.c_str()] = (char *)rdstr2.c_str(); sstrpairs2[rdstr] = rdstr2; } strpairs_t::iterator itr; strpairs_t::const_iterator citr; for (itr = strpairs2.begin(); itr != strpairs2.end(); ++itr) { check_expr(strcmp(strpairs2[itr->first], itr->second) == 0); check_expr(string(itr->second) == sstrpairs2[string(itr->first)]); strpairs_t::value_type_wrap::second_type&secref = itr->second; std::reverse((char *)secref, (char *)secref + strlen(secref)); secref._DB_STL_StoreElement(); std::reverse(sstrpairs2[itr->first].begin(), sstrpairs2[itr->first].end()); } check_expr(strpairs2.size() == sstrpairs2.size()); for (citr = strpairs2.begin( ReadModifyWriteOption::no_read_modify_write(), true, BulkRetrievalOption::bulk_retrieval()); citr != strpairs2.end(); ++citr) { check_expr(strcmp(strpairs2[citr->first], citr->second) == 0); check_expr(string(citr->second) == sstrpairs2[string(citr->first)]); } if (explicit_txn) dbstl::commit_txn(penv); db_vector > csvct(10); vector scsvct(10); const char *pconststr = "abc"; for (i = 0; i < 10; i++) { scsvct[i] = pconststr; csvct[i] = pconststr; csvct[i] = scsvct[i]; // scsvct[i] = csvct[i]; assignment won't work because scsvct // only stores pointer but do not copy the sequence, thus it // will refer to an invalid pointer when i changes. } for (i = 0; i < 10; i++) { check_expr(strcmp(csvct[i], scsvct[i]) == 0); cout< > wcsvct(10); vector wscsvct(10); const wchar_t *pconstwstr = L"abc"; for (i = 0; i < 10; i++) { wscsvct[i] = pconstwstr; wcsvct[i] = pconstwstr; wcsvct[i] = wscsvct[i]; // scsvct[i] = csvct[i]; assignment won't work because scsvct // only stores pointer but do not copy the sequence, thus it // will refer to an invalid pointer when i changes. } for (i = 0; i < 10; i++) { check_expr(wcscmp(wcsvct[i], wscsvct[i]) == 0); } } // char_star_string_storage void StlAdvancedFeaturesExample::arbitray_sequence_storage() { int i, j; if (explicit_txn) dbstl::begin_txn(0, penv); // storing arbitary sequence test . cout< > rgbmap_t; rgbmap_t rgbsmap(dmdb6, penv); map srgbsmap; DbstlElemTraits::instance()->set_sequence_len_function(rgblen); DbstlElemTraits::instance()->set_sequence_copy_function(rgbcpy); // populate srgbsmap and rgbsmap for (i = 0; i < 10; i++) { n = abs(rand()) % 10 + 2; rgbs[i] = new RGBB[n]; memset(&rgbs[i][n - 1], 0, sizeof(RGBB));//make last element 0 for (j = 0; j < n - 1; j++) { rgbs[i][j].r_ = i + 128; rgbs[i][j].g_ = 256 - i; rgbs[i][j].b_ = 128 - i; rgbs[i][j].bright_ = 256 / (i + 1); } rgbsmap.insert(make_pair(i, rgbs[i])); srgbsmap.insert(make_pair(i, rgbs[i])); } // retrieve and assert equal, then modify and store for (i = 0; i < 10; i++) { rgbmap_t::value_type_wrap::second_type rgbelem = rgbsmap[i]; prgb1 = rgbelem; check_expr(memcmp(prgb1, prgb2 = srgbsmap[i], (n = (int)rgblen(srgbsmap[i])) * sizeof(RGBB)) == 0); for (j = 0; j < n - 1; j++) { prgb1[j].r_ = 256 - prgb1[j].r_; prgb1[j].g_ = 256 - prgb1[j].g_; prgb1[j].b_ = 256 - prgb1[j].b_; prgb2[j].r_ = 256 - prgb2[j].r_; prgb2[j].g_ = 256 - prgb2[j].g_; prgb2[j].b_ = 256 - prgb2[j].b_; } rgbelem._DB_STL_StoreElement(); } // retrieve again and assert equal for (i = 0; i < 10; i++) { rgbmap_t::value_type_wrap::second_type rgbelem = rgbsmap[i]; // Can't use rgbsmap[i] here because container::operator[] is // an temporary value.; prgb1 = rgbelem; check_expr(memcmp(prgb1, prgb2 = srgbsmap[i], sizeof(RGBB) * rgblen(srgbsmap[i])) == 0); } rgbmap_t::iterator rmitr; map::iterator srmitr; for (rmitr = rgbsmap.begin(); rmitr != rgbsmap.end(); ++rmitr) { rgbmap_t::value_type_wrap::second_type rgbelem2 = (*rmitr).second; prgb1 = (*rmitr).second; srmitr = srgbsmap.find(rmitr->first); rmitr.refresh(); } for (i = 0; i < 10; i++) delete []rgbs[i]; if (explicit_txn) dbstl::commit_txn(penv); } // arbitray_sequence_storage void StlAdvancedFeaturesExample::bulk_retrieval_read() { int i; typedef db_map smsmap_t; smsmap_t smsmap(dmdb6, penv); map ssmsmap; if (explicit_txn) dbstl::begin_txn(0, penv); cout<<"\nBulk retrieval support:\n"; sms_t smsmsg; time_t now; smsmap.clear(); for (i = 0; i < 2008; i++) { smsmsg.from = 1000 + i; smsmsg.to = 10000 - i; smsmsg.sz = sizeof(smsmsg); time(&now); smsmsg.when = now; ssmsmap.insert(make_pair(i, smsmsg)); smsmap.insert(make_pair(i, smsmsg)); } // bulk retrieval test. map::iterator ssmsitr = ssmsmap.begin(); i = 0; const smsmap_t &rosmsmap = smsmap; smsmap_t::const_iterator smsitr; for (smsitr = rosmsmap.begin( BulkRetrievalOption::bulk_retrieval()); smsitr != smsmap.end(); i++) { // The order may be different, so if the two key set are // identical, it is right. check_expr((ssmsmap.count(smsitr->first) == 1)); check_expr((smsitr->second == ssmsmap[smsitr->first])); if (i % 2) smsitr++; else ++smsitr; // Exercise both pre/post increment. if (i % 100 == 0) smsitr.set_bulk_buffer( (u_int32_t)(smsitr.get_bulk_bufsize() * 1.1)); } smsmap.clear(); ssmsmap.clear(); // Using db_vector. when moving its iterator sequentially to end(), // bulk retrieval works, if moving randomly, it dose not function // for db_vector iterators. Also, note that we can create a read only // iterator when using db_vector<>::iterator rather than // db_vector<>::const_iterator. db_vector vctsms; db_vector::iterator itrv; vector::iterator sitrv; vector svctsms; for (i = 0; i < 2008; i++) { smsmsg.from = 1000 + i; smsmsg.to = 10000 - i; smsmsg.sz = sizeof(smsmsg); time(&now); smsmsg.when = now; vctsms.push_back(smsmsg); svctsms.push_back(smsmsg); } for (itrv = vctsms.begin(ReadModifyWriteOption::no_read_modify_write(), true, BulkRetrievalOption::bulk_retrieval(64 * 1024)), sitrv = svctsms.begin(), i = 0; itrv != vctsms.end(); ++itrv, ++sitrv, ++i) { check_expr(*itrv == *sitrv); if (i % 100 == 0) itrv.set_bulk_buffer( (u_int32_t)(itrv.get_bulk_bufsize() * 1.1)); } if (explicit_txn) dbstl::commit_txn(penv); } //bulk_retrieval_read void StlAdvancedFeaturesExample::primitive() { int i; if ( explicit_txn) dbstl::begin_txn(0, penv); db_vector > ivi(dbprim, penv); vector spvi4; fill(ivi, spvi4); check_expr(is_equal(ivi, spvi4)); ivi.clear(false); db_vector > ivi2(dbprim, penv); vector spvi5; fill(ivi2, spvi5); check_expr(is_equal(ivi2, spvi5)); size_t vsz = ivi2.size(); for (i = 0; i < (int)vsz - 1; i++) { ivi2[i] += 3; ivi2[i]--; ivi2[i] <<= 2; ivi2[i] = (~ivi2[i] | ivi2[i] & ivi2[i + 1] ^ (2 * (-ivi2[i + 1]) + ivi2[i]) * 3) / (ivi2[i] * ivi2[i + 1] + 1); spvi5[i] += 3; spvi5[i]--; spvi5[i] <<= 2; spvi5[i] = (~spvi5[i] | spvi5[i] & spvi5[i + 1] ^ (2 * (-spvi5[i + 1]) + spvi5[i]) * 3) / (spvi5[i] * spvi5[i + 1] + 1); } check_expr(is_equal(ivi2, spvi5)); ivi2.clear(false); typedef db_vector > dbl_vct_t; dbl_vct_t dvi(dbprim, penv); vector dsvi; for (i = 0; i < 10; i++) { dvi.push_back(i * 3.14); dsvi.push_back(i * 3.14); } check_expr(is_equal(dvi, dsvi)); dbl_vct_t::iterator ditr; vector::iterator sditr; for (ditr = dvi.begin(), sditr = dsvi.begin(); ditr != dvi.end(); ++ditr, ++sditr){ *ditr *= 2; *sditr *= 2; } check_expr(is_equal(dvi, dsvi)); for (i = 0; i < 9; i++) { dvi[i] /= (-dvi[i] / 3 + 2 * dvi[i + 1]) / (1 + dvi[i]) + 1; dsvi[i] /= (-dsvi[i] / 3 + 2 * dsvi[i + 1]) / (1 + dsvi[i]) + 1; } cout<<"\ndsvi after math operations: \n"; for (i = 0; i <= 9; i++) cout< intq(quev); std::queue sintq; check_expr(intq.empty()); check_expr(intq.size() == 0); for (i = 0; i < 100; i++) { intq.push(ptint(i)); sintq.push(i); check_expr(intq.front() == 0); check_expr(intq.back() == i); } check_expr(intq.size() == 100); for (i = 0; i < 100; i++) { check_expr(intq.front() == i); check_expr(intq.back() == 99); check_expr(intq.front() == sintq.front()); check_expr(sintq.back() == intq.back()); sintq.pop(); intq.pop(); } check_expr(intq.size() == 0); check_expr(intq.empty()); quev.clear(); // std::priority_queue test cout<<"\ndb_vector working with std::priority_queue\n"; std::vector squev; intvec_t pquev(pquedb, penv); pquev.clear(); std::priority_queue intpq(ptintless, pquev); std::priority_queue, ptintless_ft> sintpq(ptintless, squev); check_expr(intpq.empty()); check_expr(intpq.size() == 0); ptint tmppq, tmppq1; set ptintset; for (i = 0; i < 100; i++) { for (;;) {// avoid duplicate tmppq = rand(); if (ptintset.count(tmppq) == 0) { intpq.push(tmppq); sintpq.push(tmppq); ptintset.insert(tmppq); break; } } } check_expr(intpq.empty() == false); check_expr(intpq.size() == 100); for (i = 0; i < 100; i++) { tmppq = intpq.top(); tmppq1 = sintpq.top(); if (i == 98 && tmppq != tmppq1) { tmppq = intpq.top(); } if (i < 98) check_expr(tmppq == tmppq1); if (i == 97) intpq.pop(); else intpq.pop(); sintpq.pop(); } check_expr(intpq.empty()); check_expr(intpq.size() == 0); // std::stack test cout<<"\ndb_vector working with std::stack\n"; std::stack intstk(quev); std::stack sintstk; check_expr(intstk.size() == 0); check_expr(intstk.empty()); for (i = 0; i < 100; i++) { intstk.push(ptint(i)); sintstk.push(ptint(i)); check_expr(intstk.top() == i); check_expr(intstk.size() == (size_t)i + 1); } for (i = 99; i >= 0; i--) { check_expr(intstk.top() == ptint(i)); check_expr(intstk.top() == sintstk.top()); sintstk.pop(); intstk.pop(); check_expr(intstk.size() == (size_t)i); } check_expr(intstk.size() == 0); check_expr(intstk.empty()); // Vector with no handles specified. ptint_vector simple_vct(10); vector ssvct(10); for (i = 0; i < 10; i++) { simple_vct[i] = ptint(i); ssvct[i] = ptint(i); } check_expr(is_equal(simple_vct, ssvct)); if ( explicit_txn) dbstl::commit_txn(penv); return; } // queue_stack DbEnv *g_env; int g_test_start_txn; int main(int argc, char *argv[]) { int c, ret; char *envhome = NULL, *mode = NULL; int flags = DB_THREAD, setflags = 0, explicit_txn = 0; int test_autocommit = 1, totalinsert = 100, verbose = 0; DBTYPE dbtype = DB_BTREE; int shortest = 50, longest = 200; u_int32_t cachesize = 8 * 1024 * 1024; DbEnv *penv = NULL; TestParam *ptp = new TestParam; while ((c = getopt(argc, argv, "T:c:hH:k:l:m:n:r:s:t:v")) != EOF) { switch (c) { case 'T': totalinsert = atoi(optarg); break; case 'c': cachesize = atoi(optarg); break; case 'h': usage(); return 0; break; case 'H': envhome = strdup(optarg); break; case 'k': shortest = atoi(optarg); break; case 'l': longest = atoi(optarg); break; case 'm': mode = 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; default: usage(); break; } } 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; ptp->explicit_txn = explicit_txn; ptp->flags = flags; ptp->dbtype = dbtype; ptp->setflags = setflags; ptp->test_autocommit = test_autocommit; ptp->dboflags = DB_THREAD; // Call this method before any use of dbstl. dbstl_startup(); penv = new DbEnv(DB_CXX_NO_EXCEPTIONS); BDBOP(penv->set_flags(setflags, 1), ret); BDBOP(penv->set_cachesize(0, cachesize, 1), 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); BDBOP(penv->open(envhome, flags | DB_CREATE | DB_INIT_MPOOL, 0777), ret); register_db_env(penv); ptp->dbenv = penv; g_env = penv; g_test_start_txn = test_autocommit * explicit_txn; // Create the example and run. StlAdvancedFeaturesExample example(ptp); example.run(); // Clean up and exit. delete ptp; dbstl_exit();// Call this method before the process exits. if (penv) delete penv; } void usage() { cout<< "\nUsage: StlAdvancedFeaturesExample\n\ [-c number cache size]\n\ [-h print this help message then exit]\n\ [-H dir Specify dir as environment home]\n\ [-k number shortest string inserted]\n\ [-l number longest string inserted]\n\ [-m ds/cds/tds use ds/cds/tds product]\n\ [-s b/h use btree/hash type of DB for assocative \ containers] \n\ [-t a/e for tds, use autocommit/explicit transaction in \ the test] \n\ [-v verbose mode, output more info in multithread \ test]\n\ "; } void using_charstr(TCHAR*str) { cout<<_T("using str read only with non-const parameter type:")<get_data(); result->set_data(&(p->to)); result->set_size(sizeof(p->to)); return 0; } void SMSMsgRestore(SMSMsg2& dest, const void *srcdata) { char *p = dest.msg; memcpy(&dest, srcdata, sizeof(dest)); dest.msg = (char *)DbstlReAlloc(p, dest.szmsg); strcpy(dest.msg, (char*)srcdata + sizeof(dest)); } u_int32_t SMSMsgSize(const SMSMsg2& elem) { return (u_int32_t)(sizeof(elem) + strlen(elem.msg) + 1); } void SMSMsgCopy(void *dest, const SMSMsg2&elem) { memcpy(dest, &elem, sizeof(elem)); strcpy((char*)dest + sizeof(elem), elem.msg); } u_int32_t rgblen(const RGBB *seq) { size_t s = 0; const RGBB *p = seq, rgb0; for (s = 0, p = seq; memcmp(p, &rgb0, sizeof(rgb0)) != 0; p++, s++); // this size includes the all-0 last element used like '\0' // for char* strings return (u_int32_t)(s + 1); } // The seqs sequence of RGBB objects may not reside in a consecutive chunk of // memory but the seqd points to a consecutive chunk of mem large enough to // hold all objects from seqs. void rgbcpy(RGBB *seqd, const RGBB *seqs, size_t num) { const RGBB *p = seqs; RGBB rgb0; RGBB *q = seqd; memset((void *)&rgb0, 0, sizeof(rgb0)); for (p = seqs, q = seqd; memcmp(p, &rgb0, sizeof(rgb0)) != 0 && num > 0; num--, p++, q++) memcpy((void *)q, p, sizeof(RGBB)); memcpy((void *)q, p, sizeof(RGBB));// append trailing end token. }