void Freeze::handleDbException(const DbException& dx, Key& key, Dbt& dbKey, const char* file, int line) { bool bufferSmallException = #if (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR == 2) (dx.get_errno() == ENOMEM); #else (dx.get_errno() == DB_BUFFER_SMALL || dx.get_errno() == ENOMEM); #endif if(bufferSmallException && (dbKey.get_size() > dbKey.get_ulen())) { // // Keep the old key size in case it's used as input // size_t oldKeySize = key.size(); key.resize(dbKey.get_size()); initializeOutDbt(key, dbKey); dbKey.set_size(static_cast<u_int32_t>(oldKeySize)); } else { handleDbException(dx, file, line); } }
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; }
bool operator==(const Dbt&d1, const Dbt&d2) { if (d1.get_size() != d2.get_size()) return false; return memcmp(d1.get_data(), d2.get_data(), d2.get_size()) == 0; }
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 FileRecord::RemoveLock(const std::string& lock_id, std::list<std::pair<std::string,std::string> >& ids) { if(!valid_) return false; Glib::Mutex::Lock lock(lock_); Dbc* cur = NULL; if(!dberr("removelock:cursor",db_lock_->cursor(NULL,&cur,DB_WRITECURSOR))) return false; Dbt key; Dbt data; make_string(lock_id,key); void* pkey = key.get_data(); if(!dberr("removelock:get1",cur->get(&key,&data,DB_SET))) { // TODO: handle errors ::free(pkey); cur->close(); return false; }; for(;;) { std::string id; std::string owner; uint32_t size = data.get_size(); void* buf = data.get_data(); buf = parse_string(id,buf,size); buf = parse_string(owner,buf,size); ids.push_back(std::pair<std::string,std::string>(id,owner)); if(!dberr("removelock:del",cur->del(0))) { ::free(pkey); cur->close(); return false; }; if(!dberr("removelock:get2",cur->get(&key,&data,DB_NEXT_DUP))) break; }; db_lock_->sync(0); ::free(pkey); cur->close(); return true; }
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); }
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); }
static void parse_record(std::string& uid, std::string& id, std::string& owner, std::list<std::string>& meta, const Dbt& key, const Dbt& data) { uint32_t size = 0; void* d = NULL; d = (void*)key.get_data(); size = (uint32_t)key.get_size(); d = parse_string(id,d,size); d = parse_string(owner,d,size); d = (void*)data.get_data(); size = (uint32_t)data.get_size(); d = parse_string(uid,d,size); for(;size;) { std::string s; d = parse_string(s,d,size); meta.push_back(s); }; }
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__); } } }
std::set<std::string> ClicDb::get(const std::string& usr) { Dbt key(const_cast<char*>(usr.c_str()), usr.size()); Dbt value; if (db.get(NULL, &key, &value, 0) == DB_NOTFOUND) return std::set<std::string>(); std::string str((char*)value.get_data(), value.get_size()); std::set<std::string> result; boost::algorithm::split(result, str, boost::algorithm::is_any_of("\t")); return result; }
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; }
std::set<std::string> ClicDb::get(const std::string& usr) { Dbt key(const_cast<char*>(usr.c_str()), usr.size()); Dbt value; if (db.get(NULL, &key, &value, 0) == DB_NOTFOUND) return std::set<std::string>(); std::string str((char*)value.get_data(), value.get_size()); std::set<std::string> res; for (const auto &i : split(str, '\t')) res.insert(i); return res; }
void Freeze::handleDbException(const DbException& dx, Key& key, Dbt& dbKey, Value& value, Dbt& dbValue, const char* file, int line) { bool bufferSmallException = #if (DB_VERSION_MAJOR == 4) && (DB_VERSION_MINOR == 2) (dx.get_errno() == ENOMEM); #else (dx.get_errno() == DB_BUFFER_SMALL || dx.get_errno() == ENOMEM); #endif bool resized = false; if(bufferSmallException) { if(dbKey.get_size() > dbKey.get_ulen()) { size_t oldKeySize = key.size(); key.resize(dbKey.get_size()); initializeOutDbt(key, dbKey); dbKey.set_size(static_cast<u_int32_t>(oldKeySize)); resized = true; } if(dbValue.get_size() > dbValue.get_ulen()) { value.resize(dbValue.get_size()); initializeOutDbt(value, dbValue); resized = true; } } if(!resized) { handleDbException(dx, file, line); } }
bool DbMultipleDataIterator::next(Dbt &data) { if (*p_ == (u_int32_t)-1) { data.set_data(0); data.set_size(0); p_ = 0; } else { data.set_data(data_ + *p_--); data.set_size(*p_--); if (data.get_size() == 0 && data.get_data() == data_) data.set_data(0); } return (data.get_data() != 0); }
void getWord(const std::string & word, unsigned int & good_count, unsigned int & bad_count) { Dbt key(const_cast<void *>(reinterpret_cast<const void *>(word.c_str())), word.size()); Dbt data; BayesDBData bdata; good_count = 0; bad_count = 0; if(db.get(NULL, &key, &data, 0) != DB_NOTFOUND) { int s = data.get_size(); if(s != sizeof(bdata)) throw std::runtime_error("Bayesian DB returned wrong record size"); void * vdata = data.get_data(); memcpy((void *)&bdata, vdata, s); good_count = bdata.good_edits; bad_count = bdata.bad_edits; } }
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); }
void* BDBFile::readFirstRec(void* key_, unsigned int keySize_) { assert(dbHandle != NULL && dbCursor != NULL); Dbt key; Dbt data; int rtrnCode = dbCursor->get(&key, &data, DB_FIRST); if (rtrnCode > 0) { key_ = NULL; keySize_ = 0; return NULL; } else { key_ = key.get_data(); keySize_ = key.get_size(); return data.get_data(); } }
void* BDBFile::readLastRec(void* key_, unsigned int keySize_) { assert(dbHandle != NULL); Dbt key; Dbt data; int rtrnCode = this->cursorRead(key, data, DB_LAST); if (rtrnCode > 0) { key_ = NULL; keySize_ = 0; return NULL; } else { key_ = key.get_data(); keySize_ = key.get_size(); return data.get_data(); } }
bool FileRecord::ListLocks(std::list<std::string>& locks) { if(!valid_) return false; Glib::Mutex::Lock lock(lock_); Dbc* cur = NULL; if(db_lock_->cursor(NULL,&cur,0)) return false; for(;;) { Dbt key; Dbt data; if(cur->get(&key,&data,DB_NEXT_NODUP) != 0) break; // TODO: handle errors std::string str; uint32_t size = key.get_size(); parse_string(str,key.get_data(),size); locks.push_back(str); }; cur->close(); return true; }
/* Adds a single word pertinent to a single edit */ void addWord(const std::string & word, bool is_bad) { Dbt key(const_cast<void *>(reinterpret_cast<const void *>(word.c_str())), word.size()); Dbt data; BayesDBData bdata; if(db.get(NULL, &key, &data, 0) != DB_NOTFOUND) { int s = data.get_size(); if(s != sizeof(bdata)) throw std::runtime_error("Bayesian DB returned wrong record size"); void * vdata = data.get_data(); memcpy((void *)&bdata, vdata, s); } if(is_bad) { bdata.bad_edits++; } else { bdata.good_edits++; } data.set_data((void *)&bdata); data.set_size(sizeof(bdata)); db.put(NULL, &key, &data, 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(); };
//############################################################################## //############################################################################## std::string BerkeleyDBCXXDb::get_record(record_type type, const std::string& key) const { RANGE_LOG_TIMED_FUNCTION(); std::string fullkey = key_name(type, key); auto txn = current_txn_.lock(); if(txn) { std::string data; if(txn->get_record(type, key, data)) { return data; } } auto lck = boost::dynamic_pointer_cast<BerkeleyDBCXXLock>(this->read_lock(type, key)); DbTxn * dbtxn = BerkeleyDBCXXLockTxnGetter(lck).txn(); Dbt dbkey { (void*) fullkey.c_str(), (uint32_t) fullkey.size() }; size_t bufsize = 131072; std::unique_ptr<char[]> buf { nullptr }; Dbt dbdata; int dbrval = 0; do { if(buf) { LOG(debug0, "resizing_record_buffer") << bufsize; } buf = std::unique_ptr<char[]>(new char[bufsize]); if(!buf) { std::stringstream s; s << "Unable to allocate buffer of size: " << bufsize; THROW_STACK(DatabaseEnvironmentException(s.str())); } dbdata = Dbt(buf.get(), bufsize); dbdata.set_ulen(bufsize); dbdata.set_flags(DB_DBT_USERMEM); bufsize *= 2; int flags = lck->readonly() ? 0 : DB_RMW; try { dbrval = inst_->get(dbtxn, &dbkey, &dbdata, flags); } catch (DbException &e) { if(e.get_errno() == DB_BUFFER_SMALL) { continue; } THROW_STACK(DatabaseEnvironmentException(std::string("Unable to read record") + e.what())); } catch (std::exception &e) { THROW_STACK(DatabaseEnvironmentException(std::string("Unable to read record") + e.what())); } } while(dbrval == DB_BUFFER_SMALL); switch(dbrval) { case 0: break; case DB_NOTFOUND: return std::string(); case DB_BUFFER_SMALL: THROW_STACK(DatabaseEnvironmentException("The requested item could not be returned due to undersized buffer.")); break; case DB_LOCK_DEADLOCK: THROW_STACK(DatabaseEnvironmentException("A transactional database environment operation was selected to resolve a deadlock.")); break; case DB_LOCK_NOTGRANTED: THROW_STACK(DatabaseEnvironmentException("unable to grant a lock in the allowed time.")); break; case DB_REP_HANDLE_DEAD: THROW_STACK(DatabaseEnvironmentException("Dead handle")); break; default: LOG(error, "unknown dbrval") << dbrval; } std::string rval { (char *) dbdata.get_data(), dbdata.get_size() }; return rval; }
DbMultipleIterator::DbMultipleIterator(const Dbt &dbt) : data_((u_int8_t*)dbt.get_data()), p_((u_int32_t*)(data_ + dbt.get_size() - sizeof(u_int32_t))) { }
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(); } }
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; }
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; }
const Freeze::Key* Freeze::IteratorHelperI::get() const { size_t keySize = _key.size(); if(keySize < 1024) { keySize = 1024; } _key.resize(keySize); Dbt dbKey; initializeOutDbt(_key, dbKey); // // 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; if(_indexed) { // // Not interested in getting the index's key // Dbt iKey; iKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL); err = _dbc->pget(&iKey, &dbKey, &dbValue, DB_CURRENT); } else { err = _dbc->get(&dbKey, &dbValue, DB_CURRENT); } if(err == 0) { _key.resize(dbKey.get_size()); return &_key; } else if(err == DB_KEYEMPTY) { throw InvalidPositionException(__FILE__, __LINE__); } 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__); } } }