Ejemplo n.º 1
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.º 2
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.º 3
0
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)));
}
Ejemplo n.º 4
0
void JabberBotSession::Status(const std::string *from, MessageStanza::MessageTypes type, const std::string *id) {
  std::string account_id, resource;
  split_identifier(from, account_id, resource);
  char keyValue[account_id.size()+1];
  account_id.copy(keyValue, std::string::npos);
  keyValue[account_id.size()] = '\0';
  time_t last = 0;

  Dbt key(keyValue, account_id.size()+1);
  Dbt data;
  data.set_data(&last);
  data.set_ulen(sizeof(time_t));
  int result = m_subscriptionDb.get(NULL, &key, &data, 0);

  MessageStanza message;
  message.Type(type);
  message.To(from);
  message.Thread(id);
  if (0 != result) {
    message.Body("You are not subscribed");
  }
  else {
    message.Body("You are subscribed");
  }
  m_session->SendMessage(message, false);
}
Ejemplo n.º 5
0
/**
 * 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, &currentData, 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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
void operator<<(Dbt& dbt, const T& obj)
{
  QByteArray ba;
  QDataStream ds(&ba, QIODevice::WriteOnly);

  // Serialize the object
  ds << obj;

  dbt.set_ulen(ba.size());
  dbt.set_data(ba.data());
}
Ejemplo n.º 11
0
 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;
 };
Ejemplo n.º 12
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);
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
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.º 16
0
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;
}
Ejemplo n.º 17
0
/* Bulk delete from a secondary db. */
void BulkExample::bulkSecondaryDelete(
    int num, int pair, int *countp, int *iterp, int verbose)
{
	Dbt key;
	DbTxn *txnp;
	DbMultipleDataBuilder *ptrd;
	DbMultipleKeyDataBuilder *ptrkd;
	u_int32_t flag;
	int count, i, iter, j, k, rc, ret;
	char ch;

	memset(&key, 0, sizeof(Dbt));
	txnp = NULL;
	count = flag = iter = ret = 0;
	rc = rand() % (STRLEN - 1);

	/*
	 * The buffer must be at least as large as the page size of the
	 * underlying database and aligned for unsigned integer access.
	 * Its size must be a multiple of 1024 bytes.
	 */
	if (klen != (u_int32_t)UPDATES_PER_BULK_PUT *
	    (sizeof(u_int32_t) + DATALEN) * 1024) {
		klen = (u_int32_t)UPDATES_PER_BULK_PUT *
		    (sizeof(u_int32_t) + DATALEN) * 1024;
		kbuf = realloc(kbuf, klen);
	}
	memset(kbuf, 0, klen);
	key.set_ulen(klen);
	key.set_flags(DB_DBT_USERMEM | DB_DBT_BULK);
	key.set_data(kbuf);

	/*
	 * Bulk delete all records of a specific set of keys which includes all
	 * characters before the random key in the tstring. The random key is
	 * one of the characters in the tstring.
	 * If DB_MULTIPLE, construct the key Dbt by the DbMultipleDataBuilder
	 * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key
	 * Dbt by the DbMultipleKeyDataBuilder with all key/data pairs of the
	 * specific set of keys.
	 */
	flag |= (pair) ? DB_MULTIPLE_KEY : DB_MULTIPLE;
	if (pair)
		ptrkd = new DbMultipleKeyDataBuilder(key);
	else
		ptrd = new DbMultipleDataBuilder(key);
	try {
		for (i = 0; i <= rc; i++) {
			if (i % UPDATES_PER_BULK_PUT == 0) {
				if (txnp != NULL) {
					ret = txnp->commit(0);
					txnp = NULL;
					if (ret != 0)
						throwException(dbenv, NULL,
						    ret, "DB_TXN->commit");
				}
				if ((ret = dbenv->txn_begin(NULL,
				    &txnp, 0)) != 0)
					throwException(dbenv,
					    NULL, ret, "DB_ENV->txn_begin");
			}

			ch = tstring[i];
			if (!pair) {
				if (ptrd->append(&ch, sizeof(ch)) == false)
					throwException(dbenv,
					    txnp, EXIT_FAILURE,
					    "DbMultipleDataBuilder->append");
				count++;
				if (verbose)
					printf("Delete key: %c\n", ch);
			} else {
				j = 0;
				do {
					k = j * (STRLEN - 1) + i;
					if (ptrkd->append(&ch, sizeof(ch),
					    &k, sizeof(k)) == false)
						throwException(dbenv,
						    txnp, EXIT_FAILURE,
"DbMultipleKeyDataBuilder->append");
					count++;
					if (verbose)
						printf(
"Delete secondary key: %c, \tdata: %d\n", 
						    ch, k);
				} while (++j < (int)(num / (STRLEN - 1)));
			}

			if ((i + 1) % UPDATES_PER_BULK_PUT == 0) {
				if ((ret = sdbp->del(txnp, &key, flag)) != 0)
					throwException(dbenv,
					    txnp, ret, "Bulk DB->del");
				iter++;
				if (pair)
					ptrkd = new
					    DbMultipleKeyDataBuilder(key);
				else
					ptrd = new DbMultipleDataBuilder(key);
			}
		}
		if ((rc % UPDATES_PER_BULK_PUT) != 0) {
			if ((ret = sdbp->del(txnp, &key, flag)) != 0)
				throwException(dbenv,
				    txnp, ret, "Bulk DB->del");
			iter++;
		}

		ret = txnp->commit(0);
		txnp = NULL;
		if (ret != 0)
			throwException(dbenv, NULL, ret, "DB_TXN->commit");

		*countp = count;
		*iterp = iter;
	} catch (DbException &dbe) {
		cerr << "bulkSecondaryDelete " << dbe.what() << endl;
		if (txnp != NULL)
			(void)txnp->abort();
		throw dbe;
	}
}
Ejemplo n.º 18
0
/* Bulk delete from a database. */
void BulkExample::bulkDelete(
    int num, int dups, int *countp, int *iterp, int verbose)
{
	Dbt key;
	DbTxn *txnp;
	DbMultipleDataBuilder *ptrd;
	DbMultipleKeyDataBuilder *ptrkd;
	u_int32_t flag;
	int count, i, j, iter, ret;

	txnp = NULL;
	count = flag = iter = ret = 0;
	memset(&key, 0, sizeof(Dbt));

	j = rand() % num;

	/*
	 * The buffer must be at least as large as the page size of the
	 * underlying database and aligned for unsigned integer access.
	 * Its size must be a multiple of 1024 bytes.
	 */
	if (klen != (u_int32_t)UPDATES_PER_BULK_PUT *
	    (sizeof(u_int32_t) + DATALEN) * 1024) {
		klen = (u_int32_t)UPDATES_PER_BULK_PUT *
		    (sizeof(u_int32_t) + DATALEN) * 1024;
		kbuf = realloc(kbuf, klen);
	}
	memset(kbuf, 0, klen);
	key.set_ulen(klen);
	key.set_flags(DB_DBT_USERMEM | DB_DBT_BULK);
	key.set_data(kbuf);
	if (data_val == NULL)
		data_val = (data *)malloc(DATALEN);
	memset(data_val, 0, DATALEN);

	/*
	 * Bulk delete all records of a specific set of keys which includes all
	 * non-negative integers smaller than the random key. The random key is
	 * a random non-negative integer smaller than "num".
	 * If DB_MULTIPLE, construct the key Dbt by the DbMultipleDataBuilder
	 * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key
	 * Dbt by the DbMultipleKeyDataBuilder with all key/data pairs of the
	 * specific set of keys.
	 */
	flag |= (dups) ? DB_MULTIPLE_KEY : DB_MULTIPLE;
	if (dups)
		ptrkd = new DbMultipleKeyDataBuilder(key);
	else
		ptrd = new DbMultipleDataBuilder(key);
	try {
		for (i = 0; i < j; i++) {
			if (i % UPDATES_PER_BULK_PUT == 0) {
				if (txnp != NULL) {
					ret = txnp->commit(0);
					txnp = NULL;
					if (ret != 0)
						throwException(dbenv, NULL,
						    ret, "DB_TXN->commit");
				}
				if ((ret = dbenv->txn_begin(NULL,
				    &txnp, 0)) != 0)
					throwException(dbenv, NULL,
					    ret, "DB_ENV->txn_begin");
			}

			if (dups) {
				data_val->id = 0;
				get_string(tstring, data_val->str, i);
				do {
					if(ptrkd->append(&i,sizeof(i),
					    data_val, DATALEN) == false)
						throwException(dbenv,
						    txnp, EXIT_FAILURE,
"DbMultipleKeyDataBuilder->append");
					count++;
					if (verbose)
						printf(
"Delete key: %d, \tdata: (id %d, str %s)\n",
						    i, data_val->id,
						    data_val->str);
				} while (data_val->id++ < dups);
			} else {
				if(ptrd->append(&i,sizeof(i)) == false)
					throwException(dbenv, txnp, ret,
					    "DbMultipleDataBuilder->append");
				count++;
				if (verbose)
					printf("Delete key: %d\n", i);
			}

			if ((i + 1) % UPDATES_PER_BULK_PUT == 0) {
				if ((ret = dbp->del(txnp, &key, flag)) != 0)
					throwException(dbenv,
					    txnp, ret, "Bulk DB->del");
				iter++;
				if (dups)
					ptrkd = new
					    DbMultipleKeyDataBuilder(key);
				else
					ptrd = new DbMultipleDataBuilder(key);
			}
		}
		if ((j % UPDATES_PER_BULK_PUT) != 0) {
			if ((ret = dbp->del(txnp, &key, flag)) != 0)
				throwException(dbenv,
				    txnp, ret, "Bulk DB->del");
			iter++;
		}

		ret = txnp->commit(0);
		txnp = NULL;
		if (ret != 0)
			throwException(dbenv, NULL, ret, "DB_TXN->commit");

		*countp = count;
		*iterp = iter;
	} catch (DbException &dbe) {
		cerr << "bulkDelete " << dbe.what() << endl;
		if (txnp != NULL)
			(void)txnp->abort();
		throw dbe;
	}
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
int main(int argc, const char* argv[]) {

  if (argc !=3) {
      cout << "usage: "<< argv[0] << " <filename> <db filename>" << endl;
      return 1;
  }

  const char* kDatabaseName = argv[2];
  const char* filename = argv[1];

  DbEnv env(0);
  Db* pdb;

  string line;

  bool datamode = false;

  try {

    env.set_error_stream(&cerr);
    env.open("./", DB_CREATE | DB_INIT_MPOOL, 0);

    pdb = new Db(&env, 0);
    // If you want to support duplicated records and make duplicated
    // records sorted by data, you need to call:
    //   pdb->set_flags(DB_DUPSORT);
    // Note that only Btree-typed database supports sorted duplicated
    // records

    // If the database does not exist, create it.  If it exists, clear
    // its content after openning.
    pdb->set_flags( DB_DUP );// | DB_DUPSORT);
    pdb->open(NULL, kDatabaseName, NULL, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0);


    ifstream myfile (filename);
    if (myfile.is_open()) {
        int count = 0;
        while ( myfile.good() ) {
            //if (count++ > 10) {
            //    break;
            //} 
            getline (myfile,line);
            if (!datamode) {
                if ("[DATA]" == line ) {
                    datamode = true;
                }
                continue;
            }
            //cout << (int)line[8]  << endl;
            int index = 0;
            while (32 != (char)line[index]) {
                index++;
            }
            string cjkey = line.substr(0, index);
            while (32 == line[index]) {
                index++;
            }
            string cjdata = line.substr(index, (line.size()-index));
            cout << cjkey << "---" << cjdata << endl;
            Dbt key(const_cast<char*>(cjkey.data()), cjkey.size());
            Dbt value(const_cast<char*>(cjdata.data()), cjdata.size());
            pdb->put(NULL, &key, &value, 0);
        }
        myfile.close();
    } else { 
        cout << "Unable to open file";  
    }


    // You need to set ulen and flags=DB_DBT_USERMEM to prevent Dbt
    // from allocate its own memory but use the memory provided by you.
    string search("aa");
    Dbt key(const_cast<char*>(search.c_str()), search.size());
    char buffer[1024];
    Dbt data;
    data.set_data(buffer);
    data.set_ulen(1024);
    data.set_flags(DB_DBT_USERMEM);
    if (pdb->get(NULL, &key, &data, 0) == DB_NOTFOUND) {
      cerr << "Not found" << endl;
    } else {
      cout << "Found: " << "PPPPPP" <<buffer << "PPPPPP" << endl;
    }

    if (pdb != NULL) {
      pdb->close(0);
      delete pdb;
      // You have to close and delete an exisiting handle, then create
      // a new one before you can use it to remove a database (file).
      pdb = new Db(NULL, 0);
      //pdb->remove("access.db", NULL, 0);
      delete pdb;
    }
    env.close(0);

  } catch (DbException& e) {
    cerr << "DbException: " << e.what() << endl;
    return -1;
  } catch (std::exception& e) {
    cerr << e.what() << endl;
    return -1;
  }

  return 0;
}
Ejemplo n.º 21
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;
}