JabberBotSession::JabberBotSession(const std::string &host, unsigned short port, bool isSecure, const std::string &userid, const std::string &password, const std::string &resource, const std::string &email, const std::string &affirmation_path, const std::string &db_path) : m_subscriptionDb(NULL, 0) { openlog("affirmations-bot", LOG_PID|LOG_CONS, LOG_DAEMON); Dbc *cursor; m_subscriptionDb.open(NULL, db_path.c_str(), NULL, DB_BTREE, DB_CREATE, 0); m_subscriptionDb.cursor(NULL, &cursor, 0); if (NULL != cursor) { Dbt key, data; time_t now = time(NULL); time_t bod = now - (now % 86400); m_eod = bod + 86400; while (0 == cursor->get(&key, &data, DB_NEXT)) { std::string user((char *)key.get_data()); time_t last = *((time_t*) data.get_data()); if (last < bod) { // He hasn't gotten an affirmation today time_t t1 = random() % ((m_eod - now)/2); time_t t2 = random() % ((m_eod - now)/2); Upcoming newEntry(user, now + t1 + t2); m_upcomingQueue.push(newEntry); } std::ostringstream message; message << "User " << user << " last got an affirmation at " << last; syslog(LOG_NOTICE, message.str().c_str()); } cursor->close(); } if (m_handlers.begin() == m_handlers.end()) { CommandHandler handler; handler.method = &JabberBotSession::Subscribe; m_handlers.insert(CommandHandlerMap::value_type("subscribe", handler)); handler.method = &JabberBotSession::Unsubscribe; m_handlers.insert(CommandHandlerMap::value_type("unsubscribe", handler)); handler.method = &JabberBotSession::Affirmation; m_handlers.insert(CommandHandlerMap::value_type("affirmation", handler)); handler.method = &JabberBotSession::Status; m_handlers.insert(CommandHandlerMap::value_type("status", handler)); } if (m_affirmations.empty()) { srand(time(NULL)); std::string line; std::ifstream a(affirmation_path.c_str()); while (getline(a, line)) { std::ostringstream message; message << "The line is \"" << line << "\"" << std::endl; syslog(LOG_DEBUG, message.str().c_str()); m_affirmations.push_back(line); } } m_session = new JabberSession(host, port, isSecure); // SYZYGY m_session->Register(this, HandlePresenceRequest); m_session->Register(this, HandleMessageRequest); m_session->Register(this, HandlePingRequest, "urn:xmpp:ping"); JabberIqAuth login_stanza(userid, password, resource); const Stanza *response = m_session->SendMessage(login_stanza, true); std::ostringstream message; message << "The first login response is " << *(response->render(NULL)) << std::endl; syslog(LOG_DEBUG, message.str().c_str()); if (200 != response->Error()) { message << "The first login response is " << response->ErrorMessage() << std::endl; syslog(LOG_NOTICE, message.str().c_str()); JabberIqRegister register_stanza(userid, password, email); response = m_session->SendMessage(register_stanza, true); message << "The register response is " << *(response->render(NULL)) << std::endl; syslog(LOG_NOTICE, message.str().c_str()); if (200 != response->Error()) { message << "The register response is " << response->ErrorMessage() << std::endl; syslog(LOG_NOTICE, message.str().c_str()); } else { JabberIqAuth login2_stanza(userid, password, resource); response = m_session->SendMessage(login2_stanza, true); message << "The second login response is " << *(response->render(NULL)) << std::endl; syslog(LOG_NOTICE, message.str().c_str()); if (200 != response->Error()) { message << "The second login failed with a message of " << response->ErrorMessage() << std::endl; syslog(LOG_NOTICE, message.str().c_str()); } } } delete response; m_id = 0; m_continueRunning = true; }
void TestKeyRange::run() { // Remove the previous database. (void)unlink(FileName); // Create the database object. // There is no environment for this simple example. Db db(0, 0); db.set_error_stream(&cerr); db.set_errpfx("TestKeyRange"); db.set_pagesize(1024); /* Page size: 1K. */ db.set_cachesize(0, 32 * 1024, 0); db.open(NULL, FileName, NULL, DB_BTREE, DB_CREATE, 0664); // // Insert records into the database, where the key is the user // input and the data is the user input in reverse order. // char buf[1024]; char rbuf[1024]; char *t; char *p; int ret; int len; Dbt *firstkey = NULL; char firstbuf[1024]; for (;;) { cout << "input>"; cout.flush(); cin.getline(buf, sizeof(buf)); if (cin.eof()) break; if ((len = strlen(buf)) <= 0) continue; for (t = rbuf, p = buf + (len - 1); p >= buf;) *t++ = *p--; *t++ = '\0'; Dbt key(buf, len + 1); Dbt data(rbuf, len + 1); if (firstkey == NULL) { strcpy(firstbuf, buf); firstkey = new Dbt(firstbuf, len + 1); } ret = db.put(0, &key, &data, DB_NOOVERWRITE); if (ret == DB_KEYEXIST) { cout << "Key " << buf << " already exists.\n"; } cout << "\n"; } // We put a try block around this section of code // to ensure that our database is properly closed // in the event of an error. // try { // Acquire a cursor for the table. Dbc *dbcp; db.cursor(NULL, &dbcp, 0); /*ADDED...*/ DB_KEY_RANGE range; memset(&range, 0, sizeof(range)); db.key_range(NULL, firstkey, &range, 0); printf("less: %f\n", range.less); printf("equal: %f\n", range.equal); printf("greater: %f\n", range.greater); /*end ADDED*/ Dbt key; Dbt data; // Walk through the table, printing the key/data pairs. while (dbcp->get(&key, &data, DB_NEXT) == 0) { char *key_string = (char *)key.get_data(); char *data_string = (char *)data.get_data(); cout << key_string << " : " << data_string << "\n"; } dbcp->close(); } catch (DbException &dbe) { cerr << "TestKeyRange: " << dbe.what() << "\n"; } db.close(0); }
bool Table::VisitBackward(TableVisitor &tv) { ByteString bsKey, bsValue; Dbc* cursor = NULL; bool ret = true; u_int32_t flags = DB_PREV; // TODO call tv.OnComplete() or error handling if (db->cursor(NULL, &cursor, 0) != 0) return false; Dbt key, value; if (tv.GetStartKey() && tv.GetStartKey()->length > 0) { key.set_data(tv.GetStartKey()->buffer); key.set_size(tv.GetStartKey()->length); flags = DB_SET_RANGE; // as DB_SET_RANGE finds the smallest key greater than or equal to the // specified key, in order to visit the database backwards, move to the // first matching elem, then move backwards if (cursor->get(&key, &value, flags) != 0) { // end of database cursor->close(); if (db->cursor(NULL, &cursor, 0) != 0) return false; } else { // if there is a match, call the acceptor, otherwise move to the // previous elem in the database if (memcmp(tv.GetStartKey()->buffer, key.get_data(), MIN(tv.GetStartKey()->length, key.get_size())) == 0) { bsKey.size = key.get_size(); bsKey.length = key.get_size(); bsKey.buffer = (char*) key.get_data(); bsValue.size = value.get_size(); bsValue.length = value.get_size(); bsValue.buffer = (char*) value.get_data(); ret = tv.Accept(bsKey, bsValue); } } } flags = DB_PREV; while (ret && cursor->get(&key, &value, flags) == 0) { bsKey.size = key.get_size(); bsKey.length = key.get_size(); bsKey.buffer = (char*) key.get_data(); bsValue.size = value.get_size(); bsValue.length = value.get_size(); bsValue.buffer = (char*) value.get_data(); ret = tv.Accept(bsKey, bsValue); if (!ret) break; flags = DB_PREV; } cursor->close(); tv.OnComplete(); return ret; }
bool CDB::Rewrite(const string& strFile, const char* pszSkip) { while (true) { { LOCK(bitdb.cs_db); if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { // Flush log data to the dat file bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); bitdb.mapFileUseCount.erase(strFile); bool fSuccess = true; printf("Rewriting %s...\n", strFile.c_str()); string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); Db* pdbCopy = new Db(&bitdb.dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type DB_CREATE, // Flags 0); if (ret > 0) { printf("Cannot create database file %s\n", strFileRes.c_str()); fSuccess = false; } Dbc* pcursor = db.GetCursor(); if (pcursor) while (fSuccess) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); if (ret == DB_NOTFOUND) { pcursor->close(); break; } else if (ret != 0) { pcursor->close(); fSuccess = false; break; } if (pszSkip && strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) continue; if (strncmp(&ssKey[0], "\x07version", 8) == 0) { // Update version: ssValue.clear(); ssValue << CLIENT_VERSION; } Dbt datKey(&ssKey[0], ssKey.size()); Dbt datValue(&ssValue[0], ssValue.size()); int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); if (ret2 > 0) fSuccess = false; } if (fSuccess) { db.Close(); bitdb.CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; delete pdbCopy; } } if (fSuccess) { Db dbA(&bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; Db dbB(&bitdb.dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } if (!fSuccess) printf("Rewriting of %s FAILED!\n", strFileRes.c_str()); return fSuccess; } } MilliSleep(100); } return false; }
static void transformDb(bool evictor, const Ice::CommunicatorPtr& communicator, const FreezeScript::ObjectFactoryPtr& objectFactory, DbEnv& dbEnv, DbEnv& dbEnvNew, const string& dbName, const Freeze::ConnectionPtr& connectionNew, vector<Db*>& dbs, const Slice::UnitPtr& oldUnit, const Slice::UnitPtr& newUnit, DbTxn* txnNew, bool purgeObjects, bool suppress, string descriptors) { if(evictor) { // // The evictor database file contains multiple databases. We must first // determine the names of those databases, ignoring any whose names // begin with "$index:". Each database represents a separate facet, with // the facet name used as the database name. The database named "$default" // represents the main object. // vector<string> dbNames; { Db db(&dbEnv, 0); db.open(0, dbName.c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); Dbt dbKey, dbValue; dbKey.set_flags(DB_DBT_MALLOC); dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Dbc* dbc = 0; db.cursor(0, &dbc, 0); while(dbc->get(&dbKey, &dbValue, DB_NEXT) == 0) { string s(static_cast<char*>(dbKey.get_data()), dbKey.get_size()); if(s.find("$index:") != 0) { dbNames.push_back(s); } free(dbKey.get_data()); } dbc->close(); db.close(0); } // // Transform each database. We must delay closing the new databases // until after the transaction is committed or aborted. // for(vector<string>::iterator p = dbNames.begin(); p != dbNames.end(); ++p) { string name = p->c_str(); Db db(&dbEnv, 0); db.open(0, dbName.c_str(), name.c_str(), DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE); Db* dbNew = new Db(&dbEnvNew, 0); dbs.push_back(dbNew); dbNew->open(txnNew, dbName.c_str(), name.c_str(), DB_BTREE, DB_CREATE | DB_EXCL, FREEZE_SCRIPT_DB_MODE); // // Execute the transformation descriptors. // istringstream istr(descriptors); string facet = (name == "$default" ? string("") : name); FreezeScript::transformDatabase(communicator, objectFactory, oldUnit, newUnit, &db, dbNew, txnNew, 0, dbName, facet, purgeObjects, cerr, suppress, istr); db.close(0); } Freeze::Catalog catalogNew(connectionNew, Freeze::catalogName()); Freeze::CatalogData catalogData = { true, "::Ice::Identity", "Object" }; catalogNew.put(Freeze::Catalog::value_type(dbName, catalogData)); } else { // // Transform a map database. // Db db(&dbEnv, 0); db.open(0, dbName.c_str(), 0, DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE); Db* dbNew = new Db(&dbEnvNew, 0); dbs.push_back(dbNew); dbNew->open(txnNew, dbName.c_str(), 0, DB_BTREE, DB_CREATE | DB_EXCL, FREEZE_SCRIPT_DB_MODE); // // Execute the transformation descriptors. // istringstream istr(descriptors); FreezeScript::transformDatabase(communicator, objectFactory, oldUnit, newUnit, &db, dbNew, txnNew, connectionNew, dbName, "", purgeObjects, cerr, suppress, istr); db.close(0); } }
void test1() { int numberOfKeysToWrite= 10000; Db db(0,DB_CXX_NO_EXCEPTIONS); db.set_pagesize(512); int err= db.open(0, "test1.db", 0, DB_BTREE, DB_CREATE, 0); { int i= 0; Dbt key(&i,sizeof(i)); Dbt data(&i,sizeof(i)); for(;i<numberOfKeysToWrite;++i) { db.put(0,&key,&data,0); } } { Dbc *dbc; err= db.cursor(0,&dbc,0); char *check= (char*)calloc(numberOfKeysToWrite,1); char buffer[8192]; int numberOfKeysRead= 0; Dbt multikey(&numberOfKeysRead,sizeof(numberOfKeysRead)); Dbt multidata(&buffer,sizeof(buffer)); multidata.set_flags(DB_DBT_USERMEM); multidata.set_ulen(sizeof(buffer)); err= 0; while(err==0) { err= dbc->get(&multikey,&multidata,DB_NEXT|DB_MULTIPLE_KEY); if(err==0) { Dbt key, data; DbMultipleKeyDataIterator i(multidata); while(err==0 && i.next(key,data)) { int actualKey; int actualData; memmove(&actualKey, key.get_data(), sizeof(actualKey)); memmove(&actualData, data.get_data(), sizeof(actualData)); if(actualKey!=actualData) { std::cout << "Error: key/data mismatch. " << actualKey << "!=" << actualData << std::endl; err= -1; } else { check[actualKey]++; } numberOfKeysRead++; } } else if(err!=DB_NOTFOUND) std::cout << "Error: dbc->get: " << db_strerror(err) << std::endl; } if(numberOfKeysRead!=numberOfKeysToWrite) { std::cout << "Error: key count mismatch. " << numberOfKeysRead << "!=" << numberOfKeysToWrite << std::endl; } for(int n=0;n<numberOfKeysToWrite;++n) { if(check[n]!=1) { std::cout << "Error: key " << n << " was written to the database, but not read back." << std::endl; } } free(check); dbc->close(); } db.close(0); }
void QueueScheduler::loadData(Db* _schedDb, bool createStartup) { Dbc *cursor = 0; Dbt key, data; uchar *keymem=new uchar[KEYMEM_SIZE]; uchar *datamem=new uchar[DATAMEM_SIZE]; key.set_flags(DB_DBT_USERMEM); key.set_data(keymem); key.set_ulen(KEYMEM_SIZE); data.set_flags(DB_DBT_USERMEM); data.set_ulen(DATAMEM_SIZE); data.set_data(datamem); int maxId = 0; int ret = 0; schedDb = _schedDb; schedDb->cursor(0, &cursor, DB_WRITECURSOR); QueueSchedule* queueSchedule = 0; while (ret == 0) { if ((ret = cursor->get(&key, &data, DB_NEXT)) == 0) { // qDebug() << "Just read schedule from Db, key = : " << key.get_data(); queueSchedule = new QueueSchedule(schedDb, (uchar*)data.get_data(), this); queueSchedules.append(queueSchedule); currentSchedule = queueSchedule; if (queueSchedule->getIsActive()) enabledSchedules.insert(queueSchedule->getPriority(), queueSchedule); } else if (ret == DB_BUFFER_SMALL) { ret = 0; qDebug("Insufficient memory"); qDebug("Size required is: %d", data.get_size()); uchar *p=datamem; datamem=new uchar[data.get_size()+1000]; data.set_ulen(data.get_size()+1000); data.set_data(datamem); Q_DELETE_ARRAY(p); } } cursor->close(); if (createStartup) { queueSchedule = new QueueSchedule(schedDb, tr("Un-metered"), this); queueSchedule->setIsActive(false); queueSchedule->setPriority(2); queueSchedule->addElement( 480 * 60, (1439 * 60) + 59, 128*1024, 0); queueSchedule->addElement(1920 * 60, (2879 * 60) + 59, 128*1024, 0); queueSchedule->addElement(3360 * 60, (4319 * 60) + 59, 128*1024, 0); queueSchedule->addElement(4800 * 60, (5759 * 60) + 59, 128*1024, 0); maxId = queueSchedule->addElement(6240 * 60, (7199 * 60) + 59, 128*1024, 0); queueSchedule->setMaxId(maxId); queueSchedules.append(queueSchedule); currentSchedule = queueSchedule; queueSchedule->dbSave(); } managePeriods(); Q_DELETE_ARRAY(keymem); Q_DELETE_ARRAY(datamem); }
void run_bdb_btree_big(stxxl::int64 n, unsigned ops) { const char * filename = BDB_FILE; my_key key1_storage; my_data data1_storage; #ifdef BDB_BULK_SCAN int * bulk_buffer = new int[logbufsize / sizeof(int)]; #endif unlink(filename); memset(key1_storage.keybuf, 'a', KEY_SIZE); memset(data1_storage.databuf, 'b', DATA_SIZE); Db db(NULL, 0); // Instantiate the Db object try { // here we start with the tests Dbt key1(key1_storage.keybuf, KEY_SIZE); Dbt data1(data1_storage.databuf, DATA_SIZE); stxxl::timer Timer; stxxl::int64 n_inserts = ops, n_locates = ops, n_range_queries = ops, n_deletes = ops; stxxl::int64 i; //comp_type cmp_; ran32State = 0xdeadbeef; Timer.start(); vector_type SortedSeq(n); //const vector_type & CSortedSeq(SortedSeq); { rand_key_gen Gen(n, key1_storage); typedef stxxl::stream::sort<rand_key_gen, comp_type> sorter_type; sorter_type Sorter(Gen, comp_type(), SORTER_MEM); typedef key2pair<sorter_type> key2pair_type; key2pair_type Key2Pair(Sorter); stxxl::stream::materialize(Key2Pair, SortedSeq.begin()); } Timer.stop(); STXXL_MSG("Finished sorting input. Elapsed time: " << (Timer.mseconds() / 1000.) << " seconds."); db.set_errfile(stderr); db.set_pagesize(pagesize); db.set_cachesize(0, cachesize, 10); STXXL_MSG("BDB cache size set."); // Open the database db.open(NULL, // Transaction pointer filename, // Database file name NULL, // Optional logical database name DB_BTREE, // Database access method DB_CREATE, // Open flags 0); // File mode (using defaults) db.get_env()->memp_stat(NULL, NULL, DB_STAT_CLEAR); Timer.reset(); Timer.start(); // DBD does not have bulk construction // however inserting in sorted order might help // to improve performance vector_type::const_iterator cit = SortedSeq.begin(); for (i = 0; i < n; ++i, ++cit) { key1_storage = cit->first; db.put(NULL, &key1, &data1, DB_NOOVERWRITE); } Timer.stop(); DB_BTREE_STAT * dbstat; db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); STXXL_MSG("Construction elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(n) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.stat_print(0); db.get_env()->memp_stat_print(DB_STAT_CLEAR); //////////////////////////////////////// Timer.reset(); Timer.start(); for (i = 0; i < n_inserts; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); db.put(NULL, &key1, &data1, DB_NOOVERWRITE); } Timer.stop(); db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(n_inserts) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.stat_print(0); db.get_env()->memp_stat_print(DB_STAT_CLEAR); ///////////////////////////////////////// Timer.reset(); Timer.start(); Dbc * cursorp; db.cursor(NULL, &cursorp, 0); for (i = 0; i < n_locates; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); Dbt keyx(key1_storage.keybuf, KEY_SIZE); Dbt datax(data1_storage.databuf, DATA_SIZE); cursorp->get(&keyx, &datax, DB_SET_RANGE); } Timer.stop(); STXXL_MSG("Locates elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.stat_print(0); db.get_env()->memp_stat_print(DB_STAT_CLEAR); //////////////////////////////////// Timer.reset(); Timer.start(); stxxl::int64 n_scanned = 0; for (i = 0; i < n_range_queries; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); my_key last_key = key1_storage; //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); if (last_key < key1_storage) std::swap(last_key, key1_storage); //STXXL_MSG("Looking "<<key1_storage<<" scanned: "<<n_scanned); //STXXL_MSG("Upper bound "<<last_key); Dbt keyx(key1_storage.keybuf, KEY_SIZE); #ifdef BDB_BULK_SCAN Dbt datax(bulk_buffer, DATA_SIZE); datax.set_ulen(logbufsize); datax.set_flags(DB_DBT_USERMEM); #else Dbt datax(data1_storage.databuf, DATA_SIZE); #endif #ifdef BDB_BULK_SCAN if (cursorp->get(&keyx, &datax, DB_SET_RANGE | DB_MULTIPLE_KEY) == DB_NOTFOUND) continue; do { DbMultipleKeyDataIterator BulkIterator(datax); Dbt key1, data1; while (BulkIterator.next(key1, data1) && *((my_key *)key1.get_data()) <= last_key) { ++n_scanned; //STXXL_MSG("Result "<<*((my_key *)key1.get_data())); } if (cursorp->get(&keyx, &datax, DB_NEXT | DB_MULTIPLE_KEY) == DB_NOTFOUND) break; if (*((my_key *)keyx.get_data()) > last_key) { break; } } while (1); #else if (cursorp->get(&keyx, &datax, DB_SET_RANGE) == DB_NOTFOUND) continue; while (*((my_key *)keyx.get_data()) <= last_key) { ++n_scanned; if (cursorp->get(&keyx, &datax, DB_NEXT) == DB_NOTFOUND) break; } #endif if (n_scanned >= SCAN_LIMIT(n)) { ++i; break; } } n_range_queries = i; Timer.stop(); if (cursorp != NULL) cursorp->close(); STXXL_MSG("Range query elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(n_scanned) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec, #queries " << n_range_queries << " #scanned elements: " << n_scanned); db.stat_print(0); db.get_env()->memp_stat_print(DB_STAT_CLEAR); ////////////////////////////////////// ran32State = 0xdeadbeef; memset(key1_storage.keybuf, 'a', KEY_SIZE); Timer.reset(); Timer.start(); for (i = 0; i < n_deletes; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); Dbt keyx(key1_storage.keybuf, KEY_SIZE); db.del(NULL, &keyx, 0); } Timer.stop(); db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); STXXL_MSG("Erase elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.stat_print(0); db.get_env()->memp_stat_print(DB_STAT_CLEAR); db.close(0); } catch (DbException & e) { STXXL_ERRMSG("DbException happened"); } catch (std::exception & e) { STXXL_ERRMSG("std::exception happened"); } unlink(filename); #ifdef BDB_BULK_SCAN delete[] bulk_buffer; #endif }
// Check that key/data for 0 - count-1 are already present, // and write a key/data for count. The key and data are // both "0123...N" where N == count-1. // // For some reason on Windows, we need to open using the full pathname // of the file when there is no environment, thus the 'has_env' // variable. // void rundb(Db *db, int count, int has_env) { const char *name; if (has_env) name = CONSTRUCT01_DBNAME; else name = CONSTRUCT01_DBFULLPATH; db->set_error_stream(&cerr); // We don't really care about the pagesize, but we do want // to make sure adjusting Db specific variables works before // opening the db. // CHK(db->set_pagesize(1024)); CHK(db->open(NULL, name, NULL, DB_BTREE, count ? 0 : DB_CREATE, 0664)); // The bit map of keys we've seen long bitmap = 0; // The bit map of keys we expect to see long expected = (1 << (count+1)) - 1; char outbuf[10]; int i; for (i=0; i<count; i++) { outbuf[i] = '0' + i; } outbuf[i++] = '\0'; Dbt key(outbuf, i); Dbt data(outbuf, i); DEBUGOUT("Put: " << outbuf); CHK(db->put(0, &key, &data, DB_NOOVERWRITE)); // Acquire a cursor for the table. Dbc *dbcp; CHK(db->cursor(NULL, &dbcp, 0)); // Walk through the table, checking Dbt readkey; Dbt readdata; while (dbcp->get(&readkey, &readdata, DB_NEXT) == 0) { char *key_string = (char *)readkey.get_data(); char *data_string = (char *)readdata.get_data(); DEBUGOUT("Got: " << key_string << ": " << data_string); int len = strlen(key_string); long bit = (1 << len); if (len > count) { ERR("reread length is bad"); } else if (strcmp(data_string, key_string) != 0) { ERR("key/data don't match"); } else if ((bitmap & bit) != 0) { ERR("key already seen"); } else if ((expected & bit) == 0) { ERR("key was not expected"); } else { bitmap |= bit; expected &= ~(bit); for (i=0; i<len; i++) { if (key_string[i] != ('0' + i)) { cout << " got " << key_string << " (" << (int)key_string[i] << ")" << ", wanted " << i << " (" << (int)('0' + i) << ")" << " at position " << i << "\n"; ERR("key is corrupt"); } } } } if (expected != 0) { cout << " expected more keys, bitmap is: " << expected << "\n"; ERR("missing keys in database"); } CHK(dbcp->close()); CHK(db->close(0)); }
// Modify or create a part based on the following information MultiPartHeader::Add_Code MultiPartHeader::modifyPart(Db* pdb, quint16 partNo, RawHeader *rh, quint16 hostId) { //qDebug() << "Entering modifyPart"; Add_Code retCode = New_Part; int ret = 0; bool createPart = false; Header* h = 0; char *phead = 0; Dbc *cursorp = 0; Dbt key; Dbt data; //qDebug() << "Creating part for key " << multiPartKey; key.set_data(&multiPartKey); key.set_size(sizeof(quint64)); data.set_data(&partNo); data.set_size(sizeof(quint16)); // Get a cursor pdb->cursor(NULL, &cursorp, DB_WRITECURSOR); //qDebug("1"); // Position the cursor to the first record in the database whose // key matches the search key and whose data begins with the search // data. ret = cursorp->get(&key, &data, DB_GET_BOTH); if (ret == 0) { //qDebug("2"); // update the data h = new Header((char*)data.get_data(), (char*)key.get_data()); //qDebug("3"); if (h->isHeldByServer(hostId)) { retCode = Duplicate_Part; } else retCode = Updated_Part; // qDebug() << "Found an update for part " << partNo << ", existing part " << h->getPartNo() << ", existing msgid " << h->getMessageId() << ", new msgid " << rh->m_mid; // Always update the article number h->setServerPartNum(hostId, rh->m_num); //qDebug("4"); phead=h->data(); data.set_data(phead); data.set_size(h->getRecordSize()); //qDebug("5"); cursorp->put(&key, &data, DB_CURRENT); //qDebug("6"); Q_DELETE_ARRAY(phead); } else if (ret == DB_NOTFOUND) // create the part { //qDebug("7"); createPart = true; } else // encountered an error { qDebug() << "Unable to find part " << partNo << " for key " << multiPartKey << ", result = " << ret; retCode = Error_Part; } // Close the cursor if (cursorp != NULL) cursorp->close(); if (createPart == true) { //qDebug("8"); quint32 partSize = rh->m_bytes.toULong(); h = new Header(multiPartKey, partNo, partSize); //qDebug("9"); h->setMessageId(rh->m_mid); h->setServerPartNum(hostId, rh->m_num); //save in the parts db phead=h->data(); data.set_data(phead); data.set_size(h->getRecordSize()); //qDebug("10"); ret = pdb->put(0, &key, &data, 0); if (ret) { qDebug() << "Unable to create part " << partNo << " for key " << multiPartKey << ", result = " << ret; retCode = Error_Part; } else retCode = New_Part; //qDebug("11"); Q_DELETE_ARRAY(phead); } Q_DELETE(h); //qDebug("12\n"); //qDebug() << "Exiting modifyPart"; return retCode; }
void BtRecExample::run() { db_recno_t recno; int ret; char buf[1024]; // Acquire a cursor for the database. dbp->cursor(NULL, &dbcp, 0); // // Prompt the user for a record number, then retrieve and display // that record. // for (;;) { // Get a record number. cout << "recno #> "; cout.flush(); if (fgets(buf, sizeof(buf), stdin) == NULL) break; recno = atoi(buf); // // Start with a fresh key each time, // the dbp->get() routine returns // the key and data pair, not just the key! // Dbt key(&recno, sizeof(recno)); Dbt data; if ((ret = dbcp->get(&key, &data, DB_SET_RECNO)) != 0) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } // Display the key and data. show("k/d\t", &key, &data); // Move the cursor a record forward. if ((ret = dbcp->get(&key, &data, DB_NEXT)) != 0) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } // Display the key and data. show("next\t", &key, &data); // // Retrieve the record number for the following record into // local memory. // data.set_data(&recno); data.set_size(sizeof(recno)); data.set_ulen(sizeof(recno)); data.set_flags(data.get_flags() | DB_DBT_USERMEM); if ((ret = dbcp->get(&key, &data, DB_GET_RECNO)) != 0) { if (ret != DB_NOTFOUND && ret != DB_KEYEMPTY) { dbp->err(ret, "DBcursor->get"); throw DbException(ret); } } else { cout << "retrieved recno: " << (u_long)recno << "\n"; } } dbcp->close(); dbcp = NULL; }
vector<Identity>::const_iterator Freeze::EvictorIteratorI::nextBatch() { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); _batch.clear(); if(!_more) { return _batch.end(); } vector<EvictorElementPtr> evictorElements; evictorElements.reserve(_batchSize); Key firstKey = _key; CommunicatorPtr communicator = _store->communicator(); try { for(;;) { _batch.clear(); evictorElements.clear(); Dbt dbKey; initializeOutDbt(_key, dbKey); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Dbc* dbc = 0; try { // // Move to the first record // u_int32_t flags = DB_NEXT; if(_initialized) { // // _key represents the next element not yet returned // if it has been deleted, we want the one after // flags = DB_SET_RANGE; // // Will be used as input as well // dbKey.set_size(static_cast<u_int32_t>(firstKey.size())); } _store->db()->cursor(0, &dbc, 0); bool done = false; do { for(;;) { try { // // It is critical to set key size to key capacity before the // get, as a resize that increases the size inserts 0 // _key.resize(_key.capacity()); _more = (dbc->get(&dbKey, &dbValue, flags) == 0); if(_more) { _key.resize(dbKey.get_size()); _initialized = true; flags = DB_NEXT; Ice::Identity ident; ObjectStore::unmarshal(ident, _key, communicator); if(_batch.size() < _batchSize) { _batch.push_back(ident); } else { // // Keep the last element in _key // done = true; } } break; } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { handleDbException(dx, _key, dbKey, __FILE__, __LINE__); } } } while(!done && _more); Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { // // Ignored // } } _key = firstKey; // // Retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { // // Ignored // } } throw; } } } catch(const DbException& dx) { handleDbException(dx, __FILE__, __LINE__); } if(_batch.size() == 0) { return _batch.end(); } else { return _batch.begin(); } }
ScanResponse BDBBackend::scan (const string & bucket, const string & seed, int32_t count) { ScanResponse scan_response; Dbc * dbc; try { Dbt db_key; char key[BDB_BACKEND_MAX_KEY_SIZE + 1]; db_key.set_data (key); db_key.set_ulen (BDB_BACKEND_MAX_KEY_SIZE + 1); db_key.set_flags (DB_DBT_USERMEM); Dbt db_value; char value[BDB_BACKEND_MAX_VALUE_SIZE + 1]; db_value.set_data (value); db_value.set_ulen (BDB_BACKEND_MAX_VALUE_SIZE + 1); db_value.set_flags (DB_DBT_USERMEM); get_db (bucket)->cursor (NULL, &dbc, 0); // this get positions us at the last key we grabbed or the one // imediately following it // copy over the seed and it's size strncpy (key, seed.c_str (), seed.length () + 1); db_key.set_size (seed.length () + 1); if (dbc->get (&db_key, &db_value, DB_SET_RANGE) == 0) { string key_tmp ((const char *)db_key.get_data (), db_key.get_size ()); if (seed != key_tmp) { // we got the one after it, it must be gone now, so return // this one Element e; e.key = key_tmp; e.value = string ((const char *)db_value.get_data (), db_value.get_size ()); scan_response.elements.push_back (e); } // we'll skip it, it's the one we had last time // now keep going until we run out of items or get our fill while ((dbc->get (&db_key, &db_value, DB_NEXT) == 0) && (scan_response.elements.size () < (unsigned int)count)) { Element e; e.key = string ((const char *)db_key.get_data (), db_key.get_size ()); e.value = string ((const char *)db_value.get_data (), db_value.get_size ()); scan_response.elements.push_back (e); } } } catch (DbDeadlockException & e) { T_INFO ("scan: exception=%s", e.what ()); dbc->close (); throw e; } catch (DbException & e) { T_ERROR ("scan: exception=%s", e.what ()); dbc->close (); throw e; } dbc->close (); scan_response.seed = scan_response.elements.size () > 0 ? scan_response.elements.back ().key : ""; return scan_response; }
/* * Look at all the records and parse keys for addresses and private keys */ bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass) { DBErrors result = DB_LOAD_OK; std::string strType; bool first = true; try { Dbc* pcursor = GetCursor(); if (!pcursor) { LogPrintf("Error getting wallet database cursor\n"); result = DB_CORRUPT; } if (dumppriv) { while (result == DB_LOAD_OK && true) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int result = ReadAtCursor(pcursor, ssKey, ssValue); if (result == DB_NOTFOUND) { break; } else if (result != 0) { LogPrintf("Error reading next record from wallet database\n"); result = DB_CORRUPT; break; } ssKey >> strType; if (strType == "mkey") { updateMasterKeys(ssKey, ssValue); } } pcursor->close(); pcursor = GetCursor(); } while (result == DB_LOAD_OK && true) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = ReadAtCursor(pcursor, ssKey, ssValue); if (ret == DB_NOTFOUND) { std::cout << " ]" << std::endl; first = true; break; } else if (ret != DB_LOAD_OK) { LogPrintf("Error reading next record from wallet database\n"); result = DB_CORRUPT; break; } ssKey >> strType; if (strType == "key" || strType == "ckey") { std::string strAddr = getAddress(ssKey); std::string strKey = ""; if (dumppriv && strType == "key") strKey = getKey(ssKey, ssValue); if (dumppriv && strType == "ckey") { if (masterPass == "") { std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl; show_help(); result = DB_LOAD_FAIL; break; } strKey = getCryptedKey(ssKey, ssValue, masterPass); } if (strAddr != "") { if (first) std::cout << "[ "; else std::cout << ", "; } if (dumppriv) { std::cout << "{\"addr\" : \"" + strAddr + "\", " << "\"pkey\" : \"" + strKey + "\"}" << std::flush; } else { std::cout << "\"" + strAddr + "\""; } first = false; } } pcursor->close(); } catch (DbException &e) { std::cout << "DBException caught " << e.get_errno() << std::endl; } catch (std::exception &e) { std::cout << "Exception caught " << std::endl; } if (result == DB_LOAD_OK) return true; else return false; }
/*static*/ void Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection, const string& dbName, const string& key, const string& value, const Freeze::KeyCompareBasePtr& keyCompare, const std::vector<MapIndexBasePtr>& indices) { Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection.get()); if(connectionI == 0) { throw DatabaseException(__FILE__, __LINE__, "Invalid connection"); } if(dbName == catalogName() || dbName == catalogIndexListName()) { throw DatabaseException(__FILE__, __LINE__, "You cannot destroy recreate the \"" + dbName + "\" database"); } if(connectionI->trace() >= 1) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); out << "Recreating \"" << dbName << "\""; } TransactionPtr tx = connectionI->currentTransaction(); bool ownTx = (tx == 0); Dbt keyDbt; keyDbt.set_flags(DB_DBT_REALLOC); Dbt valueDbt; valueDbt.set_flags(DB_DBT_REALLOC); try { for(;;) { try { if(ownTx) { tx = 0; tx = connectionI->beginTransaction(); } DbTxn* txn = connectionI->dbTxn(); if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); out << "Removing all existing indices for \"" << dbName << "\""; } CatalogIndexList catalogIndexList(connection, catalogIndexListName()); CatalogIndexList::iterator p = catalogIndexList.find(dbName); if(p != catalogIndexList.end()) { const StringSeq& idxs = p->second; for(size_t i = 0; i < idxs.size(); ++i) { try { connection->removeMapIndex(dbName, idxs[i]); } catch(const IndexNotFoundException&) { // // Ignored // } } catalogIndexList.erase(p); } // // Rename existing database // string oldDbName = dbName + ".old-" + generateUUID(); if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); out << "Renaming \"" << dbName << "\" to \"" << oldDbName << "\""; } connectionI->dbEnv()->getEnv()->dbrename(txn, dbName.c_str(), 0, oldDbName.c_str(), 0); // // Fortunately, DB closes oldDb automatically when it goes out of scope // Db oldDb(connectionI->dbEnv()->getEnv(), 0); // // Berkeley DB expects file paths to be UTF8 encoded. // oldDb.open(txn, nativeToUTF8(oldDbName, getProcessStringConverter()).c_str(), 0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE); IceInternal::UniquePtr<MapDb> newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true)); if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); out << "Writing contents of \"" << oldDbName << "\" to fresh \"" << dbName << "\""; } // // Now simply write all of oldDb into newDb // Dbc* dbc = 0; oldDb.cursor(txn, &dbc, 0); try { while(dbc->get(&keyDbt, &valueDbt, DB_NEXT) == 0) { newDb->put(txn, &keyDbt, &valueDbt, 0); } } catch(...) { dbc->close(); throw; } dbc->close(); if(connectionI->trace() >= 2) { Trace out(connectionI->communicator()->getLogger(), "Freeze.Map"); out << "Transfer complete; removing \"" << oldDbName << "\""; } connectionI->dbEnv()->getEnv()->dbremove(txn, oldDbName.c_str(), 0, 0); if(ownTx) { tx->commit(); } break; // for (;;) } catch(const DbDeadlockException& dx) { if(ownTx) { if(connectionI->deadlockWarning()) { Warning out(connectionI->communicator()->getLogger()); out << "Deadlock in Freeze::MapHelperI::recreate on Db \"" << dbName << "\"; retrying ..."; } // // Ignored, try again // } else { throw DeadlockException(__FILE__, __LINE__, dx.what(), tx); } } catch(const DbException& dx) { if(ownTx) { try { tx->rollback(); } catch(...) { } } throw DatabaseException(__FILE__, __LINE__, dx.what()); } catch(...) { if(ownTx && tx != 0) { try { tx->rollback(); } catch(...) { } } throw; } } free(keyDbt.get_data()); free(valueDbt.get_data()); } catch(...) { free(keyDbt.get_data()); free(valueDbt.get_data()); throw; } }
void run_bdb_btree(stxxl::int64 ops) { const char * filename = BDB_FILE; my_key key1_storage; my_data data1_storage; unlink(filename); memset(key1_storage.keybuf, 'a', KEY_SIZE); memset(data1_storage.databuf, 'b', DATA_SIZE); Db db(NULL, 0); // Instantiate the Db object try { db.set_errfile(stderr); db.set_pagesize(pagesize); db.set_cachesize(0, cachesize, 1); // Open the database db.open(NULL, // Transaction pointer filename, // Database file name NULL, // Optional logical database name DB_BTREE, // Database access method DB_CREATE, // Open flags 0); // File mode (using defaults) // here we start with the tests Dbt key1(key1_storage.keybuf, KEY_SIZE); Dbt data1(data1_storage.databuf, DATA_SIZE); stxxl::timer Timer; stxxl::int64 n_inserts = ops, n_locates = ops, n_range_queries = ops, n_deletes = ops; stxxl::int64 i; //comp_type cmp_; ran32State = 0xdeadbeef; DB_BTREE_STAT * dbstat; db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); db.get_env()->memp_stat(NULL, NULL, DB_STAT_CLEAR); Timer.start(); for (i = 0; i < n_inserts; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); db.put(NULL, &key1, &data1, DB_NOOVERWRITE); } Timer.stop(); db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(n_inserts) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.get_env()->memp_stat_print(DB_STAT_CLEAR); ///////////////////////////////////////// Timer.reset(); Timer.start(); Dbc * cursorp; db.cursor(NULL, &cursorp, 0); for (i = 0; i < n_locates; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); Dbt keyx(key1_storage.keybuf, KEY_SIZE); Dbt datax(data1_storage.databuf, DATA_SIZE); cursorp->get(&keyx, &datax, DB_SET_RANGE); } Timer.stop(); STXXL_MSG("Locates elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.get_env()->memp_stat_print(DB_STAT_CLEAR); //////////////////////////////////// Timer.reset(); Timer.start(); stxxl::int64 n_scanned = 0; for (i = 0; i < n_range_queries; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); my_key last_key = key1_storage; //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); if (last_key < key1_storage) std::swap(last_key, key1_storage); Dbt keyx(key1_storage.keybuf, KEY_SIZE); Dbt datax(data1_storage.databuf, DATA_SIZE); if (cursorp->get(&keyx, &datax, DB_SET_RANGE) == DB_NOTFOUND) continue; while (*((my_key *)keyx.get_data()) <= last_key) { ++n_scanned; if (cursorp->get(&keyx, &datax, DB_NEXT) == DB_NOTFOUND) break; } if (n_scanned >= 10 * n_range_queries) { ++i; break; } } n_range_queries = i; Timer.stop(); if (cursorp != NULL) cursorp->close(); STXXL_MSG("Range query elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(n_scanned) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec, #queries " << n_range_queries << " #scanned elements: " << n_scanned); db.get_env()->memp_stat_print(DB_STAT_CLEAR); ////////////////////////////////////// ran32State = 0xdeadbeef; memset(key1_storage.keybuf, 'a', KEY_SIZE); Timer.reset(); Timer.start(); for (i = 0; i < n_deletes; ++i) { //key1_storage.keybuf[KEYPOS] = letters[VALUE]; rand_key(i, key1_storage); Dbt keyx(key1_storage.keybuf, KEY_SIZE); db.del(NULL, &keyx, 0); } Timer.stop(); db.stat(NULL, &dbstat, 0); STXXL_MSG("Records in map: " << dbstat->bt_ndata); STXXL_MSG("Erase elapsed time: " << (Timer.mseconds() / 1000.) << " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec"); db.get_env()->memp_stat_print(DB_STAT_CLEAR); db.close(0); } catch (DbException & e) { STXXL_ERRMSG("DbException happened"); } catch (std::exception & e) { STXXL_ERRMSG("std::exception happened"); } unlink(filename); }
void Freeze::MapHelperI::clear() { DbTxn* txn = _connection->dbTxn(); if(txn == 0) { closeAllIterators(); } Dbt dbKey; dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); try { for(;;) { Dbc* dbc = 0; try { IteratorHelperI::TxPtr tx; if(txn == 0) { #ifdef ICE_CPP11_COMPILER tx.reset(new IteratorHelperI::Tx(*this)); #else tx = new IteratorHelperI::Tx(*this); #endif txn = tx->getTxn(); } _db->cursor(txn, &dbc, 0); while(dbc->get(&dbKey, &dbValue, DB_NEXT | DB_RMW) == 0) { dbc->del(0); } Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } if(_connection->deadlockWarning()) { Warning out(_connection->communicator()->getLogger()); out << "Deadlock in Freeze::MapHelperI::clear on Map \"" << _dbName << "\"; retrying ..."; } if(txn != 0) { throw; } // // Otherwise retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), _connection->currentTransaction()); } catch(const DbException& dx) { throw DatabaseException(__FILE__, __LINE__, dx.what()); } }
/* Loop get batches of records. */ void BulkExample::bulkRead( int num, int dups, int iter, int *countp, int verbose) { Dbc *dbcp; Dbt data, dp, key, kp; DbTxn *txnp; DbMultipleDataIterator *ptrd; DbMultipleKeyDataIterator *ptrkd; u_int32_t flags; int count, i, j, ret; count = klen = ret = 0; dbcp = NULL; txnp = NULL; /* Initialize key Dbt and data Dbt, malloc bulk buffer. */ memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.set_size(sizeof(j)); if (dlen != DATALEN * 16 * 1024) { dlen = DATALEN * 16 * 1024; dbuf = realloc(dbuf, dlen); } memset(dbuf, 0, dlen); data.set_flags(DB_DBT_USERMEM); data.set_data(dbuf); data.set_ulen(dlen); data.set_size(dlen); flags = DB_SET; flags |= (dups) ? DB_MULTIPLE: DB_MULTIPLE_KEY; try { for (i = 0; i < iter; i++) { if ((ret = dbenv->txn_begin(NULL, &txnp, 0)) != 0) throwException(dbenv, NULL, ret, "DB_ENV->txn_begin"); if ((ret = dbp->cursor(txnp, &dbcp, 0)) != 0) throwException(dbenv, txnp, ret, "DB->cursor"); /* * Bulk retrieve by a random key which is a random * non-negative integer smaller than "num". * If there are duplicates in the database, retrieve * with DB_MULTIPLE and use the DbMultipleDataIterator * to iterate the data of the random key in the data * Dbt. Otherwise retrieve with DB_MULTIPLE_KEY and use * the DbMultipleKeyDataIterator to iterate the * key/data pairs of the specific set of keys which * includes all integers >= the random key and < "num". */ j = rand() % num; key.set_data(&j); if ((ret = dbcp->get(&key, &data, flags)) != 0) throwException(dbenv, NULL, ret, "DBC->get"); if (dups) { ptrd = new DbMultipleDataIterator(data); while (ptrd->next(dp) == true) { count++; if (verbose) printf( "Retrieve key: %d, \tdata: (id %d, str %s)\n", j, ((struct data *)( dp.get_data()))->id, (char *)((struct data *)( dp.get_data()))->str); } } else { ptrkd = new DbMultipleKeyDataIterator(data); while (ptrkd->next(kp, dp) == true) { count++; if (verbose) printf( "Retrieve key: %d, \tdata: (id %d, str %s)\n", *((int *)kp.get_data()), ((struct data *)( dp.get_data()))->id, (char *)((struct data *)( dp.get_data()))->str); } } ret = dbcp->close(); dbcp = NULL; if (ret != 0) throwException(dbenv, txnp, ret, "DBC->close"); ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); } *countp = count; } catch (DbException &dbe) { cerr << "bulkRead " << dbe.what() << endl; if (dbcp != NULL) (void)dbcp->close(); if (txnp != NULL) (void)txnp->abort(); throw dbe; } }
int Freeze::MapIndexI::untypedCount(const Key& k, const ConnectionIPtr& connection) const { Dbt dbKey; initializeInDbt(k, dbKey); #if (DB_VERSION_MAJOR <= 4) // // When we have a custom-comparison function, Berkeley DB returns // the key on-disk (when it finds one). We disable this behavior: // (ref Oracle SR 5925672.992) // dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); #else // // In DB 5.x we can not set DB_DBT_PARTIAL in the key Dbt, // when using DB_SET, we must resize the Dbt key param to hold enought // space or Dbc::get fails with DB_BUFFER_SMALL. // dbKey.set_flags(DB_DBT_USERMEM); dbKey.set_ulen(static_cast<u_int32_t>(k.size())); #endif Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int result = 0; DbTxn* txn = connection->dbTxn(); try { for(;;) { Dbc* dbc = 0; try { // // Move to the first record // _db->cursor(txn, &dbc, 0); bool found = (dbc->get(&dbKey, &dbValue, DB_SET) == 0); if(found) { db_recno_t count = 0; dbc->count(&count, 0); result = static_cast<int>(count); } Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } if(connection->deadlockWarning()) { Warning out(connection->communicator()->getLogger()); out << "Deadlock in Freeze::MapIndexI::untypedCount while searching \"" << _dbName << "\""; } if(txn != 0) { throw; } // // Otherwise retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(txn != 0) { throw; } else { // // Ignored // } } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), connection->currentTransaction()); } catch(const DbException& dx) { throw DatabaseException(__FILE__, __LINE__, dx.what()); } return result; }
void AccessExample::run(bool removeExistingDatabase, const char *fileName) { // Remove the previous database. if (removeExistingDatabase) (void)remove(fileName); // Create the database object. // There is no environment for this simple example. Db db(0, 0); db.set_error_stream(&cerr); db.set_errpfx("AccessExample"); db.set_pagesize(1024); /* Page size: 1K. */ db.set_cachesize(0, 32 * 1024, 0); db.open(NULL, fileName, NULL, DB_BTREE, DB_CREATE, 0664); // // Insert records into the database, where the key is the user // input and the data is the user input in reverse order. // char buf[1024], rbuf[1024]; char *p, *t; int ret; u_int32_t len; for (;;) { cout << "input> "; cout.flush(); cin.getline(buf, sizeof(buf)); if (cin.eof()) break; if ((len = (u_int32_t)strlen(buf)) <= 0) continue; for (t = rbuf, p = buf + (len - 1); p >= buf;) *t++ = *p--; *t++ = '\0'; Dbt key(buf, len + 1); Dbt data(rbuf, len + 1); ret = db.put(0, &key, &data, DB_NOOVERWRITE); if (ret == DB_KEYEXIST) { cout << "Key " << buf << " already exists.\n"; } } cout << "\n"; // We put a try block around this section of code // to ensure that our database is properly closed // in the event of an error. // try { // Acquire a cursor for the table. Dbc *dbcp; db.cursor(NULL, &dbcp, 0); // Walk through the table, printing the key/data pairs. Dbt key; Dbt data; while (dbcp->get(&key, &data, DB_NEXT) == 0) { char *key_string = (char *)key.get_data(); char *data_string = (char *)data.get_data(); cout << key_string << " : " << data_string << "\n"; } dbcp->close(); } catch (DbException &dbe) { cerr << "AccessExample: " << dbe.what() << "\n"; } db.close(0); }
int main() { u_int32_t env_flags = DB_CREATE | // If the environment does not exist, create it. DB_INIT_MPOOL; // Initialize the in-memory cache. //std::string envHome("./"); std::string envHome("/home/kirill"); u_int32_t db_flags = DB_RDONLY; // only read std::string dbName("X-po2s.db"); //std::string dbName("X-so2p.db"); //std::string dbName("X-sp2o.db"); DbEnv myEnv(0); Db *myDb; // Instantiate the Db object Dbc *cursorp; // cursor try { cout << "X-po2s.db output:" << endl; myEnv.open(envHome.c_str(), env_flags, 0); myDb = new Db(&myEnv, 0); myDb->open(NULL, dbName.c_str(), NULL, DB_BTREE, db_flags, 0); // Get a cursor myDb->cursor(NULL, &cursorp, 0); Dbt key, data; // Position the cursor to the first record in the database whose // key and data begin with the correct strings. int ret = cursorp->get(&key, &data, DB_NEXT); while (ret != DB_NOTFOUND) { cout << "..." << endl; std::cout << "key: " << (char *)key.get_data() << "data: " << (char *)data.get_data()<< std::endl; ret = cursorp->get(&key, &data, DB_NEXT); } // Cursors must be closed if (cursorp != NULL) cursorp->close(); if (myDb != NULL) { myDb->close(0); } myEnv.close(0); cout << "Closing ..." << endl; } // Must catch both DbException and std::exception catch(DbException &e) { myDb->err(e.get_errno(), "Database open failed %s", dbName.c_str()); throw e; } catch(std::exception &e) { // No DB error number available, so use errx myDb->errx("Error opening database: %s", e.what()); throw e; } return 0; }
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) { if (database.IsDummy()) { return true; } BerkeleyEnvironment *env = database.env; const std::string& strFile = database.strFile; while (true) { { LOCK(cs_db); if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) { // Flush log data to the dat file env->CloseDb(strFile); env->CheckpointLSN(strFile); env->mapFileUseCount.erase(strFile); bool fSuccess = true; LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); std::string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} BerkeleyBatch db(database, "r"); std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0); int ret = pdbCopy->open(nullptr, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type DB_CREATE, // Flags 0); if (ret > 0) { LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes); fSuccess = false; } Dbc* pcursor = db.GetCursor(); if (pcursor) while (fSuccess) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue); if (ret1 == DB_NOTFOUND) { pcursor->close(); break; } else if (ret1 != 0) { pcursor->close(); fSuccess = false; break; } if (pszSkip && strncmp(ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) continue; if (strncmp(ssKey.data(), "\x07version", 8) == 0) { // Update version: ssValue.clear(); ssValue << CLIENT_VERSION; } Dbt datKey(ssKey.data(), ssKey.size()); Dbt datValue(ssValue.data(), ssValue.size()); int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, DB_NOOVERWRITE); if (ret2 > 0) fSuccess = false; } if (fSuccess) { db.Close(); env->CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; } else { pdbCopy->close(0); } } if (fSuccess) { Db dbA(env->dbenv.get(), 0); if (dbA.remove(strFile.c_str(), nullptr, 0)) fSuccess = false; Db dbB(env->dbenv.get(), 0); if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0)) fSuccess = false; } if (!fSuccess) LogPrintf("BerkeleyBatch::Rewrite: Failed to rewrite database file %s\n", strFileRes); return fSuccess; } } MilliSleep(100); } }
// // XXX Figure out the appropriate way to pick out IDs. // int TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb, int accounts, int branches, int tellers) { Dbc *acurs = NULL; Dbc *bcurs = NULL; Dbc *tcurs = NULL; DbTxn *t = NULL; db_recno_t key; Defrec rec; Histrec hrec; int account, branch, teller; Dbt d_dbt; Dbt d_histdbt; Dbt k_dbt; Dbt k_histdbt(&key, sizeof(key)); // // XXX We could move a lot of this into the driver to make this // faster. // account = random_id(ACCOUNT, accounts, branches, tellers); branch = random_id(BRANCH, accounts, branches, tellers); teller = random_id(TELLER, accounts, branches, tellers); k_dbt.set_size(sizeof(int)); d_dbt.set_flags(DB_DBT_USERMEM); d_dbt.set_data(&rec); d_dbt.set_ulen(sizeof(rec)); hrec.aid = account; hrec.bid = branch; hrec.tid = teller; hrec.amount = 10; // Request 0 bytes since we're just positioning. d_histdbt.set_flags(DB_DBT_PARTIAL); // START TIMING if (txn_begin(NULL, &t, 0) != 0) goto err; if (adb->cursor(t, &acurs, 0) != 0 || bdb->cursor(t, &bcurs, 0) != 0 || tdb->cursor(t, &tcurs, 0) != 0) goto err; // Account record k_dbt.set_data(&account); if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Branch record k_dbt.set_data(&branch); if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Teller record k_dbt.set_data(&teller); if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // History record d_histdbt.set_flags(0); d_histdbt.set_data(&hrec); d_histdbt.set_ulen(sizeof(hrec)); if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0) goto err; if (acurs->close() != 0 || bcurs->close() != 0 || tcurs->close() != 0) goto err; if (t->commit(0) != 0) goto err; // END TIMING return (0); err: if (acurs != NULL) (void)acurs->close(); if (bcurs != NULL) (void)bcurs->close(); if (tcurs != NULL) (void)tcurs->close(); if (t != NULL) (void)t->abort(); if (verbose) cout << "Transaction A=" << (long)account << " B=" << (long)branch << " T=" << (long)teller << " failed\n"; return (-1); }
// // XXX Figure out the appropriate way to pick out IDs. // int TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb, int accounts, int branches, int tellers) { Dbc *acurs = NULL; Dbc *bcurs = NULL; Dbc *tcurs = NULL; DbTxn *t = NULL; db_recno_t key; Defrec rec; Histrec hrec; int account, branch, teller, ret; Dbt d_dbt; Dbt d_histdbt; Dbt k_dbt; Dbt k_histdbt(&key, sizeof(key)); // !!! // This is sample code -- we could move a lot of this into the driver // to make it faster. // account = random_id(ACCOUNT, accounts, branches, tellers); branch = random_id(BRANCH, accounts, branches, tellers); teller = random_id(TELLER, accounts, branches, tellers); k_dbt.set_size(sizeof(int)); d_dbt.set_flags(DB_DBT_USERMEM); d_dbt.set_data(&rec); d_dbt.set_ulen(sizeof(rec)); hrec.aid = account; hrec.bid = branch; hrec.tid = teller; hrec.amount = 10; // Request 0 bytes since we're just positioning. d_histdbt.set_flags(DB_DBT_PARTIAL); // START PER-TRANSACTION TIMING. // // Technically, TPCB requires a limit on response time, you only get // to count transactions that complete within 2 seconds. That's not // an issue for this sample application -- regardless, here's where // the transaction begins. if (txn_begin(NULL, &t, 0) != 0) goto err; if (adb->cursor(t, &acurs, 0) != 0 || bdb->cursor(t, &bcurs, 0) != 0 || tdb->cursor(t, &tcurs, 0) != 0) goto err; try { // Account record k_dbt.set_data(&account); if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Branch record k_dbt.set_data(&branch); if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // Teller record k_dbt.set_data(&teller); if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0) goto err; rec.balance += 10; if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0) goto err; // History record d_histdbt.set_flags(0); d_histdbt.set_data(&hrec); d_histdbt.set_ulen(sizeof(hrec)); if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0) goto err; } catch (DbDeadlockException e) { goto err; } if (acurs->close() != 0 || bcurs->close() != 0 || tcurs->close() != 0) goto err; ret = t->commit(0); t = NULL; if (ret != 0) goto err; // END PER-TRANSACTION TIMING. return (0); err: if (acurs != NULL) (void)acurs->close(); if (bcurs != NULL) (void)bcurs->close(); if (tcurs != NULL) (void)tcurs->close(); if (t != NULL) (void)t->abort(); if (verbose) cout << "Transaction A=" << (long)account << " B=" << (long)branch << " T=" << (long)teller << " failed\n"; return (-1); }
static int run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator, const FreezeScript::CompactIdResolverIPtr& resolver) { vector<string> cppArgs; bool debug; bool ice = true; // Needs to be true in order to create default definitions. bool underscore; string outputFile; string inputFile; vector<string> slice; bool evictor; string keyTypeName; string valueTypeName; string selectExpr; string dbEnvName, dbName; const string appName = originalArgs[0]; IceUtilInternal::Options opts; opts.addOpt("h", "help"); opts.addOpt("v", "version"); opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); opts.addOpt("d", "debug"); opts.addOpt("", "ice"); opts.addOpt("", "underscore"); opts.addOpt("o", "", IceUtilInternal::Options::NeedArg); opts.addOpt("f", "", IceUtilInternal::Options::NeedArg); opts.addOpt("", "load", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); opts.addOpt("e"); opts.addOpt("", "key", IceUtilInternal::Options::NeedArg); opts.addOpt("", "value", IceUtilInternal::Options::NeedArg); opts.addOpt("", "select", IceUtilInternal::Options::NeedArg); opts.addOpt("c", "catalog"); vector<string> args; try { args = opts.parse(originalArgs); } catch(const IceUtilInternal::BadOptException& e) { cerr << appName << ": " << e.reason << endl; usage(appName); return EXIT_FAILURE; } // // Freeze creates a lock file by default to prevent multiple processes from opening // the same database environment simultaneously. In the case of a read-only program // such as dumpdb, however, we still want to be able to open the environment despite // the lock. This assumes of course that the other process has opened the environment // with DbPrivate=0. If DbPrivate=0 is also set for dumpdb, we disable the lock. // if(!args.empty()) { // // If an argument is present, we assume it is the name of the database environment. // Ice::PropertiesPtr props = communicator->getProperties(); string prefix = "Freeze.DbEnv." + args[0]; if(props->getPropertyAsIntWithDefault(prefix + ".DbPrivate", 1) <= 0) { props->setProperty(prefix + ".LockFile", "0"); } } if(opts.isSet("h")) { usage(appName); return EXIT_SUCCESS; } if(opts.isSet("version")) { cout << ICE_STRING_VERSION << endl; return EXIT_SUCCESS; } if(opts.isSet("c")) { if(args.empty()) { cerr << appName << ": no database environment specified." << endl; usage(appName); return EXIT_FAILURE; } else if(args.size() > 2) { usage(appName); return EXIT_FAILURE; } try { FreezeScript::CatalogDataMap catalog = FreezeScript::readCatalog(communicator, args[0]); if(args.size() == 1) { if(catalog.empty()) { cout << "Catalog is empty." << endl; } else { cout << "Catalog contents:" << endl; for(FreezeScript::CatalogDataMap::const_iterator p = catalog.begin(); p != catalog.end(); ++p) { cout << endl; printCatalogData(p->first, p->second); } } } else { FreezeScript::CatalogDataMap::const_iterator p = catalog.find(args[1]); if(p == catalog.end()) { cerr << appName << ": database `" << args[1] << "' not found in environment `" << args[0] << "'." << endl; return EXIT_FAILURE; } else { printCatalogData(p->first, p->second); } } return EXIT_SUCCESS; } catch(const FreezeScript::FailureException& ex) { cerr << appName << ": " << ex.reason() << endl; return EXIT_FAILURE; } } if(opts.isSet("D")) { vector<string> optargs = opts.argVec("D"); for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { cppArgs.push_back("-D" + *i); } } if(opts.isSet("U")) { vector<string> optargs = opts.argVec("U"); for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { cppArgs.push_back("-U" + *i); } } if(opts.isSet("I")) { vector<string> optargs = opts.argVec("I"); for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) { cppArgs.push_back("-I" + *i); } } debug = opts.isSet("debug"); // No need to set --ice option here -- it is always true. underscore = opts.isSet("underscore"); if(opts.isSet("o")) { outputFile = opts.optArg("o"); } if(opts.isSet("f")) { inputFile = opts.optArg("f"); } if(opts.isSet("load")) { vector<string> optArgs = opts.argVec("load"); for(vector<string>::const_iterator i = optArgs.begin(); i != optArgs.end(); ++i) { slice.push_back(*i); } } evictor = opts.isSet("e"); if(opts.isSet("key")) { keyTypeName = opts.optArg("key"); } if(opts.isSet("value")) { valueTypeName = opts.optArg("value"); } if(opts.isSet("select")) { selectExpr = opts.optArg("select"); } if(outputFile.empty() && args.size() != 2) { usage(appName); return EXIT_FAILURE; } if(!args.empty()) { dbEnvName = args[0]; } if(args.size() == 2) { dbName = args[1]; } else { usage(appName); return EXIT_FAILURE; } if(!inputFile.empty() && !selectExpr.empty()) { cerr << appName << ": an input file cannot be specified with --select" << endl; return EXIT_FAILURE; } Slice::UnitPtr unit = Slice::Unit::createUnit(true, true, ice, underscore); FreezeScript::Destroyer<Slice::UnitPtr> unitD(unit); if(!FreezeScript::parseSlice(appName, unit, slice, cppArgs, debug, "-D__DUMPDB__")) { return EXIT_FAILURE; } FreezeScript::createEvictorSliceTypes(unit); FreezeScript::collectCompactIds(unit, resolver); // // If no input file was provided, then we need to generate default descriptors. // string descriptors; if(inputFile.empty()) { const string evictorKeyTypeName = "::Ice::Identity"; const string oldEvictorValueTypeName = "::Freeze::ObjectRecord"; const string newEvictorValueTypeName = "Object"; if((!keyTypeName.empty() && valueTypeName.empty()) || (keyTypeName.empty() && !valueTypeName.empty() && !evictor)) { cerr << appName << ": a key type and a value type must be specified" << endl; usage(appName); return EXIT_FAILURE; } else if(valueTypeName.empty()) { try { FreezeScript::CatalogDataMap catalog = FreezeScript::readCatalog(communicator, dbEnvName); FreezeScript::CatalogDataMap::iterator p = catalog.find(dbName); if(p == catalog.end()) { cerr << appName << ": database `" << dbName << "' not found in catalog." << endl; cerr << "Current catalog databases:" << endl; for(p = catalog.begin(); p != catalog.end(); ++p) { cerr << " " << p->first << endl; } return EXIT_FAILURE; } else { if(p->second.evictor) { evictor = true; } keyTypeName = p->second.key; valueTypeName = p->second.value; if(evictor && valueTypeName.empty()) { valueTypeName = oldEvictorValueTypeName; } } } catch(const FreezeScript::FailureException& ex) { cerr << appName << ": " << ex.reason() << endl; return EXIT_FAILURE; } } if(evictor) { if(keyTypeName.empty()) { keyTypeName = evictorKeyTypeName; } if(valueTypeName.empty()) { valueTypeName = newEvictorValueTypeName; } } Slice::TypePtr keyType, valueType; Slice::TypeList l; l = unit->lookupType(keyTypeName, false); if(l.empty()) { cerr << appName << ": unknown key type `" << keyTypeName << "'" << endl; return EXIT_FAILURE; } keyType = l.front(); l = unit->lookupType(valueTypeName, false); if(l.empty()) { cerr << appName << ": unknown value type `" << valueTypeName << "'" << endl; return EXIT_FAILURE; } valueType = l.front(); ostringstream os; IceUtilInternal::XMLOutput out(os); out << se("dumpdb"); FreezeScript::SliceVisitor visitor(out, keyType, valueType, selectExpr); unit->visit(&visitor, false); out << ee; descriptors = os.str(); if(!outputFile.empty()) { IceUtilInternal::ofstream of(outputFile); if(!of.good()) { cerr << appName << ": unable to open file `" << outputFile << "'" << endl; return EXIT_FAILURE; } of << descriptors << endl; of.close(); return EXIT_SUCCESS; } } else { IceUtilInternal::ifstream in(inputFile); char buff[1024]; while(true) { in.read(buff, 1024); descriptors.append(buff, static_cast<size_t>(in.gcount())); if(in.gcount() < 1024) { break; } } in.close(); } FreezeScript::ValueFactoryPtr valueFactory = new FreezeScript::ValueFactory; communicator->getValueFactoryManager()->add(valueFactory, ""); DbEnv dbEnv(0); DbTxn* txn = 0; Freeze::ConnectionPtr connection; int status = EXIT_SUCCESS; try { #ifdef _WIN32 // // Berkeley DB may use a different C++ runtime. // dbEnv.set_alloc(::malloc, ::realloc, ::free); #endif // // Open the database environment and start a transaction. // { u_int32_t flags = DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_MPOOL; dbEnv.open(dbEnvName.c_str(), flags, FREEZE_SCRIPT_DB_MODE); } // // We're creating a connection just to make sure the database environment // isn't locked. // connection = Freeze::createConnection(communicator, dbEnvName, dbEnv); dbEnv.txn_begin(0, &txn, 0); FreezeScript::ErrorReporterPtr errorReporter = new FreezeScript::ErrorReporter(cerr, false); try { FreezeScript::DataFactoryPtr factory = new FreezeScript::DataFactory(communicator, unit, errorReporter); FreezeScript::DescriptorHandler dh(factory, unit, errorReporter, valueFactory); istringstream istr(descriptors); IceXML::Parser::parse(istr, dh); FreezeScript::DumpDBDescriptorPtr descriptor = dh.descriptor(); descriptor->validate(); if(evictor) { // // The evictor database file contains multiple databases. We must first // determine the names of those databases, ignoring any whose names // begin with "$index:". Each database represents a separate facet, with // the facet name used as the database name. The database named "$default" // represents the main object. // vector<string> dbNames; { Db db(&dbEnv, 0); db.open(txn, dbName.c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); Dbt dbKey, dbValue; dbKey.set_flags(DB_DBT_MALLOC); dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Dbc* dbc = 0; db.cursor(txn, &dbc, 0); while(dbc->get(&dbKey, &dbValue, DB_NEXT) == 0) { string s(static_cast<char*>(dbKey.get_data()), dbKey.get_size()); if(s.find("$index:") != 0) { dbNames.push_back(s); } free(dbKey.get_data()); } dbc->close(); db.close(0); } // // Dump each database. // for(vector<string>::iterator p = dbNames.begin(); p != dbNames.end(); ++p) { string name = *p; string facet = (name == "$default" ? string("") : name); Db db(&dbEnv, 0); db.open(txn, dbName.c_str(), name.c_str(), DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE); descriptor->dump(communicator, &db, txn, facet); db.close(0); } } else { // // Dump a map database. // Db db(&dbEnv, 0); db.open(txn, dbName.c_str(), 0, DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE); descriptor->dump(communicator, &db, txn, ""); db.close(0); } } catch(const IceXML::ParserException& ex) { errorReporter->error(ex.reason()); } } catch(const DbException& ex) { cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } catch(...) { try { if(txn) { txn->abort(); } dbEnv.close(0); } catch(const DbException& ex) { cerr << appName << ": database error: " << ex.what() << endl; } if(connection) { connection->close(); connection = 0; } throw; } try { if(txn) { txn->abort(); } if(connection) { connection->close(); } dbEnv.close(0); } catch(const DbException& ex) { cerr << appName << ": database error: " << ex.what() << endl; status = EXIT_FAILURE; } return status; }
bool CDB::Rewrite(const string& strFile, BerkerleyDBUpgradeProgress &progress, const char* pszSkip, int previousVer, int currentVer) { while (!fShutdown) { { LOCK(bitdb.cs_db); if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0) { // Flush log data to the dat file bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); bitdb.mapFileUseCount.erase(strFile); bool fSuccess = true; printf("Rewriting %s...\n", strFile.c_str()); string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} CDB db(strFile.c_str(), "r"); Db* pdbCopy = new Db(&bitdb.dbenv, 0); int ret = pdbCopy->open(NULL, // Txn pointer strFileRes.c_str(), // Filename "main", // Logical db name DB_BTREE, // Database type DB_CREATE, // Flags 0); if (ret > 0) { printf("Cannot create database file %s\n", strFileRes.c_str()); fSuccess = false; } Dbc* pcursor = db.GetCursor(); if (pcursor) nTotalBytesCompleted = 0; nProgressPercent = 0; int numRows = 0; CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); while (fSuccess) { int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); if (ret == DB_NOTFOUND) { pcursor->close(); break; } else if (ret != 0) { pcursor->close(); fSuccess = false; break; } numRows++; } db.ReadAtCursor(pcursor, ssKey, ssValue, DB_FIRST); nTotalBytes = numRows; // Set up progress calculations and callbacks. callbackTotalOperationProgress = &progress; ExternalBlockFileProgress callbackProgress; callbackProgress.connect(RewriteProgress); (*callbackTotalOperationProgress)(0.0); fSuccess = true; while (fSuccess) { CDataStream ssKey(SER_DISK, CLIENT_VERSION); CDataStream ssValue(SER_DISK, CLIENT_VERSION); int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); if (ret == DB_NOTFOUND) { pcursor->close(); break; } else if (ret != 0) { pcursor->close(); fSuccess = false; break; } /* if (strncmp(&ssKey[0], "\x02tx", 3) != 0) { char* k = &ssKey[0]; int xx = 1; } */ if (pszSkip && strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) continue; if (strncmp(&ssKey[0], "\x07version", 8) == 0) { // Update version: ssValue.clear(); ssValue << currentVer; } // update blockindex to include block hash if (previousVer <= DB_MINVER_INCHASH && strncmp(&ssKey[0], "\nblockindex", 11) == 0) { CDiskBlockIndex diskindex(DB_PREV_VER); ssValue >> diskindex; diskindex.fileVersion = CLIENT_VERSION; // update version /* // Construct block index object CBlockIndex* pindexNew = InsertBlockIndex(blockHash); pindexNew->pprev = InsertBlockIndex(diskindex.hashPrev); pindexNew->pnext = InsertBlockIndex(diskindex.hashNext); pindexNew->nFile = diskindex.nFile; pindexNew->nBlockPos = diskindex.nBlockPos; pindexNew->nHeight = diskindex.nHeight; pindexNew->nMint = diskindex.nMint; pindexNew->nMoneySupply = diskindex.nMoneySupply; pindexNew->nFlags = diskindex.nFlags; pindexNew->nStakeModifier = diskindex.nStakeModifier; pindexNew->prevoutStake = diskindex.prevoutStake; pindexNew->nStakeTime = diskindex.nStakeTime; pindexNew->hashProofOfStake = diskindex.hashProofOfStake; pindexNew->nVersion = diskindex.nVersion; pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; pindexNew->nTime = diskindex.nTime; pindexNew->nBits = diskindex.nBits; pindexNew->nNonce = diskindex.nNonce; */ uint256 blockHash = diskindex.GetBlockHash(); // calc hash (force) ssValue << diskindex; // serialize } Dbt datKey(&ssKey[0], ssKey.size()); Dbt datValue(&ssValue[0], ssValue.size()); (callbackProgress)(1); int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); if (ret2 > 0) fSuccess = false; } if (fSuccess) { db.Close(); bitdb.CloseDb(strFile); if (pdbCopy->close(0)) fSuccess = false; delete pdbCopy; } } if (fSuccess) { Db dbA(&bitdb.dbenv, 0); if (dbA.remove(strFile.c_str(), NULL, 0)) fSuccess = false; Db dbB(&bitdb.dbenv, 0); if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0)) fSuccess = false; } if (!fSuccess) printf("Rewriting of %s FAILED!\n", strFileRes.c_str()); return fSuccess; } }
/* Get all scores of a certain patient. * Returns 0 if everything is ok; * returns -1 if permission is denied, and error message is not sent out successfully; * returns 1 if permission is denied, but error message is sent out successfully; * returns -2 if patient ID is invalid, and error message is not sent out successfully; * returns 2 if patient ID is invalid, but error message is sent out successfully; * returns -3 if error occurs when searching score value table, and error message is not sent out successfully; * returns 3 if error occurs when searching score value table, but error message is sent out successfully; * returns -4 if no score value record is found, and error message is not sent out successfully; * returns 4 if no score value record is found, but error message is sent out successfully; * returns -5 if data size message is not sent out successfully; * returns -6 if score value data are not sent out successfully; * returns -7 if no session is available, and the message is not sent out successfully; * returns -8 if error occurs when searching session table, and error message is not sent out successfully; * returns 8 if error occurs when searching session table, but error message is sent out successfully; * returns -9 if session data are not sent out successfully. */ int srvSession::sendPatientScores() { if (!permissions.size()) { statMsg = "Permission denied"; if (sendStatMsg()) return -1; return 1; } // send error message to client if patient ID is invalid or score values not found int32 pID; bool conv_stat = str2num(c_tokens[1], pID); if (!conv_stat || pID <= 0) { statMsg = "no_data: Invalid patient ID " + c_tokens[1]; if (sendStatMsg()) return -2; return 2; } // get score values set<int32> sid_set; DbTxn* txn = NULL; dbs.env.getEnv()->txn_begin(NULL, &txn, 0); Dbc* cursorp = NULL; if (dbs.scoreValueDB.getDb().cursor(txn, &cursorp, 0)) { txn->abort(); statMsg = "no_data: db error when searching score value table"; if (sendStatMsg()) return -3; return 3; } // Iterate over score values table Dbt key, data; int ret; int32 status = 0; while ((ret = cursorp->get(&key, &data, DB_NEXT_NODUP)) == 0) { DBscorevalue svData; svData.deserializeHdr(data.get_data()); if (pID != svData.patient || svData.deleted) continue; string tmpPerm = getMaxPerm(svData, permissions); if (tmpPerm.empty()) continue; /* Add session IDs into session_list vector (session 0 is ignored here * because this session doesn't exist in session table anyway) */ int32 sess_id = svData.sessionid; if (sess_id) sid_set.insert(sess_id); // Add real score value records into DBscorevalue vector. status = 1; uint32 dat_size = data.get_size(); statMsg = "scorevalue: " + num2str(dat_size) + " " + tmpPerm; if (sendStatMsg()) { cursorp->close(); txn->abort(); return -4; } if (sendBuffer(g_session, dat_size, (char*) data.get_data())) { statMsg = "Error when sending score value to client"; cursorp->close(); txn->abort(); return -4; } } // Returns -1 if ret is non-zero and it doesn't reach the end of table if (ret && ret != DB_NOTFOUND) { cursorp->close(); txn->abort(); statMsg = "no_data: db error when searching score value table"; if (sendStatMsg()) return -3; return 3; } cursorp->close(); if (status == 0) { txn->commit(0); statMsg = "no_scorevalue"; if (sendStatMsg()) return -5; return 5; } // If session ID list is empty, tell client that no session info sent out if (sid_set.size() == 0) { txn->commit(0); statMsg = "no_session"; if (sendStatMsg()) return -7; return 0; } // get related DBsession vector<DBsession> sessList; int32 dat_size = getSessions(dbs.sessionDB, txn, sid_set, sessList); // Note that dat_size may be zero if all score values are static if (dat_size <= 0) { txn->abort(); statMsg = "no_data: Session record not found"; if (sendStatMsg()) return -8; return 8; } txn->commit(0); // send session data to client char sess_buff[dat_size]; serialize(sessList, sess_buff); if (sendData(dat_size, sess_buff)) { statMsg = "Error when sending patient session data to client: " + statMsg; return -9; } return 0; }