bool Table::Get(Transaction* tx, const ByteString &key, ByteString &value) { Dbt dbtKey; Dbt dbtValue; DbTxn* txn = NULL; int ret; if (tx) txn = tx->txn; dbtKey.set_flags(DB_DBT_USERMEM); dbtKey.set_data(key.buffer); dbtKey.set_ulen(key.length); dbtKey.set_size(key.length); dbtValue.set_flags(DB_DBT_USERMEM); dbtValue.set_data(value.buffer); dbtValue.set_ulen(value.size); ret = db->get(txn, &dbtKey, &dbtValue, 0); // DB_PAGE_NOTFOUND can occur with parallel PRUNE and GET operations // probably because we have DB_READ_UNCOMMITED turned on if (ret == DB_KEYEMPTY || ret == DB_NOTFOUND || ret == DB_PAGE_NOTFOUND) return false; if (dbtValue.get_size() > (size_t) value.size) return false; value.length = dbtValue.get_size(); return true; }
static int dbdump(const char *env_dir, const char *dbfile, const char *dbname) { int r; #if defined(USE_ENV) && USE_ENV DbEnv env(DB_CXX_NO_EXCEPTIONS); r = env.set_redzone(0); assert(r==0); r = env.open(env_dir, DB_INIT_MPOOL + DB_CREATE + DB_PRIVATE, 0777); assert(r == 0); Db db(&env, DB_CXX_NO_EXCEPTIONS); #else Db db(0, DB_CXX_NO_EXCEPTIONS); #endif r = db.open(0, dbfile, dbname, DB_UNKNOWN, 0, 0777); if (r != 0) { printf("cant open %s:%s %d:%s\n", dbfile, dbname, r, db_strerror(r)); #if defined(USE_ENV) && USE_ENV r = env.close(0); assert(r == 0); #endif return 1; } u_int32_t dbflags; r = db.get_flags(&dbflags); assert(r == 0); #ifndef TOKUDB if (dbflags & DB_DUP) printf("duplicates=1\n"); if (dbflags & DB_DUPSORT) printf("dupsort=1\n"); #endif #if 0 u_int32_t nodesize; r = db.get_nodesize(&nodesize); assert(r == 0); printf("nodesize=%d\n", nodesize); #endif Dbc *cursor; r = db.cursor(0, &cursor, 0); assert(r == 0); Dbt key; key.set_flags(DB_DBT_REALLOC); Dbt val; val.set_flags(DB_DBT_REALLOC); for (;;) { r = cursor->get(&key, &val, DB_NEXT); if (r != 0) break; // printf("%.*s\n", key.get_size(), (char *)key.get_data()); hexdump(&key); // printf("%.*s\n", val.get_size(), (char *)val.get_data()); hexdump(&val); } if (key.get_data()) toku_free(key.get_data()); if (val.get_data()) toku_free(val.get_data()); r = cursor->close(); assert(r == 0); r = db.close(0); assert(r == 0); #if defined(USE_ENV) && USE_ENV r = env.close(0); assert(r == 0); #endif return 0; }
vector<string> Freeze::EvictorIBase::allDbs() const { vector<string> result; try { Db db(_dbEnv->getEnv(), 0); // // Berkeley DB expects file paths to be UTF8 encoded. // db.open(0, nativeToUTF8(_filename, getProcessStringConverter()).c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0); Dbc* dbc = 0; db.cursor(0, &dbc, 0); Dbt dbKey; dbKey.set_flags(DB_DBT_MALLOC); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); bool more = true; while(more) { more = (dbc->get(&dbKey, &dbValue, DB_NEXT) == 0); if(more) { string dbName(static_cast<char*>(dbKey.get_data()), dbKey.get_size()); if(dbName.find(indexPrefix) != 0) { result.push_back(dbName); } free(dbKey.get_data()); } } dbc->close(); db.close(0); } catch(const DbException& dx) { if(dx.get_errno() != ENOENT) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } } return result; }
bool Freeze::IteratorHelperI::next(bool skipDups) const { // // Keep 0 length since we're not interested in the data // Dbt dbKey; dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int flags = DB_NEXT; if(skipDups) { flags = DB_NEXT_NODUP; } else if(_indexed && _onlyDups) { flags = DB_NEXT_DUP; } try { if(_dbc->get(&dbKey, &dbValue, flags) == 0) { return true; } else { return false; } } catch(const ::DbDeadlockException& dx) { if(_tx != 0) { _tx->dead(); } DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } catch(const ::DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } }
RecordData Database::get(const RecordID& id) const { Dbt key(id.data(), id.size()); Dbt data; thread_local static std::vector<char> buffer(256); while (true) { try { data.set_flags(DB_DBT_USERMEM); data.set_data(buffer.data()); data.set_ulen(buffer.size()); const int err = dbMain_.get(/*txnid*/nullptr, &key, &data, /*flags*/0); assert (err == 0); break; } catch(DbException const& ex) { if (ex.get_errno() != DB_BUFFER_SMALL) { throw; } buffer.resize(data.get_size() * 1.5); } } return RecordData(data); }
HeaderGroup* BulkHeaderGroup::getGroup(NewsGroup* ng, QString& articleIndex) { HeaderGroup *hg = 0; int ret; Dbt groupkey; Dbt groupdata; memset(&groupkey, 0, sizeof(groupkey)); memset(&groupdata, 0, sizeof(groupdata)); groupdata.set_flags(DB_DBT_MALLOC); QByteArray ba = articleIndex.toLocal8Bit(); const char *k= ba.constData(); groupkey.set_data((void*)k); groupkey.set_size(articleIndex.length()); Db* groupsDb = ng->getGroupingDb(); ret=groupsDb->get(NULL, &groupkey, &groupdata, 0); if (ret != 0) //key not found { qDebug() << "Failed to find group with key " << articleIndex; } else { qDebug() << "Found group with key " << articleIndex; hg=new HeaderGroup(articleIndex.length(), (char*)k, (char*)groupdata.get_data()); void* ptr = groupdata.get_data(); Q_FREE(ptr); } return hg; }
void berkeleydb_store<Object>::get(const timestamp& time, const long lp_id, obj_ptr& ret) { boost::lock_guard<boost::mutex> guard(get_mutex_); /* generate key */ std::vector<char> key; key_lpid_to_char(time, lp_id, key); Dbt db_key(&key[0], key.size()); /* get data */ char* event_binary; Dbt data; data.set_data(event_binary); data.set_flags(DB_DBT_MALLOC); db->get(NULL, &db_key, &data, 0); /* deserialize the data */ std::string binary = std::string((char*) data.get_data(), data.get_size()); std::stringstream from_ss; from_ss << binary; boost::archive::binary_iarchive iar(from_ss); Object obj; iar >> obj; ret = boost::make_shared<Object>(obj); };
AntiCacheBlock AntiCacheDB::readBlockBerkeleyDB(std::string tableName, int16_t blockId) { Dbt key; key.set_data(&blockId); key.set_size(sizeof(int16_t)); Dbt value; value.set_flags(DB_DBT_MALLOC); VOLT_DEBUG("Reading evicted block with id %d", blockId); int ret_value = m_db->get(NULL, &key, &value, 0); if (ret_value != 0) { VOLT_ERROR("Invalid anti-cache blockId '%d' for table '%s'", blockId, tableName.c_str()); throw UnknownBlockAccessException(tableName, blockId); } else { // m_db->del(NULL, &key, 0); // if we have this the benchmark won't end assert(value.get_data() != NULL); } AntiCacheBlock block(blockId, static_cast<char*>(value.get_data()), value.get_size()); return (block); }
db_iterator Database::dirs_begin() const { Dbc* pCursor = nullptr; dbDirs_.cursor(NULL, &pCursor, 0); assert(pCursor); RecordID id; Dbt key; Dbt data; key.set_flags(DB_DBT_USERMEM); key.set_data(id.data()); key.set_ulen(id.size()); const int err = pCursor->get(&key, &data, DB_FIRST); if (err) { pCursor->close(); if (err != DB_NOTFOUND) { throw DbException("Failed to obtain first directory record", err); } return dirs_end(); } return db_iterator(pCursor, make_Record(std::move(id), RecordData(data))); }
/** * Cursor must be closed before the transaction is aborted/commited. * http://download.oracle.com/docs/cd/E17076_02/html/programmer_reference/transapp_cursor.html */ Bdb::ResponseCode Bdb:: update(const std::string& key, const std::string& value) { if (!inited_) { fprintf(stderr, "insert called on uninitialized database"); return Error; } DbTxn* txn = NULL; Dbc* cursor = NULL; Dbt dbkey, dbdata; dbkey.set_data(const_cast<char*>(key.c_str())); dbkey.set_size(key.size()); dbdata.set_data(const_cast<char*>(value.c_str())); dbdata.set_size(value.size()); Dbt currentData; currentData.set_data(NULL); currentData.set_ulen(0); currentData.set_dlen(0); currentData.set_doff(0); currentData.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); int rc = 0; for (uint32_t idx = 0; idx < numRetries_; idx++) { env_->txn_begin(NULL, &txn, 0); (*db_).cursor(txn, &cursor, DB_READ_COMMITTED); // move the cursor to the record. rc = cursor->get(&dbkey, ¤tData, DB_SET | DB_RMW); if (rc != 0) { cursor->close(); txn->abort(); if (rc == DB_NOTFOUND) { return KeyNotFound; } else if (rc != DB_LOCK_DEADLOCK) { fprintf(stderr, "Db::get() returned: %s", db_strerror(rc)); return Error; } continue; } // update the record. rc = cursor->put(NULL, &dbdata, DB_CURRENT); cursor->close(); if (rc == 0) { txn->commit(DB_TXN_SYNC); return Success; } else { txn->abort(); if (rc != DB_LOCK_DEADLOCK) { fprintf(stderr, "Db::put() returned: %s", db_strerror(rc)); return Error; } } } fprintf(stderr, "update failed %d times", numRetries_); return Error; }
bool Freeze::IteratorHelperI::lowerBound(const Key& key) const { // // We retrieve the actual key for upperBound // Dbt dbKey; _key = key; initializeOutDbt(_key, dbKey); dbKey.set_size(static_cast<u_int32_t>(_key.size())); // // Keep 0 length since we're not interested in the data // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); for(;;) { try { int err = _dbc->get(&dbKey, &dbValue, DB_SET_RANGE); if(err == 0) { _key.resize(dbKey.get_size()); return true; } else if(err == DB_NOTFOUND) { return false; } else { // // Bug in Freeze // assert(0); throw DatabaseException(__FILE__, __LINE__); } } catch(const ::DbDeadlockException& dx) { if(_tx != 0) { _tx->dead(); } DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } catch(const ::DbException& dx) { handleDbException(dx, _key, dbKey, __FILE__, __LINE__); } } }
bool Freeze::IteratorHelperI::find(const Key& key) const { Dbt dbKey; initializeInDbt(key, dbKey); // // 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); // // Keep 0 length since we're not interested in the data // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); for(;;) { try { return _dbc->get(&dbKey, &dbValue, DB_SET) == 0; } catch(const ::DbDeadlockException& dx) { if(_tx != 0) { _tx->dead(); } DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } catch(const ::DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } } }
unsigned long CKeyValuePair::GetUnsignedLong(const std::string &key) { structKey k( UInt32, key.size(), key.c_str() ); Dbt v; unsigned long value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( unsigned long ) ); v.set_size( sizeof( unsigned long ) ); v.set_data( &value ); Get( k, &v ); return value; }
float CKeyValuePair::GetFloat(const std::string &key) { structKey k( Float, key.size(), key.c_str() ); Dbt v; float value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( float ) ); v.set_size( sizeof( float ) ); v.set_data( &value ); Get( k, &v ); return value; }
double CKeyValuePair::GetDouble(const std::string &key) { structKey k( Double, key.size(), key.c_str() ); Dbt v; double value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( double ) ); v.set_size( sizeof( double ) ); v.set_data( &value ); Get( k, &v ); return value; }
short CKeyValuePair::GetShort(const std::string &key) { structKey k( Int16, key.size(), key.c_str() ); Dbt v; short value; v.set_flags( DB_DBT_USERMEM ); v.set_ulen( sizeof( short ) ); v.set_size( sizeof( short ) ); v.set_data( &value ); Get( k, &v ); return value; }
void berkeleydb_store<Object>::get_range(const timestamp& from, const timestamp& to, const long lp_id, std::vector<obj_ptr>& ret_obj) { boost::lock_guard<boost::mutex> guard(get_mutex_); if (from > to) return; /* generate key */ std::vector<char> from_char; key_lpid_to_char(from, lp_id, from_char); Dbt db_key = Dbt(&from_char[0], from_char.size()); /* prepare data */ char* binary; Dbt data; data.set_data(binary); data.set_flags(DB_DBT_MALLOC); /* seek to from */ Dbc* cursorp; db->cursor(NULL, &cursorp, 0); int ret = cursorp->get(&db_key, &data, DB_SET_RANGE); if (ret) { if (cursorp != NULL) cursorp->close(); return; } std::string get_data_binary = std::string((char*) data.get_data(), data.get_size()); std::stringstream from_ss; from_ss << get_data_binary; boost::archive::binary_iarchive iar(from_ss); Object obj; iar >> obj; ret_obj.push_back(boost::make_shared<Object>(obj)); /* get until end */ while ((ret = cursorp->get(&db_key, &data, DB_NEXT)) == 0) { timestamp tmstmp; long id; char_to_key_lpid((char*) db_key.get_data(), tmstmp, id); if (tmstmp > to || id != lp_id) break; get_data_binary = std::string((char*) data.get_data(), data.get_size()); std::stringstream ss; ss << get_data_binary; boost::archive::binary_iarchive iar(ss); Object deserialized_obj; iar >> deserialized_obj; ret_obj.push_back(boost::make_shared<Object>(deserialized_obj)); } if (cursorp != NULL) cursorp->close(); };
bool Freeze::IteratorHelperI::find(const Dbt& key) const { assert((key.get_flags() & DB_DBT_USERMEM) != 0); Dbt dbKey(key); #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // 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(dbKey.get_flags() | DB_DBT_PARTIAL); #else // // In DB > 5.1 we can not set DB_DBT_PARTIAL in the key Dbt, // when using DB_SET, we must resize the Dbt key param to hold enough // space or Dbc::get fails with DB_BUFFER_SMALL. // dbKey.set_ulen(dbKey.get_size()); #endif // // Keep 0 length since we're not interested in the data. // Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); for(;;) { try { return _dbc->get(&dbKey, &dbValue, DB_SET) == 0; } catch(const ::DbDeadlockException& dx) { if(_tx != 0) { _tx->dead(); } DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } catch(const ::DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } } }
void Database::del(const RecordID& id) { Dbt key(id.data(), id.size()); // fetch children std::vector<RecordID> childrenIds; Dbc* pCursor = nullptr; dbParentId_.cursor(NULL, &pCursor, 0); assert(pCursor); BOOST_SCOPE_EXIT(&pCursor) { if(pCursor) pCursor->close(); } BOOST_SCOPE_EXIT_END Dbt keyChild; Dbt record; record.set_flags(DB_DBT_PARTIAL); record.set_doff(0); record.set_dlen(0); int res = pCursor->pget(&key, &keyChild, &record, DB_SET); while (res == 0) { childrenIds.push_back(RecordID(keyChild)); res = pCursor->pget(&key, &keyChild, &record, DB_NEXT_DUP); } if (res != DB_NOTFOUND) { throw DbException("Failed to obtain children ids", res); } pCursor->close(); pCursor = nullptr; // delete children for (const RecordID& childId : childrenIds) { del(childId); } // delete the record itself const int err = dbMain_.del(nullptr, &key, /*flags*/0); if (err && err != DB_NOTFOUND) { std::ostringstream ss; ss << "Failed to delete record id='" << id << '\''; throw DbException(ss.str().c_str(), err); } }
void Freeze::IteratorHelperI::set(const Dbt& value) { if(_indexed) { DatabaseException ex(__FILE__, __LINE__); ex.message = "Cannot set an iterator retrieved through an index"; throw ex; } // // key ignored // Dbt dbKey; dbKey.set_flags(DB_DBT_USERMEM); Dbt dbValue(value); if(_tx != 0) { _map.closeAllIteratorsExcept(_tx); } try { #ifndef NDEBUG int err = _dbc->put(&dbKey, &dbValue, DB_CURRENT); assert(err == 0); #else _dbc->put(&dbKey, &dbValue, DB_CURRENT); #endif } catch(const ::DbDeadlockException& dx) { if(_tx != 0) { _tx->dead(); } DeadlockException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } catch(const ::DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } }
string read(const char* skey){ Dbt key((void*)skey, ::strlen(skey)); //fetch char* buf = _allocHeap(); //keep as heap mem Dbt data; data.set_data(buf); data.set_ulen(MAX_LEN); data.set_flags(DB_DBT_USERMEM); if( _db->get(nullptr, &key, &data, 0) == DB_NOTFOUND){ return string("F"); }; string res(buf); delete[] buf; return res; };
int main(int argc, char *argv[]) { try { Db *db = new Db(NULL, 0); db->open(NULL, "my.db", NULL, DB_BTREE, DB_CREATE, 0644); // populate our massive database. // all our strings include null for convenience. // Note we have to cast for idiomatic // usage, since newer gcc requires it. Dbt *keydbt = new Dbt((char *)"key", 4); Dbt *datadbt = new Dbt((char *)"data", 5); db->put(NULL, keydbt, datadbt, 0); // Now, retrieve. We could use keydbt over again, // but that wouldn't be typical in an application. Dbt *goodkeydbt = new Dbt((char *)"key", 4); Dbt *badkeydbt = new Dbt((char *)"badkey", 7); Dbt *resultdbt = new Dbt(); resultdbt->set_flags(DB_DBT_MALLOC); int ret; if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { cout << "get: " << DbEnv::strerror(ret) << "\n"; } else { char *result = (char *)resultdbt->get_data(); cout << "got data: " << result << "\n"; } if ((ret = db->get(NULL, badkeydbt, resultdbt, 0)) != 0) { // We expect this... cout << "get using bad key: " << DbEnv::strerror(ret) << "\n"; } else { char *result = (char *)resultdbt->get_data(); cout << "*** got data using bad key!!: " << result << "\n"; } cout << "finished test\n"; } catch (DbException &dbe) { cerr << "Db Exception: " << dbe.what(); } return 0; }
void test_dbt(void) { u_int32_t size = 3; u_int32_t flags = 5; u_int32_t ulen = 7; void* data = &size; Dbt dbt; dbt.set_size(size); dbt.set_flags(flags); dbt.set_data(data); dbt.set_ulen(ulen); assert(dbt.get_size() == size); assert(dbt.get_flags() == flags); assert(dbt.get_data() == data); assert(dbt.get_ulen() == ulen); }
// Shows a vendor record. Each vendor record is an instance of // a vendor structure. See loadVendorDB() in // example_database_load for how this structure was originally // put into the database. int show_vendor(MyDb &vendorDB, const char *vendor) { Dbt data; VENDOR my_vendor; try { // Set the search key to the vendor's name // vendor is explicitly cast to char * to stop a compiler // complaint. Dbt key((char *)vendor, (u_int32_t)strlen(vendor) + 1); // Make sure we use the memory we set aside for the VENDOR // structure rather than the memory that DB allocates. // Some systems may require structures to be aligned in memory // in a specific way, and DB may not get it right. data.set_data(&my_vendor); data.set_ulen(sizeof(VENDOR)); data.set_flags(DB_DBT_USERMEM); // Get the record vendorDB.getDb().get(NULL, &key, &data, 0); std::cout << " " << my_vendor.street << "\n" << " " << my_vendor.city << ", " << my_vendor.state << "\n" << " " << my_vendor.zipcode << "\n" << " " << my_vendor.phone_number << "\n" << " Contact: " << my_vendor.sales_rep << "\n" << " " << my_vendor.sales_rep_phone << std::endl; } catch (DbException &e) { vendorDB.getDb().err(e.get_errno(), "Error in show_vendor"); throw e; } catch (std::exception &e) { throw e; } return (0); }
void berkeleydb_store<Object>::get_prev(const timestamp& time, const long lp_id, obj_ptr& ret_obj, timestamp& time_of_ret) { boost::lock_guard<boost::mutex> guard(get_mutex_); /* generate key */ std::vector<char> key; key_lpid_to_char(time, lp_id, key); Dbt db_key = Dbt(&key[0], key.size()); /* prepare data */ char* binary; Dbt data; data.set_data(binary); data.set_flags(DB_DBT_MALLOC); /* seek to key */ Dbc* cursorp; db->cursor(NULL, &cursorp, 0); int ret = cursorp->get(&db_key, &data, DB_SET_RANGE); /* seek back */ ret = cursorp->get(&db_key, &data, DB_PREV); /* get value */ std::string obj_binary = std::string((char*) data.get_data(), data.get_size()); std::stringstream ss; ss << obj_binary; boost::archive::binary_iarchive iar(ss); Object obj; iar >> obj; ret_obj = boost::make_shared<Object>(obj); /* get key */ long lp_id_; char_to_key_lpid((char*) db_key.get_data(), time_of_ret, lp_id_); if (cursorp != NULL) cursorp->close(); };
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> Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); // // 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); Key pkey(1024); Dbt pdbKey; initializeOutDbt(pkey, pdbKey); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); Ice::CommunicatorPtr communicator = _store->communicator(); _store->evictor()->saveNow(); vector<Identity> identities; try { for(;;) { Dbc* dbc = 0; identities.clear(); try { // // Move to the first record // _db->cursor(0, &dbc, 0); u_int32_t flags = DB_SET; bool found; 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 // pkey.resize(pkey.capacity()); found = (dbc->pget(&dbKey, &pdbKey, &dbValue, flags) == 0); if(found) { pkey.resize(pdbKey.get_size()); Ice::Identity ident; ObjectStore::unmarshal(ident, pkey, communicator); identities.push_back(ident); flags = DB_NEXT_DUP; } break; // for(;;) } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { handleDbException(dx, pkey, pdbKey, __FILE__, __LINE__); } } } while((firstN <= 0 || identities.size() < static_cast<size_t>(firstN)) && found); Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { // // Ignored // } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedFindFirst while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } // // Retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { // // Ignored // } } throw; } } } catch(const DbException& dx) { handleDbException(dx, __FILE__, __LINE__); } return identities; }
vector<Identity> Freeze::IndexI::untypedFindFirst(const Key& bytes, Int firstN) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // 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.1 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>(bytes.size())); #endif Key pkey(1024); Dbt pdbKey; initializeOutDbt(pkey, pdbKey); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); const Ice::CommunicatorPtr& communicator = _store->communicator(); const Ice::EncodingVersion& encoding = _store->encoding(); TransactionIPtr transaction = _store->evictor()->beforeQuery(); DbTxn* tx = transaction == 0 ? 0 : transaction->dbTxn(); vector<Identity> identities; try { for(;;) { Dbc* dbc = 0; identities.clear(); try { // // Move to the first record // _db->cursor(tx, &dbc, 0); u_int32_t flags = DB_SET; bool found; 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 // pkey.resize(pkey.capacity()); found = (dbc->pget(&dbKey, &pdbKey, &dbValue, flags) == 0); if(found) { pkey.resize(pdbKey.get_size()); Ice::Identity ident; ObjectStoreBase::unmarshal(ident, pkey, communicator, encoding); identities.push_back(ident); flags = DB_NEXT_DUP; } break; // for(;;) } catch(const DbDeadlockException&) { throw; } catch(const DbException& dx) { handleDbException(dx, pkey, pdbKey, __FILE__, __LINE__); } } } while((firstN <= 0 || identities.size() < static_cast<size_t>(firstN)) && found); Dbc* toClose = dbc; dbc = 0; toClose->close(); break; // for (;;) } catch(const DbDeadlockException&) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedFindFirst while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } if(tx != 0) { throw; } // Else retry } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { handleDbException(dx, __FILE__, __LINE__); } return identities; }
Int Freeze::IndexI::untypedCount(const Key& bytes) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); // // 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); Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); _store->evictor()->saveNow(); Int result = 0; try { for(;;) { Dbc* dbc = 0; try { // // Move to the first record // _db->cursor(0, &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&) { // // Ignored // } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedCount while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } // // Retry // } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { // // Ignored // } } throw; } } } catch(const DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } return result; }
Int Freeze::IndexI::untypedCount(const Key& bytes) const { DeactivateController::Guard deactivateGuard(_store->evictor()->deactivateController()); Dbt dbKey; initializeInDbt(bytes, dbKey); #if (DB_VERSION_MAJOR <= 4) || (DB_VERSION_MAJOR == 5 && DB_VERSION_MINOR <= 1) // // 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.1 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>(bytes.size())); #endif Dbt dbValue; dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); TransactionIPtr transaction = _store->evictor()->beforeQuery(); DbTxn* tx = transaction == 0 ? 0 : transaction->dbTxn(); Int result = 0; try { for(;;) { Dbc* dbc = 0; try { // // Move to the first record // _db->cursor(tx, &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(tx != 0) { throw; } // Else ignored } } if(_store->evictor()->deadlockWarning()) { Warning out(_store->communicator()->getLogger()); out << "Deadlock in Freeze::IndexI::untypedCount while searching \"" << _store->evictor()->filename() + "/" + _dbName << "\"; retrying ..."; } if(tx != 0) { throw; } // Else retry } catch(...) { if(dbc != 0) { try { dbc->close(); } catch(const DbDeadlockException&) { if(tx != 0) { throw; } // Else ignored } } throw; } } } catch(const DbDeadlockException& dx) { throw DeadlockException(__FILE__, __LINE__, dx.what(), transaction); } catch(const DbException& dx) { DatabaseException ex(__FILE__, __LINE__); ex.message = dx.what(); throw ex; } return result; }