Ejemplo n.º 1
0
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);
    }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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();
};
Ejemplo n.º 5
0
 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;
 }
Ejemplo n.º 6
0
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);
};
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
0
  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);
    };
  }
Ejemplo n.º 10
0
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__);
        }
    }
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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);
    }
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
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;
     }
 }
Ejemplo n.º 17
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);
}
Ejemplo n.º 18
0
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();
  }
}
Ejemplo n.º 19
0
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();
  }
}
Ejemplo n.º 20
0
 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;
 }
Ejemplo n.º 21
0
 /* 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);
 }
Ejemplo n.º 22
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();
};
Ejemplo n.º 23
0
//##############################################################################
//##############################################################################
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;
}
Ejemplo n.º 24
0
DbMultipleIterator::DbMultipleIterator(const Dbt &dbt)
 : data_((u_int8_t*)dbt.get_data()),
   p_((u_int32_t*)(data_ + dbt.get_size() - sizeof(u_int32_t)))
{
}
Ejemplo n.º 25
0
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();
    }
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
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__);
        }
    }
}