Пример #1
0
JabberBotSession::JabberBotSession(const std::string &host, unsigned short port, bool isSecure, const std::string &userid, const std::string &password, const std::string &resource, const std::string &email, const std::string &affirmation_path, const std::string &db_path) : m_subscriptionDb(NULL, 0) {
  openlog("affirmations-bot", LOG_PID|LOG_CONS, LOG_DAEMON);

  Dbc *cursor;
  m_subscriptionDb.open(NULL, db_path.c_str(), NULL, DB_BTREE, DB_CREATE, 0);

  m_subscriptionDb.cursor(NULL, &cursor, 0);
  if (NULL != cursor) {
    Dbt key, data;
    time_t now = time(NULL);
    time_t bod = now - (now % 86400);
    m_eod = bod + 86400;

    while (0 == cursor->get(&key, &data, DB_NEXT)) {
      std::string user((char *)key.get_data());
      time_t last = *((time_t*) data.get_data());
      if (last < bod) {
	// He hasn't gotten an affirmation today
	time_t t1 = random() % ((m_eod - now)/2);
	time_t t2 = random() % ((m_eod - now)/2);
	
	Upcoming newEntry(user, now + t1 + t2);
	m_upcomingQueue.push(newEntry);
      }
      std::ostringstream message;
      message << "User " << user << " last got an affirmation at " << last;
      syslog(LOG_NOTICE, message.str().c_str());
    }
    cursor->close();
  }

  if (m_handlers.begin() == m_handlers.end()) {
    CommandHandler handler;
    handler.method = &JabberBotSession::Subscribe;
    m_handlers.insert(CommandHandlerMap::value_type("subscribe", handler));
    handler.method = &JabberBotSession::Unsubscribe;
    m_handlers.insert(CommandHandlerMap::value_type("unsubscribe", handler));
    handler.method = &JabberBotSession::Affirmation;
    m_handlers.insert(CommandHandlerMap::value_type("affirmation", handler));
    handler.method = &JabberBotSession::Status;
    m_handlers.insert(CommandHandlerMap::value_type("status", handler));
  }
  if (m_affirmations.empty()) {
    srand(time(NULL));
    std::string line;

    std::ifstream a(affirmation_path.c_str());
    while (getline(a, line)) { 
      std::ostringstream message;
      message << "The line is \"" << line << "\"" << std::endl;
      syslog(LOG_DEBUG, message.str().c_str());
      m_affirmations.push_back(line);
    }
  }

  m_session = new JabberSession(host, port, isSecure);

  // SYZYGY
  m_session->Register(this, HandlePresenceRequest);
  m_session->Register(this, HandleMessageRequest);
  m_session->Register(this, HandlePingRequest, "urn:xmpp:ping");
  JabberIqAuth login_stanza(userid, password, resource);
  const Stanza *response = m_session->SendMessage(login_stanza, true);
  std::ostringstream message;
  message << "The first login response is " << *(response->render(NULL)) << std::endl;
  syslog(LOG_DEBUG, message.str().c_str());
  if (200 != response->Error()) {
    message << "The first login response is " << response->ErrorMessage() << std::endl;
    syslog(LOG_NOTICE, message.str().c_str());
    JabberIqRegister register_stanza(userid, password, email);
    response = m_session->SendMessage(register_stanza, true);
    message << "The register response is " << *(response->render(NULL)) << std::endl;
    syslog(LOG_NOTICE, message.str().c_str());
    if (200 != response->Error()) {
      message << "The register response is " << response->ErrorMessage() << std::endl;
      syslog(LOG_NOTICE, message.str().c_str());
    }
    else {
      JabberIqAuth login2_stanza(userid, password, resource);
      response = m_session->SendMessage(login2_stanza, true);
      message << "The second login response is " << *(response->render(NULL)) << std::endl;
      syslog(LOG_NOTICE, message.str().c_str());
      if (200 != response->Error()) {
	message << "The second login failed with a message of " << response->ErrorMessage() << std::endl;
	syslog(LOG_NOTICE, message.str().c_str());
      }
    }
  }
  delete response;

  m_id = 0;
  m_continueRunning = true;
}
Пример #2
0
void TestKeyRange::run()
{
	// Remove the previous database.
	(void)unlink(FileName);

	// Create the database object.
	// There is no environment for this simple example.
	Db db(0, 0);

	db.set_error_stream(&cerr);
	db.set_errpfx("TestKeyRange");
	db.set_pagesize(1024);		/* Page size: 1K. */
	db.set_cachesize(0, 32 * 1024, 0);
	db.open(NULL, FileName, NULL, DB_BTREE, DB_CREATE, 0664);

	//
	// Insert records into the database, where the key is the user
	// input and the data is the user input in reverse order.
	//
	char buf[1024];
	char rbuf[1024];
	char *t;
	char *p;
	int ret;
	int len;
	Dbt *firstkey = NULL;
	char firstbuf[1024];

	for (;;) {
		cout << "input>";
		cout.flush();

		cin.getline(buf, sizeof(buf));
		if (cin.eof())
			break;

		if ((len = strlen(buf)) <= 0)
			continue;
		for (t = rbuf, p = buf + (len - 1); p >= buf;)
			*t++ = *p--;
		*t++ = '\0';

		Dbt key(buf, len + 1);
		Dbt data(rbuf, len + 1);
		if (firstkey == NULL) {
			strcpy(firstbuf, buf);
			firstkey = new Dbt(firstbuf, len + 1);
		}

		ret = db.put(0, &key, &data, DB_NOOVERWRITE);
		if (ret == DB_KEYEXIST) {
			cout << "Key " << buf << " already exists.\n";
		}
		cout << "\n";
	}

	// We put a try block around this section of code
	// to ensure that our database is properly closed
	// in the event of an error.
	//
	try {
		// Acquire a cursor for the table.
		Dbc *dbcp;
		db.cursor(NULL, &dbcp, 0);

		/*ADDED...*/
		DB_KEY_RANGE range;
		memset(&range, 0, sizeof(range));

		db.key_range(NULL, firstkey, &range, 0);
		printf("less: %f\n", range.less);
		printf("equal: %f\n", range.equal);
		printf("greater: %f\n", range.greater);
		/*end ADDED*/

		Dbt key;
		Dbt data;

		// Walk through the table, printing the key/data pairs.
		while (dbcp->get(&key, &data, DB_NEXT) == 0) {
			char *key_string = (char *)key.get_data();
			char *data_string = (char *)data.get_data();
			cout << key_string << " : " << data_string << "\n";
		}
		dbcp->close();
	}
	catch (DbException &dbe) {
		cerr << "TestKeyRange: " << dbe.what() << "\n";
	}

	db.close(0);
}
Пример #3
0
bool Table::VisitBackward(TableVisitor &tv)
{
	ByteString bsKey, bsValue;
	Dbc* cursor = NULL;
	bool ret = true;
	u_int32_t flags = DB_PREV;

	// TODO call tv.OnComplete() or error handling
	if (db->cursor(NULL, &cursor, 0) != 0)
		return false;
	
	Dbt key, value;
	if (tv.GetStartKey() && tv.GetStartKey()->length > 0)
	{
		key.set_data(tv.GetStartKey()->buffer);
		key.set_size(tv.GetStartKey()->length);
		flags = DB_SET_RANGE;		

		// as DB_SET_RANGE finds the smallest key greater than or equal to the
		// specified key, in order to visit the database backwards, move to the
		// first matching elem, then move backwards
		if (cursor->get(&key, &value, flags) != 0)
		{
			// end of database
			cursor->close();
			if (db->cursor(NULL, &cursor, 0) != 0)
				return false;
		}
		else
		{
			// if there is a match, call the acceptor, otherwise move to the
			// previous elem in the database
			if (memcmp(tv.GetStartKey()->buffer, key.get_data(),
				MIN(tv.GetStartKey()->length, key.get_size())) == 0)
			{
				bsKey.size = key.get_size();
				bsKey.length = key.get_size();
				bsKey.buffer = (char*) key.get_data();
				
				bsValue.size = value.get_size();
				bsValue.length = value.get_size();
				bsValue.buffer = (char*) value.get_data();

				ret = tv.Accept(bsKey, bsValue);
			}
		}
	}
		
	flags = DB_PREV;
	while (ret && cursor->get(&key, &value, flags) == 0)
	{
		bsKey.size = key.get_size();
		bsKey.length = key.get_size();
		bsKey.buffer = (char*) key.get_data();
		
		bsValue.size = value.get_size();
		bsValue.length = value.get_size();
		bsValue.buffer = (char*) value.get_data();

		ret = tv.Accept(bsKey, bsValue);
		if (!ret)
			break;

		flags = DB_PREV;
	}
	
	cursor->close();	
	tv.OnComplete();
	
	return ret;

}
Пример #4
0
bool CDB::Rewrite(const string& strFile, const char* pszSkip)
{
    while (true)
    {
        {
            LOCK(bitdb.cs_db);
            if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
            {
                // Flush log data to the dat file
                bitdb.CloseDb(strFile);
                bitdb.CheckpointLSN(strFile);
                bitdb.mapFileUseCount.erase(strFile);

                bool fSuccess = true;
                printf("Rewriting %s...\n", strFile.c_str());
                string strFileRes = strFile + ".rewrite";
                { // surround usage of db with extra {}
                    CDB db(strFile.c_str(), "r");
                    Db* pdbCopy = new Db(&bitdb.dbenv, 0);

                    int ret = pdbCopy->open(NULL,                 // Txn pointer
                                            strFileRes.c_str(),   // Filename
                                            "main",    // Logical db name
                                            DB_BTREE,  // Database type
                                            DB_CREATE,    // Flags
                                            0);
                    if (ret > 0)
                    {
                        printf("Cannot create database file %s\n", strFileRes.c_str());
                        fSuccess = false;
                    }

                    Dbc* pcursor = db.GetCursor();
                    if (pcursor)
                        while (fSuccess)
                        {
                            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }
                            if (pszSkip &&
                                strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
                                continue;
                            if (strncmp(&ssKey[0], "\x07version", 8) == 0)
                            {
                                // Update version:
                                ssValue.clear();
                                ssValue << CLIENT_VERSION;
                            }
                            Dbt datKey(&ssKey[0], ssKey.size());
                            Dbt datValue(&ssValue[0], ssValue.size());
                            int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
                            if (ret2 > 0)
                                fSuccess = false;
                        }
                    if (fSuccess)
                    {
                        db.Close();
                        bitdb.CloseDb(strFile);
                        if (pdbCopy->close(0))
                            fSuccess = false;
                        delete pdbCopy;
                    }
                }
                if (fSuccess)
                {
                    Db dbA(&bitdb.dbenv, 0);
                    if (dbA.remove(strFile.c_str(), NULL, 0))
                        fSuccess = false;
                    Db dbB(&bitdb.dbenv, 0);
                    if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
                        fSuccess = false;
                }
                if (!fSuccess)
                    printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
                return fSuccess;
            }
        }
        MilliSleep(100);
    }
    return false;
}
Пример #5
0
static void
transformDb(bool evictor,  const Ice::CommunicatorPtr& communicator,
            const FreezeScript::ObjectFactoryPtr& objectFactory,
            DbEnv& dbEnv, DbEnv& dbEnvNew, const string& dbName, 
            const Freeze::ConnectionPtr& connectionNew, vector<Db*>& dbs,
            const Slice::UnitPtr& oldUnit, const Slice::UnitPtr& newUnit, 
            DbTxn* txnNew, bool purgeObjects, bool suppress, string descriptors)
{
    if(evictor)
    {
        //
        // The evictor database file contains multiple databases. We must first
        // determine the names of those databases, ignoring any whose names
        // begin with "$index:". Each database represents a separate facet, with
        // the facet name used as the database name. The database named "$default"
        // represents the main object.
        //
        vector<string> dbNames;
        {
            Db db(&dbEnv, 0);
            db.open(0, dbName.c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0);
            Dbt dbKey, dbValue;
            dbKey.set_flags(DB_DBT_MALLOC);
            dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);
            
            Dbc* dbc = 0;
            db.cursor(0, &dbc, 0);
            
            while(dbc->get(&dbKey, &dbValue, DB_NEXT) == 0)
            {
                string s(static_cast<char*>(dbKey.get_data()), dbKey.get_size());
                if(s.find("$index:") != 0)
                {
                    dbNames.push_back(s);
                }
                free(dbKey.get_data());
            }
            
            dbc->close();
            db.close(0);
        }
        
        //
        // Transform each database. We must delay closing the new databases
        // until after the transaction is committed or aborted.
        //
        for(vector<string>::iterator p = dbNames.begin(); p != dbNames.end(); ++p)
        {
            string name = p->c_str();
            
            Db db(&dbEnv, 0);
            db.open(0, dbName.c_str(), name.c_str(), DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE);
            
            Db* dbNew = new Db(&dbEnvNew, 0);
            dbs.push_back(dbNew);
            dbNew->open(txnNew, dbName.c_str(), name.c_str(), DB_BTREE, DB_CREATE | DB_EXCL, FREEZE_SCRIPT_DB_MODE);
            
            //
            // Execute the transformation descriptors.
            //
            istringstream istr(descriptors);
            string facet = (name == "$default" ? string("") : name);
            FreezeScript::transformDatabase(communicator, objectFactory, oldUnit, newUnit, &db, dbNew, txnNew, 0,
                                            dbName, facet, purgeObjects, cerr, suppress, istr);
            
            db.close(0);
        }
        
        Freeze::Catalog catalogNew(connectionNew, Freeze::catalogName());
        Freeze::CatalogData catalogData = { true, "::Ice::Identity", "Object" };
        catalogNew.put(Freeze::Catalog::value_type(dbName, catalogData));
    }
    else
    {
        //
        // Transform a map database.
        //
        Db db(&dbEnv, 0);
        db.open(0, dbName.c_str(), 0, DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE);
        
        Db* dbNew = new Db(&dbEnvNew, 0);
        dbs.push_back(dbNew);
        dbNew->open(txnNew, dbName.c_str(), 0, DB_BTREE, DB_CREATE | DB_EXCL, FREEZE_SCRIPT_DB_MODE);
        
        //
        // Execute the transformation descriptors.
        //
        istringstream istr(descriptors);
        FreezeScript::transformDatabase(communicator, objectFactory, oldUnit, newUnit, &db, dbNew, txnNew,
                                        connectionNew, dbName, "", purgeObjects, cerr, suppress, istr);
        
        db.close(0);
    }
}
Пример #6
0
void test1()
{
	int numberOfKeysToWrite= 10000;
	Db db(0,DB_CXX_NO_EXCEPTIONS);
	db.set_pagesize(512);
	int err= db.open(0, "test1.db", 0, DB_BTREE, DB_CREATE, 0);
	{
		int i= 0;
		Dbt key(&i,sizeof(i));
		Dbt data(&i,sizeof(i));
		for(;i<numberOfKeysToWrite;++i)
		{
			db.put(0,&key,&data,0);
		}
	}

	{
		Dbc *dbc;
		err= db.cursor(0,&dbc,0);

		char *check= (char*)calloc(numberOfKeysToWrite,1);
		char buffer[8192];
		int numberOfKeysRead= 0;
		Dbt multikey(&numberOfKeysRead,sizeof(numberOfKeysRead));
		Dbt multidata(&buffer,sizeof(buffer));
		multidata.set_flags(DB_DBT_USERMEM);
		multidata.set_ulen(sizeof(buffer));
		err= 0;
		while(err==0)
		{
			err= dbc->get(&multikey,&multidata,DB_NEXT|DB_MULTIPLE_KEY);
			if(err==0)
			{
				Dbt key, data;
				DbMultipleKeyDataIterator i(multidata);
				while(err==0 && i.next(key,data))
				{
					int actualKey;
					int actualData;
					memmove(&actualKey, key.get_data(), sizeof(actualKey));
					memmove(&actualData, data.get_data(), sizeof(actualData));
					if(actualKey!=actualData)
					{
						std::cout << "Error: key/data mismatch. " << actualKey << "!=" << actualData << std::endl;
						err= -1;
					}
					else
					{
						check[actualKey]++;
					}
					numberOfKeysRead++;
				}
			} else if(err!=DB_NOTFOUND)
				std::cout << "Error: dbc->get: " << db_strerror(err) << std::endl;
		}
		if(numberOfKeysRead!=numberOfKeysToWrite)
		{
			std::cout << "Error: key count mismatch. " << numberOfKeysRead << "!=" << numberOfKeysToWrite << std::endl;
		}
		for(int n=0;n<numberOfKeysToWrite;++n)
		{
			if(check[n]!=1)
			{
				std::cout << "Error: key " << n << " was written to the database, but not read back." << std::endl;
			}
		}
		free(check);
		dbc->close();
	}

	db.close(0);
}
Пример #7
0
void QueueScheduler::loadData(Db* _schedDb, bool createStartup)
{
    Dbc *cursor = 0;
	Dbt key, data;
	uchar *keymem=new uchar[KEYMEM_SIZE];
	uchar *datamem=new uchar[DATAMEM_SIZE];

	key.set_flags(DB_DBT_USERMEM);
	key.set_data(keymem);
	key.set_ulen(KEYMEM_SIZE);

	data.set_flags(DB_DBT_USERMEM);
	data.set_ulen(DATAMEM_SIZE);
	data.set_data(datamem);

	int maxId = 0;

	int ret = 0;

	schedDb = _schedDb;

	schedDb->cursor(0, &cursor, DB_WRITECURSOR);

    QueueSchedule* queueSchedule = 0;

	while (ret == 0)
	{
		if ((ret = cursor->get(&key, &data, DB_NEXT)) == 0)
		{
			// qDebug() << "Just read schedule from Db, key = : " << key.get_data();
			queueSchedule = new QueueSchedule(schedDb, (uchar*)data.get_data(), this);
			queueSchedules.append(queueSchedule);
			currentSchedule = queueSchedule;
			if (queueSchedule->getIsActive())
				enabledSchedules.insert(queueSchedule->getPriority(), queueSchedule);
		}
		else if (ret == DB_BUFFER_SMALL)
		{
			ret = 0;
			qDebug("Insufficient memory");
			qDebug("Size required is: %d", data.get_size());
			uchar *p=datamem;
			datamem=new uchar[data.get_size()+1000];
			data.set_ulen(data.get_size()+1000);
			data.set_data(datamem);
            Q_DELETE_ARRAY(p);
		}
	}

	cursor->close();

	if (createStartup)
	{
		queueSchedule = new QueueSchedule(schedDb, tr("Un-metered"), this);
		queueSchedule->setIsActive(false);
		queueSchedule->setPriority(2);
		queueSchedule->addElement( 480 * 60, (1439 * 60) + 59, 128*1024, 0);
		queueSchedule->addElement(1920 * 60, (2879 * 60) + 59, 128*1024, 0);
		queueSchedule->addElement(3360 * 60, (4319 * 60) + 59, 128*1024, 0);
		queueSchedule->addElement(4800 * 60, (5759 * 60) + 59, 128*1024, 0);
		maxId = queueSchedule->addElement(6240 * 60, (7199 * 60) + 59, 128*1024, 0);
		queueSchedule->setMaxId(maxId);

		queueSchedules.append(queueSchedule);
		currentSchedule = queueSchedule;

		queueSchedule->dbSave();
	}

	managePeriods();

    Q_DELETE_ARRAY(keymem);
    Q_DELETE_ARRAY(datamem);
}
void run_bdb_btree_big(stxxl::int64 n, unsigned ops)
{
    const char * filename = BDB_FILE;

    my_key key1_storage;
    my_data data1_storage;

#ifdef BDB_BULK_SCAN
    int * bulk_buffer = new int[logbufsize / sizeof(int)];
#endif

    unlink(filename);

    memset(key1_storage.keybuf, 'a', KEY_SIZE);
    memset(data1_storage.databuf, 'b', DATA_SIZE);


    Db db(NULL, 0);                   // Instantiate the Db object

    try {
        // here we start with the tests
        Dbt key1(key1_storage.keybuf, KEY_SIZE);
        Dbt data1(data1_storage.databuf, DATA_SIZE);

        stxxl::timer Timer;
        stxxl::int64 n_inserts = ops, n_locates = ops, n_range_queries = ops, n_deletes = ops;
        stxxl::int64 i;
        //comp_type cmp_;

        ran32State = 0xdeadbeef;

        Timer.start();

        vector_type SortedSeq(n);
        //const vector_type & CSortedSeq(SortedSeq);
        {
            rand_key_gen Gen(n, key1_storage);
            typedef stxxl::stream::sort<rand_key_gen, comp_type> sorter_type;
            sorter_type Sorter(Gen, comp_type(), SORTER_MEM);
            typedef key2pair<sorter_type> key2pair_type;
            key2pair_type Key2Pair(Sorter);
            stxxl::stream::materialize(Key2Pair, SortedSeq.begin());
        }

        Timer.stop();

        STXXL_MSG("Finished sorting input. Elapsed time: " << (Timer.mseconds() / 1000.) << " seconds.");

        db.set_errfile(stderr);
        db.set_pagesize(pagesize);
        db.set_cachesize(0, cachesize, 10);

        STXXL_MSG("BDB cache size set.");

        // Open the database
        db.open(NULL,           // Transaction pointer
                filename,       // Database file name
                NULL,           // Optional logical database name
                DB_BTREE,       // Database access method
                DB_CREATE,      // Open flags
                0);             // File mode (using defaults)

        db.get_env()->memp_stat(NULL, NULL, DB_STAT_CLEAR);

        Timer.reset();
        Timer.start();

        // DBD does not have bulk construction
        // however inserting in sorted order might help
        // to improve performance
        vector_type::const_iterator cit = SortedSeq.begin();
        for (i = 0; i < n; ++i, ++cit)
        {
            key1_storage = cit->first;
            db.put(NULL, &key1, &data1, DB_NOOVERWRITE);
        }

        Timer.stop();

        DB_BTREE_STAT * dbstat;
        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);
        STXXL_MSG("Construction elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(n) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.stat_print(0);
        db.get_env()->memp_stat_print(DB_STAT_CLEAR);
        ////////////////////////////////////////


        Timer.reset();
        Timer.start();

        for (i = 0; i < n_inserts; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            db.put(NULL, &key1, &data1, DB_NOOVERWRITE);
        }

        Timer.stop();
        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);
        STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(n_inserts) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.stat_print(0);
        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        /////////////////////////////////////////
        Timer.reset();
        Timer.start();


        Dbc * cursorp;
        db.cursor(NULL, &cursorp, 0);

        for (i = 0; i < n_locates; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
            Dbt datax(data1_storage.databuf, DATA_SIZE);

            cursorp->get(&keyx, &datax, DB_SET_RANGE);
        }

        Timer.stop();
        STXXL_MSG("Locates elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.stat_print(0);
        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        ////////////////////////////////////
        Timer.reset();

        Timer.start();

        stxxl::int64 n_scanned = 0;

        for (i = 0; i < n_range_queries; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            my_key last_key = key1_storage;
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            if (last_key < key1_storage)
                std::swap(last_key, key1_storage);


            //STXXL_MSG("Looking     "<<key1_storage<<" scanned: "<<n_scanned);
            //STXXL_MSG("Upper bound "<<last_key);

            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
#ifdef BDB_BULK_SCAN
            Dbt datax(bulk_buffer, DATA_SIZE);
            datax.set_ulen(logbufsize);
            datax.set_flags(DB_DBT_USERMEM);
#else
            Dbt datax(data1_storage.databuf, DATA_SIZE);
#endif


#ifdef BDB_BULK_SCAN
            if (cursorp->get(&keyx, &datax, DB_SET_RANGE | DB_MULTIPLE_KEY) == DB_NOTFOUND)
                continue;


            do
            {
                DbMultipleKeyDataIterator BulkIterator(datax);
                Dbt key1, data1;
                while (BulkIterator.next(key1, data1) &&
                       *((my_key *)key1.get_data()) <= last_key)
                {
                    ++n_scanned;
                    //STXXL_MSG("Result      "<<*((my_key *)key1.get_data()));
                }
                if (cursorp->get(&keyx, &datax, DB_NEXT | DB_MULTIPLE_KEY) == DB_NOTFOUND)
                    break;


                if (*((my_key *)keyx.get_data()) > last_key)
                {
                    break;
                }
            } while (1);

#else
            if (cursorp->get(&keyx, &datax, DB_SET_RANGE) == DB_NOTFOUND)
                continue;

            while (*((my_key *)keyx.get_data()) <= last_key)
            {
                ++n_scanned;
                if (cursorp->get(&keyx, &datax, DB_NEXT) == DB_NOTFOUND)
                    break;
            }
#endif


            if (n_scanned >= SCAN_LIMIT(n))
            {
                ++i;
                break;
            }
        }

        n_range_queries = i;

        Timer.stop();
        if (cursorp != NULL)
            cursorp->close();


        STXXL_MSG("Range query elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(n_scanned) / (Timer.mseconds() / 1000.)) <<
                  " key/data pairs per sec, #queries " << n_range_queries << " #scanned elements: " << n_scanned);

        db.stat_print(0);
        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        //////////////////////////////////////

        ran32State = 0xdeadbeef;
        memset(key1_storage.keybuf, 'a', KEY_SIZE);

        Timer.reset();
        Timer.start();

        for (i = 0; i < n_deletes; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
            db.del(NULL, &keyx, 0);
        }

        Timer.stop();
        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);
        STXXL_MSG("Erase elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.stat_print(0);
        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        db.close(0);
    }
    catch (DbException & e)
    {
        STXXL_ERRMSG("DbException happened");
    }
    catch (std::exception & e)
    {
        STXXL_ERRMSG("std::exception happened");
    }

    unlink(filename);

#ifdef BDB_BULK_SCAN
    delete[]  bulk_buffer;
#endif
}
Пример #9
0
// Check that key/data for 0 - count-1 are already present,
// and write a key/data for count.  The key and data are
// both "0123...N" where N == count-1.
//
// For some reason on Windows, we need to open using the full pathname
// of the file when there is no environment, thus the 'has_env'
// variable.
//
void rundb(Db *db, int count, int has_env)
{
	const char *name;

	if (has_env)
		name = CONSTRUCT01_DBNAME;
	else
		name = CONSTRUCT01_DBFULLPATH;

	db->set_error_stream(&cerr);

	// We don't really care about the pagesize, but we do want
	// to make sure adjusting Db specific variables works before
	// opening the db.
	//
	CHK(db->set_pagesize(1024));
	CHK(db->open(NULL, name, NULL, DB_BTREE, count ? 0 : DB_CREATE, 0664));

	// The bit map of keys we've seen
	long bitmap = 0;

	// The bit map of keys we expect to see
	long expected = (1 << (count+1)) - 1;

	char outbuf[10];
	int i;
	for (i=0; i<count; i++) {
		outbuf[i] = '0' + i;
	}
	outbuf[i++] = '\0';
	Dbt key(outbuf, i);
	Dbt data(outbuf, i);

	DEBUGOUT("Put: " << outbuf);
	CHK(db->put(0, &key, &data, DB_NOOVERWRITE));

	// Acquire a cursor for the table.
	Dbc *dbcp;
	CHK(db->cursor(NULL, &dbcp, 0));

	// Walk through the table, checking
	Dbt readkey;
	Dbt readdata;
	while (dbcp->get(&readkey, &readdata, DB_NEXT) == 0) {
		char *key_string = (char *)readkey.get_data();
		char *data_string = (char *)readdata.get_data();
		DEBUGOUT("Got: " << key_string << ": " << data_string);
		int len = strlen(key_string);
		long bit = (1 << len);
		if (len > count) {
			ERR("reread length is bad");
		}
		else if (strcmp(data_string, key_string) != 0) {
			ERR("key/data don't match");
		}
		else if ((bitmap & bit) != 0) {
			ERR("key already seen");
		}
		else if ((expected & bit) == 0) {
			ERR("key was not expected");
		}
		else {
			bitmap |= bit;
			expected &= ~(bit);
			for (i=0; i<len; i++) {
				if (key_string[i] != ('0' + i)) {
					cout << " got " << key_string
					     << " (" << (int)key_string[i] << ")"
					     <<	", wanted " << i
					     << " (" << (int)('0' + i) << ")"
					     << " at position " << i << "\n";
					ERR("key is corrupt");
				}
			}
		}
	}
	if (expected != 0) {
		cout << " expected more keys, bitmap is: " << expected << "\n";
		ERR("missing keys in database");
	}
	CHK(dbcp->close());
	CHK(db->close(0));
}
Пример #10
0
// Modify or create a part based on the following information
MultiPartHeader::Add_Code MultiPartHeader::modifyPart(Db* pdb, quint16 partNo, RawHeader *rh, quint16 hostId)
{
	//qDebug() << "Entering modifyPart";
    Add_Code retCode = New_Part;
	int ret = 0;
	bool createPart = false;
	Header* h = 0;
    char *phead = 0;
    Dbc *cursorp = 0;

	Dbt key;
	Dbt data;

	//qDebug() << "Creating part for key " << multiPartKey;

	key.set_data(&multiPartKey);
	key.set_size(sizeof(quint64));

	data.set_data(&partNo);
	data.set_size(sizeof(quint16));

	// Get a cursor
	pdb->cursor(NULL, &cursorp, DB_WRITECURSOR);
	//qDebug("1");

	// Position the cursor to the first record in the database whose
	// key matches the search key and whose data begins with the search
	// data.
	ret = cursorp->get(&key, &data, DB_GET_BOTH);
	if  (ret == 0)
	{
		//qDebug("2");
	    // update the data
		h = new Header((char*)data.get_data(), (char*)key.get_data());
		//qDebug("3");

		if (h->isHeldByServer(hostId))
		{
			retCode = Duplicate_Part;
		}
		else
			retCode = Updated_Part;

        // qDebug() << "Found an update for part " << partNo << ", existing part " << h->getPartNo() << ", existing msgid " << h->getMessageId() << ", new msgid " << rh->m_mid;

		// Always update the article number
		h->setServerPartNum(hostId, rh->m_num);

		//qDebug("4");
		phead=h->data();

		data.set_data(phead);
		data.set_size(h->getRecordSize());

		//qDebug("5");
		cursorp->put(&key, &data, DB_CURRENT);
		//qDebug("6");
        Q_DELETE_ARRAY(phead);
	}
	else if (ret == DB_NOTFOUND) // create the part
	{
		//qDebug("7");
		createPart = true;
	}
	else // encountered an error
	{
		qDebug() << "Unable to find part " << partNo << " for key " << multiPartKey << ", result = " << ret;
		retCode = Error_Part;
	}

	// Close the cursor
	if (cursorp != NULL)
	    cursorp->close();

	if (createPart == true)
	{
		//qDebug("8");
		quint32 partSize = rh->m_bytes.toULong();
		h = new Header(multiPartKey, partNo, partSize);

		//qDebug("9");

		h->setMessageId(rh->m_mid);
		h->setServerPartNum(hostId, rh->m_num);

		//save in the parts db
		phead=h->data();

		data.set_data(phead);
		data.set_size(h->getRecordSize());

		//qDebug("10");

		ret = pdb->put(0, &key, &data, 0);
		if (ret)
		{
		    qDebug() << "Unable to create part " << partNo << " for key " << multiPartKey << ", result = " << ret;
		    retCode = Error_Part;
		}
		else
			retCode = New_Part;
		//qDebug("11");
        Q_DELETE_ARRAY(phead);
	}

    Q_DELETE(h);

	//qDebug("12\n");

	//qDebug() << "Exiting modifyPart";
	return retCode;
}
Пример #11
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;
}
Пример #12
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();
    }
}
Пример #13
0
ScanResponse BDBBackend::scan (const string & bucket, const string & seed,
                               int32_t count)
{
    ScanResponse scan_response;

    Dbc * dbc;

    try
    {
        Dbt db_key;
        char key[BDB_BACKEND_MAX_KEY_SIZE + 1];
        db_key.set_data (key);
        db_key.set_ulen (BDB_BACKEND_MAX_KEY_SIZE + 1);
        db_key.set_flags (DB_DBT_USERMEM);
        Dbt db_value;
        char value[BDB_BACKEND_MAX_VALUE_SIZE + 1];
        db_value.set_data (value);
        db_value.set_ulen (BDB_BACKEND_MAX_VALUE_SIZE + 1);
        db_value.set_flags (DB_DBT_USERMEM);

        get_db (bucket)->cursor (NULL, &dbc, 0);

        // this get positions us at the last key we grabbed or the one
        // imediately following it
        // copy over the seed and it's size
        strncpy (key, seed.c_str (), seed.length () + 1);
        db_key.set_size (seed.length () + 1);
        if (dbc->get (&db_key, &db_value, DB_SET_RANGE) == 0)
        {
            string key_tmp ((const char *)db_key.get_data (),
                            db_key.get_size ());
            if (seed != key_tmp)
            {
                // we got the one after it, it must be gone now, so return
                // this one
                Element e;
                e.key = key_tmp;
                e.value = string ((const char *)db_value.get_data (),
                                  db_value.get_size ());
                scan_response.elements.push_back (e);
            } // we'll skip it, it's the one we had last time

            // now keep going until we run out of items or get our fill
            while ((dbc->get (&db_key, &db_value, DB_NEXT) == 0) &&
                    (scan_response.elements.size () < (unsigned int)count))
            {
                Element e;
                e.key = string ((const char *)db_key.get_data (),
                                db_key.get_size ());
                e.value = string ((const char *)db_value.get_data (),
                                  db_value.get_size ());
                scan_response.elements.push_back (e);
            }
        }
    }
    catch (DbDeadlockException & e)
    {
        T_INFO ("scan: exception=%s", e.what ());
        dbc->close ();
        throw e;
    }
    catch (DbException & e)
    {
        T_ERROR ("scan: exception=%s", e.what ());
        dbc->close ();
        throw e;
    }

    dbc->close ();

    scan_response.seed = scan_response.elements.size () > 0 ?
                         scan_response.elements.back ().key : "";

    return scan_response;
}
Пример #14
0
/*
 * Look at all the records and parse keys for addresses and private keys
 */
bool WalletUtilityDB::parseKeys(bool dumppriv, std::string masterPass)
{
    DBErrors result = DB_LOAD_OK;
    std::string strType;
    bool first = true;

    try {
        Dbc* pcursor = GetCursor();
        if (!pcursor)
        {
            LogPrintf("Error getting wallet database cursor\n");
            result = DB_CORRUPT;
        }

        if (dumppriv)
        {
            while (result == DB_LOAD_OK && true)
            {
                CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                int result = ReadAtCursor(pcursor, ssKey, ssValue);

                if (result == DB_NOTFOUND) {
                    break;
                }
                else if (result != 0)
                {
                    LogPrintf("Error reading next record from wallet database\n");
                    result = DB_CORRUPT;
                    break;
                }

                ssKey >> strType;
                if (strType == "mkey")
                {
                    updateMasterKeys(ssKey, ssValue);
                }
            }
            pcursor->close();
            pcursor = GetCursor();
        }

        while (result == DB_LOAD_OK && true)
        {
            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
            int ret = ReadAtCursor(pcursor, ssKey, ssValue);

            if (ret == DB_NOTFOUND)
            {
                std::cout << " ]" << std::endl;
                first = true;
                break;
            }
            else if (ret != DB_LOAD_OK)
            {
                LogPrintf("Error reading next record from wallet database\n");
                result = DB_CORRUPT;
                break;
            }

            ssKey >> strType;

            if (strType == "key" || strType == "ckey")
            {
                std::string strAddr = getAddress(ssKey);
                std::string strKey = "";


                if (dumppriv && strType == "key")
                    strKey = getKey(ssKey, ssValue);
                if (dumppriv && strType == "ckey")
                {
                    if (masterPass == "")
                    {
                        std::cout << "Encrypted wallet, please provide a password. See help below" << std::endl;
                        show_help();
                        result = DB_LOAD_FAIL;
                        break;
                    }
                    strKey = getCryptedKey(ssKey, ssValue, masterPass);
                }

                if (strAddr != "")
                {
                    if (first)
                        std::cout << "[ ";
                    else
                        std::cout << ", ";
                }

                if (dumppriv)
                {
                    std::cout << "{\"addr\" : \"" + strAddr + "\", "
                        << "\"pkey\" : \"" + strKey + "\"}"
                        << std::flush;
                }
                else
                {
                    std::cout << "\"" + strAddr + "\"";
                }

                first = false;
            }
        }

        pcursor->close();
    } catch (DbException &e) {
        std::cout << "DBException caught " << e.get_errno() << std::endl;
    } catch (std::exception &e) {
        std::cout << "Exception caught " << std::endl;
    }

    if (result == DB_LOAD_OK)
        return true;
    else
        return false;
}
Пример #15
0
/*static*/ void
Freeze::MapHelper::recreate(const Freeze::ConnectionPtr& connection,
                            const string& dbName,
                            const string& key,
                            const string& value,
                            const Freeze::KeyCompareBasePtr& keyCompare,
                            const std::vector<MapIndexBasePtr>& indices)
{
    Freeze::ConnectionIPtr connectionI = Freeze::ConnectionIPtr::dynamicCast(connection.get());
    if(connectionI == 0)
    {
        throw DatabaseException(__FILE__, __LINE__, "Invalid connection");
    }

    if(dbName == catalogName() || dbName == catalogIndexListName())
    {
        throw DatabaseException(__FILE__, __LINE__,
                                "You cannot destroy recreate the \"" + dbName + "\" database");
    }

    if(connectionI->trace() >= 1)
    {
        Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
        out << "Recreating \"" << dbName << "\"";
    }

    TransactionPtr tx = connectionI->currentTransaction();
    bool ownTx = (tx == 0);

    Dbt keyDbt;
    keyDbt.set_flags(DB_DBT_REALLOC);
    Dbt valueDbt;
    valueDbt.set_flags(DB_DBT_REALLOC);

    try
    {
        for(;;)
        {
            try
            {
                if(ownTx)
                {
                    tx = 0;
                    tx = connectionI->beginTransaction();
                }

                DbTxn* txn = connectionI->dbTxn();

                if(connectionI->trace() >= 2)
                {
                    Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
                    out << "Removing all existing indices for \"" << dbName << "\"";
                }
                CatalogIndexList catalogIndexList(connection, catalogIndexListName());
                CatalogIndexList::iterator p = catalogIndexList.find(dbName);
                if(p != catalogIndexList.end())
                {
                    const StringSeq& idxs = p->second;

                    for(size_t i = 0; i < idxs.size(); ++i)
                    {
                        try
                        {
                            connection->removeMapIndex(dbName, idxs[i]);
                        }
                        catch(const IndexNotFoundException&)
                        {
                            //
                            // Ignored
                            //
                        }
                    }
                    catalogIndexList.erase(p);
                }

                //
                // Rename existing database
                //
                string oldDbName = dbName + ".old-" + generateUUID();

                if(connectionI->trace() >= 2)
                {
                    Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
                    out << "Renaming \"" << dbName << "\" to \"" << oldDbName << "\"";
                }

                connectionI->dbEnv()->getEnv()->dbrename(txn, dbName.c_str(), 0, oldDbName.c_str(), 0);

                //
                // Fortunately, DB closes oldDb automatically when it goes out of scope
                //
                Db oldDb(connectionI->dbEnv()->getEnv(), 0);

                //
                // Berkeley DB expects file paths to be UTF8 encoded.
                //
                oldDb.open(txn, nativeToUTF8(oldDbName, getProcessStringConverter()).c_str(),
                           0, DB_BTREE, DB_THREAD, FREEZE_DB_MODE);

                IceInternal::UniquePtr<MapDb> newDb(new MapDb(connectionI, dbName, key, value, keyCompare, indices, true));

                if(connectionI->trace() >= 2)
                {
                    Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
                    out << "Writing contents of \"" << oldDbName << "\" to fresh \"" << dbName << "\"";
                }

                //
                // Now simply write all of oldDb into newDb
                //
                Dbc* dbc = 0;
                oldDb.cursor(txn, &dbc, 0);

                try
                {
                    while(dbc->get(&keyDbt, &valueDbt, DB_NEXT) == 0)
                    {
                        newDb->put(txn, &keyDbt, &valueDbt, 0);
                    }
                }
                catch(...)
                {
                    dbc->close();
                    throw;
                }
                dbc->close();

                if(connectionI->trace() >= 2)
                {
                    Trace out(connectionI->communicator()->getLogger(), "Freeze.Map");
                    out << "Transfer complete; removing \"" << oldDbName << "\"";
                }
                connectionI->dbEnv()->getEnv()->dbremove(txn, oldDbName.c_str(), 0, 0);

                if(ownTx)
                {
                    tx->commit();
                }

                break; // for (;;)
            }
            catch(const DbDeadlockException& dx)
            {
                if(ownTx)
                {
                    if(connectionI->deadlockWarning())
                    {
                        Warning out(connectionI->communicator()->getLogger());
                        out << "Deadlock in Freeze::MapHelperI::recreate on Db \""
                            << dbName << "\"; retrying ...";
                    }

                    //
                    // Ignored, try again
                    //
                }
                else
                {
                    throw DeadlockException(__FILE__, __LINE__, dx.what(), tx);
                }
            }
            catch(const DbException& dx)
            {
                if(ownTx)
                {
                    try
                    {
                        tx->rollback();
                    }
                    catch(...)
                    {
                    }
                }

                throw DatabaseException(__FILE__, __LINE__, dx.what());
            }
            catch(...)
            {
                if(ownTx && tx != 0)
                {
                    try
                    {
                        tx->rollback();
                    }
                    catch(...)
                    {
                    }
                }
                throw;
            }
        }
        free(keyDbt.get_data());
        free(valueDbt.get_data());
    }
    catch(...)
    {
        free(keyDbt.get_data());
        free(valueDbt.get_data());

        throw;
    }
}
void run_bdb_btree(stxxl::int64 ops)
{
    const char * filename = BDB_FILE;

    my_key key1_storage;
    my_data data1_storage;

    unlink(filename);

    memset(key1_storage.keybuf, 'a', KEY_SIZE);
    memset(data1_storage.databuf, 'b', DATA_SIZE);


    Db db(NULL, 0);             // Instantiate the Db object

    try {
        db.set_errfile(stderr);
        db.set_pagesize(pagesize);
        db.set_cachesize(0, cachesize, 1);

        // Open the database
        db.open(NULL,           // Transaction pointer
                filename,       // Database file name
                NULL,           // Optional logical database name
                DB_BTREE,       // Database access method
                DB_CREATE,      // Open flags
                0);             // File mode (using defaults)


        // here we start with the tests
        Dbt key1(key1_storage.keybuf, KEY_SIZE);
        Dbt data1(data1_storage.databuf, DATA_SIZE);

        stxxl::timer Timer;
        stxxl::int64 n_inserts = ops, n_locates = ops, n_range_queries = ops, n_deletes = ops;
        stxxl::int64 i;
        //comp_type cmp_;

        ran32State = 0xdeadbeef;


        DB_BTREE_STAT * dbstat;

        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);

        db.get_env()->memp_stat(NULL, NULL, DB_STAT_CLEAR);

        Timer.start();

        for (i = 0; i < n_inserts; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            db.put(NULL, &key1, &data1, DB_NOOVERWRITE);
        }

        Timer.stop();
        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);
        STXXL_MSG("Insertions elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(n_inserts) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        /////////////////////////////////////////
        Timer.reset();
        Timer.start();


        Dbc * cursorp;
        db.cursor(NULL, &cursorp, 0);

        for (i = 0; i < n_locates; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
            Dbt datax(data1_storage.databuf, DATA_SIZE);

            cursorp->get(&keyx, &datax, DB_SET_RANGE);
        }

        Timer.stop();
        STXXL_MSG("Locates elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        ////////////////////////////////////
        Timer.reset();

        Timer.start();

        stxxl::int64 n_scanned = 0;

        for (i = 0; i < n_range_queries; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            my_key last_key = key1_storage;
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            if (last_key < key1_storage)
                std::swap(last_key, key1_storage);


            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
            Dbt datax(data1_storage.databuf, DATA_SIZE);

            if (cursorp->get(&keyx, &datax, DB_SET_RANGE) == DB_NOTFOUND)
                continue;


            while (*((my_key *)keyx.get_data()) <= last_key)
            {
                ++n_scanned;
                if (cursorp->get(&keyx, &datax, DB_NEXT) == DB_NOTFOUND)
                    break;
            }

            if (n_scanned >= 10 * n_range_queries)
            {
                ++i;
                break;
            }
        }

        n_range_queries = i;

        Timer.stop();
        if (cursorp != NULL)
            cursorp->close();


        STXXL_MSG("Range query elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(n_scanned) / (Timer.mseconds() / 1000.)) <<
                  " key/data pairs per sec, #queries " << n_range_queries << " #scanned elements: " << n_scanned);

        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        //////////////////////////////////////

        ran32State = 0xdeadbeef;
        memset(key1_storage.keybuf, 'a', KEY_SIZE);

        Timer.reset();
        Timer.start();

        for (i = 0; i < n_deletes; ++i)
        {
            //key1_storage.keybuf[KEYPOS] = letters[VALUE];
            rand_key(i, key1_storage);
            Dbt keyx(key1_storage.keybuf, KEY_SIZE);
            db.del(NULL, &keyx, 0);
        }

        Timer.stop();
        db.stat(NULL, &dbstat, 0);
        STXXL_MSG("Records in map: " << dbstat->bt_ndata);
        STXXL_MSG("Erase elapsed time: " << (Timer.mseconds() / 1000.) <<
                  " seconds : " << (double(ops) / (Timer.mseconds() / 1000.)) << " key/data pairs per sec");

        db.get_env()->memp_stat_print(DB_STAT_CLEAR);

        db.close(0);
    }
    catch (DbException & e)
    {
        STXXL_ERRMSG("DbException happened");
    }
    catch (std::exception & e)
    {
        STXXL_ERRMSG("std::exception happened");
    }

    unlink(filename);
}
Пример #17
0
void
Freeze::MapHelperI::clear()
{
    DbTxn* txn = _connection->dbTxn();
    if(txn == 0)
    {
        closeAllIterators();
    }

    Dbt dbKey;
    dbKey.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);

    Dbt dbValue;
    dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);

    try
    {
        for(;;)
        {
            Dbc* dbc = 0;

            try
            {
                IteratorHelperI::TxPtr tx;
                if(txn == 0)
                {
#ifdef ICE_CPP11_COMPILER
                    tx.reset(new IteratorHelperI::Tx(*this));
#else
                    tx = new IteratorHelperI::Tx(*this);
#endif
                    txn = tx->getTxn();
                }

                _db->cursor(txn, &dbc, 0);
                while(dbc->get(&dbKey, &dbValue, DB_NEXT | DB_RMW) == 0)
                {
                    dbc->del(0);
                }

                Dbc* toClose = dbc;
                dbc = 0;
                toClose->close();
                break; // for (;;)
            }
            catch(const DbDeadlockException&)
            {
                if(dbc != 0)
                {
                    try
                    {
                        dbc->close();
                    }
                    catch(const DbDeadlockException&)
                    {
                        if(txn != 0)
                        {
                            throw;
                        }
                        else
                        {
                            //
                            // Ignored
                            //
                        }
                    }
                }

                if(_connection->deadlockWarning())
                {
                    Warning out(_connection->communicator()->getLogger());
                    out << "Deadlock in Freeze::MapHelperI::clear on Map \""
                        << _dbName << "\"; retrying ...";
                }

                if(txn != 0)
                {
                    throw;
                }
                //
                // Otherwise retry
                //
            }
            catch(...)
            {
                if(dbc != 0)
                {
                    try
                    {
                        dbc->close();
                    }
                    catch(const DbDeadlockException&)
                    {
                        if(txn != 0)
                        {
                            throw;
                        }
                        else
                        {
                            //
                            // Ignored
                            //
                        }
                    }
                }
                throw;
            }
        }
    }
    catch(const DbDeadlockException& dx)
    {
        throw DeadlockException(__FILE__, __LINE__, dx.what(), _connection->currentTransaction());
    }
    catch(const DbException& dx)
    {
        throw DatabaseException(__FILE__, __LINE__, dx.what());
    }
}
Пример #18
0
/* Loop get batches of records. */
void BulkExample::bulkRead(
    int num, int dups, int iter, int *countp, int verbose)
{
	Dbc *dbcp;
	Dbt data, dp, key, kp;
	DbTxn *txnp;
	DbMultipleDataIterator *ptrd;
	DbMultipleKeyDataIterator *ptrkd;
	u_int32_t flags;
	int count, i, j, ret;

	count = klen = ret = 0;
	dbcp = NULL;
	txnp = NULL;

	/* Initialize key Dbt and data Dbt, malloc bulk buffer. */
	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));
	key.set_size(sizeof(j));
	if (dlen != DATALEN * 16 * 1024) {
		dlen = DATALEN * 16 * 1024;
		dbuf = realloc(dbuf, dlen);
	}
	memset(dbuf, 0, dlen);
	data.set_flags(DB_DBT_USERMEM);
	data.set_data(dbuf);
	data.set_ulen(dlen);
	data.set_size(dlen);

	flags = DB_SET;
	flags |= (dups) ? DB_MULTIPLE: DB_MULTIPLE_KEY;
	try {
		for (i = 0; i < iter; i++) {
			if ((ret =
			    dbenv->txn_begin(NULL, &txnp, 0)) != 0)
				throwException(dbenv, NULL,
				    ret, "DB_ENV->txn_begin");
			if ((ret = dbp->cursor(txnp, &dbcp, 0)) != 0)
				throwException(dbenv, txnp,
				    ret, "DB->cursor");

			/*
			 * Bulk retrieve by a random key which is a random
			 * non-negative integer smaller than "num".
			 * If there are duplicates in the database, retrieve
			 * with DB_MULTIPLE and use the DbMultipleDataIterator
			 * to iterate the data of the random key in the data
			 * Dbt. Otherwise retrieve with DB_MULTIPLE_KEY and use
			 * the DbMultipleKeyDataIterator to iterate the
			 * key/data pairs of the specific set of keys which
			 * includes all integers >= the random key and < "num".
			 */
			j = rand() % num;
			key.set_data(&j);
			if ((ret = dbcp->get(&key, &data, flags)) != 0) 
				throwException(dbenv, NULL, ret, "DBC->get");

			if (dups) {
				ptrd = new DbMultipleDataIterator(data);
				while (ptrd->next(dp) == true) {
					count++;
					if (verbose)
						printf(
"Retrieve key: %d, \tdata: (id %d, str %s)\n", j, ((struct data *)(
						   dp.get_data()))->id,
						   (char *)((struct data *)(
						   dp.get_data()))->str);
				}
			} else {
				ptrkd = new DbMultipleKeyDataIterator(data);
				while (ptrkd->next(kp, dp) == true) {
					count++;
					if (verbose)
						printf(
"Retrieve key: %d, \tdata: (id %d, str %s)\n", *((int *)kp.get_data()),
						    ((struct data *)(
						    dp.get_data()))->id,
						    (char *)((struct data *)(
						    dp.get_data()))->str);
				}
			}

			ret = dbcp->close();
			dbcp = NULL;
			if (ret != 0)
				throwException(dbenv, txnp, ret, "DBC->close");

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

		*countp = count;
	} catch (DbException &dbe) {
		cerr << "bulkRead " << dbe.what() << endl;
		if (dbcp != NULL)
			(void)dbcp->close();
		if (txnp != NULL)
			(void)txnp->abort();
		throw dbe;
	}
}
Пример #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;
}
Пример #20
0
void AccessExample::run(bool removeExistingDatabase, const char *fileName)
{
	// Remove the previous database.
	if (removeExistingDatabase)
		(void)remove(fileName);

	// Create the database object.
	// There is no environment for this simple example.
	Db db(0, 0);

	db.set_error_stream(&cerr);
	db.set_errpfx("AccessExample");
	db.set_pagesize(1024);		/* Page size: 1K. */
	db.set_cachesize(0, 32 * 1024, 0);
	db.open(NULL, fileName, NULL, DB_BTREE, DB_CREATE, 0664);

	//
	// Insert records into the database, where the key is the user
	// input and the data is the user input in reverse order.
	//
	char buf[1024], rbuf[1024];
	char *p, *t;
	int ret;
	u_int32_t len;

	for (;;) {
		cout << "input> ";
		cout.flush();

		cin.getline(buf, sizeof(buf));
		if (cin.eof())
			break;

		if ((len = (u_int32_t)strlen(buf)) <= 0)
			continue;
		for (t = rbuf, p = buf + (len - 1); p >= buf;)
			*t++ = *p--;
		*t++ = '\0';

		Dbt key(buf, len + 1);
		Dbt data(rbuf, len + 1);

		ret = db.put(0, &key, &data, DB_NOOVERWRITE);
		if (ret == DB_KEYEXIST) {
			cout << "Key " << buf << " already exists.\n";
		}
	}
	cout << "\n";

	// We put a try block around this section of code
	// to ensure that our database is properly closed
	// in the event of an error.
	//
	try {
		// Acquire a cursor for the table.
		Dbc *dbcp;
		db.cursor(NULL, &dbcp, 0);

		// Walk through the table, printing the key/data pairs.
		Dbt key;
		Dbt data;
		while (dbcp->get(&key, &data, DB_NEXT) == 0) {
			char *key_string = (char *)key.get_data();
			char *data_string = (char *)data.get_data();
			cout << key_string << " : " << data_string << "\n";
		}
		dbcp->close();
	}
	catch (DbException &dbe) {
		cerr << "AccessExample: " << dbe.what() << "\n";
	}

	db.close(0);
}
Пример #21
0
int main()
{
    u_int32_t env_flags = DB_CREATE |       // If the environment does not exist, create it.
                          DB_INIT_MPOOL;    // Initialize the in-memory cache.

    //std::string envHome("./");
    std::string envHome("/home/kirill");

    u_int32_t db_flags = DB_RDONLY;   // only read

    std::string dbName("X-po2s.db");
    //std::string dbName("X-so2p.db");
    //std::string dbName("X-sp2o.db");

    DbEnv myEnv(0);
    Db *myDb;       // Instantiate the Db object

    Dbc *cursorp;   // cursor

    try
    {
        cout << "X-po2s.db output:" << endl;

        myEnv.open(envHome.c_str(), env_flags, 0);

        myDb = new Db(&myEnv, 0);

        myDb->open(NULL, dbName.c_str(), NULL, DB_BTREE, db_flags, 0);

        // Get a cursor
        myDb->cursor(NULL, &cursorp, 0);

        Dbt key, data;
        // Position the cursor to the first record in the database whose
        // key and data begin with the correct strings.
        int ret = cursorp->get(&key, &data, DB_NEXT);
        while (ret != DB_NOTFOUND)
        {
            cout << "..." << endl;
            std::cout << "key: " << (char *)key.get_data()
                      << "data: " << (char *)data.get_data()<< std::endl;
            ret = cursorp->get(&key, &data, DB_NEXT);
        }

        // Cursors must be closed
        if (cursorp != NULL)
            cursorp->close();


        if (myDb != NULL) {
            myDb->close(0);
        }
        myEnv.close(0);

        cout << "Closing ..." << endl;
    }
    // Must catch both DbException and std::exception
    catch(DbException &e)
    {
        myDb->err(e.get_errno(), "Database open failed %s", dbName.c_str());
        throw e;
    }
    catch(std::exception &e)
    {
        // No DB error number available, so use errx
        myDb->errx("Error opening database: %s", e.what());
        throw e;
    }


	return 0;
}
Пример #22
0
bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip)
{
    if (database.IsDummy()) {
        return true;
    }
    BerkeleyEnvironment *env = database.env;
    const std::string& strFile = database.strFile;
    while (true) {
        {
            LOCK(cs_db);
            if (!env->mapFileUseCount.count(strFile) || env->mapFileUseCount[strFile] == 0) {
                // Flush log data to the dat file
                env->CloseDb(strFile);
                env->CheckpointLSN(strFile);
                env->mapFileUseCount.erase(strFile);

                bool fSuccess = true;
                LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile);
                std::string strFileRes = strFile + ".rewrite";
                { // surround usage of db with extra {}
                    BerkeleyBatch db(database, "r");
                    std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);

                    int ret = pdbCopy->open(nullptr,               // Txn pointer
                                            strFileRes.c_str(), // Filename
                                            "main",             // Logical db name
                                            DB_BTREE,           // Database type
                                            DB_CREATE,          // Flags
                                            0);
                    if (ret > 0) {
                        LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes);
                        fSuccess = false;
                    }

                    Dbc* pcursor = db.GetCursor();
                    if (pcursor)
                        while (fSuccess) {
                            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                            int ret1 = db.ReadAtCursor(pcursor, ssKey, ssValue);
                            if (ret1 == DB_NOTFOUND) {
                                pcursor->close();
                                break;
                            } else if (ret1 != 0) {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }
                            if (pszSkip &&
                                strncmp(ssKey.data(), pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
                                continue;
                            if (strncmp(ssKey.data(), "\x07version", 8) == 0) {
                                // Update version:
                                ssValue.clear();
                                ssValue << CLIENT_VERSION;
                            }
                            Dbt datKey(ssKey.data(), ssKey.size());
                            Dbt datValue(ssValue.data(), ssValue.size());
                            int ret2 = pdbCopy->put(nullptr, &datKey, &datValue, DB_NOOVERWRITE);
                            if (ret2 > 0)
                                fSuccess = false;
                        }
                    if (fSuccess) {
                        db.Close();
                        env->CloseDb(strFile);
                        if (pdbCopy->close(0))
                            fSuccess = false;
                    } else {
                        pdbCopy->close(0);
                    }
                }
                if (fSuccess) {
                    Db dbA(env->dbenv.get(), 0);
                    if (dbA.remove(strFile.c_str(), nullptr, 0))
                        fSuccess = false;
                    Db dbB(env->dbenv.get(), 0);
                    if (dbB.rename(strFileRes.c_str(), nullptr, strFile.c_str(), 0))
                        fSuccess = false;
                }
                if (!fSuccess)
                    LogPrintf("BerkeleyBatch::Rewrite: Failed to rewrite database file %s\n", strFileRes);
                return fSuccess;
            }
        }
        MilliSleep(100);
    }
}
Пример #23
0
//
// XXX Figure out the appropriate way to pick out IDs.
//
int
TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb,
		 int accounts, int branches, int tellers)
{
	Dbc *acurs = NULL;
	Dbc *bcurs = NULL;
	Dbc *tcurs = NULL;
	DbTxn *t = NULL;

	db_recno_t key;
	Defrec rec;
	Histrec hrec;
	int account, branch, teller;

	Dbt d_dbt;
	Dbt d_histdbt;
	Dbt k_dbt;
	Dbt k_histdbt(&key, sizeof(key));

	//
	// XXX We could move a lot of this into the driver to make this
	// faster.
	//
	account = random_id(ACCOUNT, accounts, branches, tellers);
	branch = random_id(BRANCH, accounts, branches, tellers);
	teller = random_id(TELLER, accounts, branches, tellers);

	k_dbt.set_size(sizeof(int));

	d_dbt.set_flags(DB_DBT_USERMEM);
	d_dbt.set_data(&rec);
	d_dbt.set_ulen(sizeof(rec));

	hrec.aid = account;
	hrec.bid = branch;
	hrec.tid = teller;
	hrec.amount = 10;
	// Request 0 bytes since we're just positioning.
	d_histdbt.set_flags(DB_DBT_PARTIAL);

	// START TIMING
	if (txn_begin(NULL, &t, 0) != 0)
		goto err;

	if (adb->cursor(t, &acurs, 0) != 0 ||
	    bdb->cursor(t, &bcurs, 0) != 0 ||
	    tdb->cursor(t, &tcurs, 0) != 0)
		goto err;

	// Account record
	k_dbt.set_data(&account);
	if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
		goto err;
	rec.balance += 10;
	if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
		goto err;

	// Branch record
	k_dbt.set_data(&branch);
	if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
		goto err;
	rec.balance += 10;
	if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
		goto err;

	// Teller record
	k_dbt.set_data(&teller);
	if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
		goto err;
	rec.balance += 10;
	if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
		goto err;

	// History record
	d_histdbt.set_flags(0);
	d_histdbt.set_data(&hrec);
	d_histdbt.set_ulen(sizeof(hrec));
	if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0)
		goto err;

	if (acurs->close() != 0 || bcurs->close() != 0 ||
	    tcurs->close() != 0)
		goto err;

	if (t->commit(0) != 0)
		goto err;

	// END TIMING
	return (0);

err:
	if (acurs != NULL)
		(void)acurs->close();
	if (bcurs != NULL)
		(void)bcurs->close();
	if (tcurs != NULL)
		(void)tcurs->close();
	if (t != NULL)
		(void)t->abort();

	if (verbose)
		cout << "Transaction A=" << (long)account
		     << " B=" << (long)branch
		     << " T=" << (long)teller << " failed\n";
	return (-1);
}
Пример #24
0
//
// XXX Figure out the appropriate way to pick out IDs.
//
int
TpcbExample::txn(Db *adb, Db *bdb, Db *tdb, Db *hdb,
		 int accounts, int branches, int tellers)
{
	Dbc *acurs = NULL;
	Dbc *bcurs = NULL;
	Dbc *tcurs = NULL;
	DbTxn *t = NULL;

	db_recno_t key;
	Defrec rec;
	Histrec hrec;
	int account, branch, teller, ret;

	Dbt d_dbt;
	Dbt d_histdbt;
	Dbt k_dbt;
	Dbt k_histdbt(&key, sizeof(key));

	// !!!
	// This is sample code -- we could move a lot of this into the driver
	// to make it faster.
	//
	account = random_id(ACCOUNT, accounts, branches, tellers);
	branch = random_id(BRANCH, accounts, branches, tellers);
	teller = random_id(TELLER, accounts, branches, tellers);

	k_dbt.set_size(sizeof(int));

	d_dbt.set_flags(DB_DBT_USERMEM);
	d_dbt.set_data(&rec);
	d_dbt.set_ulen(sizeof(rec));

	hrec.aid = account;
	hrec.bid = branch;
	hrec.tid = teller;
	hrec.amount = 10;
	// Request 0 bytes since we're just positioning.
	d_histdbt.set_flags(DB_DBT_PARTIAL);

	// START PER-TRANSACTION TIMING.
	//
	// Technically, TPCB requires a limit on response time, you only get
	// to count transactions that complete within 2 seconds.  That's not
	// an issue for this sample application -- regardless, here's where
	// the transaction begins.
	if (txn_begin(NULL, &t, 0) != 0)
		goto err;

	if (adb->cursor(t, &acurs, 0) != 0 ||
	    bdb->cursor(t, &bcurs, 0) != 0 ||
	    tdb->cursor(t, &tcurs, 0) != 0)
		goto err;

	try {
		// Account record
		k_dbt.set_data(&account);
		if (acurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
			goto err;
		rec.balance += 10;
		if (acurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
			goto err;

		// Branch record
		k_dbt.set_data(&branch);
		if (bcurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
			goto err;
		rec.balance += 10;
		if (bcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
			goto err;

		// Teller record
		k_dbt.set_data(&teller);
		if (tcurs->get(&k_dbt, &d_dbt, DB_SET) != 0)
			goto err;
		rec.balance += 10;
		if (tcurs->put(&k_dbt, &d_dbt, DB_CURRENT) != 0)
			goto err;

		// History record
		d_histdbt.set_flags(0);
		d_histdbt.set_data(&hrec);
		d_histdbt.set_ulen(sizeof(hrec));
		if (hdb->put(t, &k_histdbt, &d_histdbt, DB_APPEND) != 0)
			goto err;
	} catch (DbDeadlockException e) {
		goto err;
	}

	if (acurs->close() != 0 || bcurs->close() != 0 || tcurs->close() != 0)
		goto err;

	ret = t->commit(0);
	t = NULL;
	if (ret != 0)
		goto err;

	// END PER-TRANSACTION TIMING.
	return (0);

err:
	if (acurs != NULL)
		(void)acurs->close();
	if (bcurs != NULL)
		(void)bcurs->close();
	if (tcurs != NULL)
		(void)tcurs->close();
	if (t != NULL)
		(void)t->abort();

	if (verbose)
		cout << "Transaction A=" << (long)account
		     << " B=" << (long)branch
		     << " T=" << (long)teller << " failed\n";
	return (-1);
}
Пример #25
0
static int
run(const Ice::StringSeq& originalArgs, const Ice::CommunicatorPtr& communicator,
    const FreezeScript::CompactIdResolverIPtr& resolver)
{
    vector<string> cppArgs;
    bool debug;
    bool ice = true; // Needs to be true in order to create default definitions.
    bool underscore;
    string outputFile;
    string inputFile;
    vector<string> slice;
    bool evictor;
    string keyTypeName;
    string valueTypeName;
    string selectExpr;
    string dbEnvName, dbName;
    const string appName = originalArgs[0];
    IceUtilInternal::Options opts;
    opts.addOpt("h", "help");
    opts.addOpt("v", "version");
    opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
    opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
    opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
    opts.addOpt("d", "debug");
    opts.addOpt("", "ice");
    opts.addOpt("", "underscore");
    opts.addOpt("o", "", IceUtilInternal::Options::NeedArg);
    opts.addOpt("f", "", IceUtilInternal::Options::NeedArg);
    opts.addOpt("", "load", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
    opts.addOpt("e");
    opts.addOpt("", "key", IceUtilInternal::Options::NeedArg);
    opts.addOpt("", "value", IceUtilInternal::Options::NeedArg);
    opts.addOpt("", "select", IceUtilInternal::Options::NeedArg);
    opts.addOpt("c", "catalog");

    vector<string> args;
    try
    {
        args = opts.parse(originalArgs);
    }
    catch(const IceUtilInternal::BadOptException& e)
    {
        cerr << appName << ": " << e.reason << endl;
        usage(appName);
        return EXIT_FAILURE;
    }

    //
    // Freeze creates a lock file by default to prevent multiple processes from opening
    // the same database environment simultaneously. In the case of a read-only program
    // such as dumpdb, however, we still want to be able to open the environment despite
    // the lock. This assumes of course that the other process has opened the environment
    // with DbPrivate=0. If DbPrivate=0 is also set for dumpdb, we disable the lock.
    //
    if(!args.empty())
    {
        //
        // If an argument is present, we assume it is the name of the database environment.
        //
        Ice::PropertiesPtr props = communicator->getProperties();
        string prefix = "Freeze.DbEnv." + args[0];
        if(props->getPropertyAsIntWithDefault(prefix + ".DbPrivate", 1) <= 0)
        {
            props->setProperty(prefix + ".LockFile", "0");
        }
    }

    if(opts.isSet("h"))
    {
        usage(appName);
        return EXIT_SUCCESS;
    }
    if(opts.isSet("version"))
    {
        cout << ICE_STRING_VERSION << endl;
        return EXIT_SUCCESS;
    }
    if(opts.isSet("c"))
    {
        if(args.empty())
        {
            cerr << appName << ": no database environment specified." << endl;
            usage(appName);
            return EXIT_FAILURE;
        }
        else if(args.size() > 2)
        {
            usage(appName);
            return EXIT_FAILURE;
        }
        try
        {
            FreezeScript::CatalogDataMap catalog = FreezeScript::readCatalog(communicator, args[0]);
            if(args.size() == 1)
            {
                if(catalog.empty())
                {
                    cout << "Catalog is empty." << endl;
                }
                else
                {
                    cout << "Catalog contents:" << endl;
                    for(FreezeScript::CatalogDataMap::const_iterator p = catalog.begin(); p != catalog.end(); ++p)
                    {
                        cout << endl;
                        printCatalogData(p->first, p->second);
                    }
                }
            }
            else
            {
                FreezeScript::CatalogDataMap::const_iterator p = catalog.find(args[1]);
                if(p == catalog.end())
                {
                    cerr << appName << ": database `" << args[1] << "' not found in environment `" << args[0] << "'."
                         << endl;
                    return EXIT_FAILURE;
                }
                else
                {
                    printCatalogData(p->first, p->second);
                }
            }
            return EXIT_SUCCESS;
        }
        catch(const FreezeScript::FailureException& ex)
        {
            cerr << appName << ": " << ex.reason() << endl;
            return EXIT_FAILURE;
        }
    }
    if(opts.isSet("D"))
    {
        vector<string> optargs = opts.argVec("D");
        for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
        {
            cppArgs.push_back("-D" + *i);
        }
    }
    if(opts.isSet("U"))
    {
        vector<string> optargs = opts.argVec("U");
        for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
        {
            cppArgs.push_back("-U" + *i);
        }
    }
    if(opts.isSet("I"))
    {
        vector<string> optargs = opts.argVec("I");
        for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i)
        {
            cppArgs.push_back("-I" + *i);
        }
    }
    debug = opts.isSet("debug");

    // No need to set --ice option here -- it is always true.

    underscore = opts.isSet("underscore");

    if(opts.isSet("o"))
    {
        outputFile = opts.optArg("o");
    }
    if(opts.isSet("f"))
    {
        inputFile = opts.optArg("f");
    }
    if(opts.isSet("load"))
    {
        vector<string> optArgs = opts.argVec("load");
        for(vector<string>::const_iterator i = optArgs.begin(); i != optArgs.end(); ++i)
        {
            slice.push_back(*i);
        }
    }
    evictor = opts.isSet("e");
    if(opts.isSet("key"))
    {
        keyTypeName = opts.optArg("key");
    }
    if(opts.isSet("value"))
    {
        valueTypeName = opts.optArg("value");
    }
    if(opts.isSet("select"))
    {
        selectExpr = opts.optArg("select");
    }

    if(outputFile.empty() && args.size() != 2)
    {
        usage(appName);
        return EXIT_FAILURE;
    }

    if(!args.empty())
    {
        dbEnvName = args[0];
    }
    if(args.size() == 2)
    {
        dbName = args[1];
    }
    else
    {
        usage(appName);
        return EXIT_FAILURE;
    }

    if(!inputFile.empty() && !selectExpr.empty())
    {
        cerr << appName << ": an input file cannot be specified with --select" << endl;
        return EXIT_FAILURE;
    }

    Slice::UnitPtr unit = Slice::Unit::createUnit(true, true, ice, underscore);
    FreezeScript::Destroyer<Slice::UnitPtr> unitD(unit);
    if(!FreezeScript::parseSlice(appName, unit, slice, cppArgs, debug, "-D__DUMPDB__"))
    {
        return EXIT_FAILURE;
    }

    FreezeScript::createEvictorSliceTypes(unit);

    FreezeScript::collectCompactIds(unit, resolver);

    //
    // If no input file was provided, then we need to generate default descriptors.
    //
    string descriptors;
    if(inputFile.empty())
    {
        const string evictorKeyTypeName = "::Ice::Identity";
        const string oldEvictorValueTypeName = "::Freeze::ObjectRecord";
        const string newEvictorValueTypeName = "Object";

        if((!keyTypeName.empty() && valueTypeName.empty()) || (keyTypeName.empty() && !valueTypeName.empty() && !evictor))
        {
            cerr << appName << ": a key type and a value type must be specified" << endl;
            usage(appName);
            return EXIT_FAILURE;
        }
        else if(valueTypeName.empty())
        {
            try
            {
                FreezeScript::CatalogDataMap catalog = FreezeScript::readCatalog(communicator, dbEnvName);
                FreezeScript::CatalogDataMap::iterator p = catalog.find(dbName);
                if(p == catalog.end())
                {
                    cerr << appName << ": database `" << dbName << "' not found in catalog." << endl;
                    cerr << "Current catalog databases:" << endl;
                    for(p = catalog.begin(); p != catalog.end(); ++p)
                    {
                        cerr << "  " << p->first << endl;
                    }
                    return EXIT_FAILURE;
                }
                else
                {
                    if(p->second.evictor)
                    {
                        evictor = true;
                    }
                    keyTypeName = p->second.key;
                    valueTypeName = p->second.value;

                    if(evictor && valueTypeName.empty())
                    {
                        valueTypeName = oldEvictorValueTypeName;
                    }
                }
            }
            catch(const FreezeScript::FailureException& ex)
            {
                cerr << appName << ": " << ex.reason() << endl;
                return EXIT_FAILURE;
            }
        }

        if(evictor)
        {
            if(keyTypeName.empty())
            {
                keyTypeName = evictorKeyTypeName;
            }
            if(valueTypeName.empty())
            {
                valueTypeName = newEvictorValueTypeName;
            }
        }

        Slice::TypePtr keyType, valueType;
        Slice::TypeList l;

        l = unit->lookupType(keyTypeName, false);
        if(l.empty())
        {
            cerr << appName << ": unknown key type `" << keyTypeName << "'" << endl;
            return EXIT_FAILURE;
        }
        keyType = l.front();

        l = unit->lookupType(valueTypeName, false);
        if(l.empty())
        {
            cerr << appName << ": unknown value type `" << valueTypeName << "'" << endl;
            return EXIT_FAILURE;
        }
        valueType = l.front();

        ostringstream os;
        IceUtilInternal::XMLOutput out(os);

        out << se("dumpdb");

        FreezeScript::SliceVisitor visitor(out, keyType, valueType, selectExpr);
        unit->visit(&visitor, false);

        out << ee;

        descriptors = os.str();

        if(!outputFile.empty())
        {
            IceUtilInternal::ofstream of(outputFile);
            if(!of.good())
            {
                cerr << appName << ": unable to open file `" << outputFile << "'" << endl;
                return EXIT_FAILURE;
            }
            of << descriptors << endl;
            of.close();
            return EXIT_SUCCESS;
        }
    }
    else
    {
        IceUtilInternal::ifstream in(inputFile);
        char buff[1024];
        while(true)
        {
            in.read(buff, 1024);
            descriptors.append(buff, static_cast<size_t>(in.gcount()));
            if(in.gcount() < 1024)
            {
                break;
            }
        }
        in.close();
    }
    FreezeScript::ValueFactoryPtr valueFactory = new FreezeScript::ValueFactory;
    communicator->getValueFactoryManager()->add(valueFactory, "");

    DbEnv dbEnv(0);
    DbTxn* txn = 0;
    Freeze::ConnectionPtr connection;
    int status = EXIT_SUCCESS;
    try
    {
#ifdef _WIN32
        //
        // Berkeley DB may use a different C++ runtime.
        //
        dbEnv.set_alloc(::malloc, ::realloc, ::free);
#endif

        //
        // Open the database environment and start a transaction.
        //
        {
            u_int32_t flags = DB_THREAD | DB_CREATE | DB_INIT_TXN | DB_INIT_MPOOL;
            dbEnv.open(dbEnvName.c_str(), flags, FREEZE_SCRIPT_DB_MODE);
        }

        //
        // We're creating a connection just to make sure the database environment
        // isn't locked.
        //
        connection = Freeze::createConnection(communicator, dbEnvName, dbEnv);

        dbEnv.txn_begin(0, &txn, 0);

        FreezeScript::ErrorReporterPtr errorReporter = new FreezeScript::ErrorReporter(cerr, false);
        try
        {
            FreezeScript::DataFactoryPtr factory = new FreezeScript::DataFactory(communicator, unit, errorReporter);
            FreezeScript::DescriptorHandler dh(factory, unit, errorReporter, valueFactory);

            istringstream istr(descriptors);
            IceXML::Parser::parse(istr, dh);

            FreezeScript::DumpDBDescriptorPtr descriptor = dh.descriptor();
            descriptor->validate();

            if(evictor)
            {
                //
                // The evictor database file contains multiple databases. We must first
                // determine the names of those databases, ignoring any whose names
                // begin with "$index:". Each database represents a separate facet, with
                // the facet name used as the database name. The database named "$default"
                // represents the main object.
                //
                vector<string> dbNames;
                {
                    Db db(&dbEnv, 0);
                    db.open(txn, dbName.c_str(), 0, DB_UNKNOWN, DB_RDONLY, 0);
                    Dbt dbKey, dbValue;
                    dbKey.set_flags(DB_DBT_MALLOC);
                    dbValue.set_flags(DB_DBT_USERMEM | DB_DBT_PARTIAL);

                    Dbc* dbc = 0;
                    db.cursor(txn, &dbc, 0);

                    while(dbc->get(&dbKey, &dbValue, DB_NEXT) == 0)
                    {
                        string s(static_cast<char*>(dbKey.get_data()), dbKey.get_size());
                        if(s.find("$index:") != 0)
                        {
                            dbNames.push_back(s);
                        }
                        free(dbKey.get_data());
                    }

                    dbc->close();
                    db.close(0);
                }

                //
                // Dump each database.
                //
                for(vector<string>::iterator p = dbNames.begin(); p != dbNames.end(); ++p)
                {
                    string name = *p;
                    string facet = (name == "$default" ? string("") : name);
                    Db db(&dbEnv, 0);
                    db.open(txn, dbName.c_str(), name.c_str(), DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE);
                    descriptor->dump(communicator, &db, txn, facet);
                    db.close(0);
                }
            }
            else
            {
                //
                // Dump a map database.
                //
                Db db(&dbEnv, 0);
                db.open(txn, dbName.c_str(), 0, DB_BTREE, DB_RDONLY, FREEZE_SCRIPT_DB_MODE);
                descriptor->dump(communicator, &db, txn, "");
                db.close(0);
            }
        }
        catch(const IceXML::ParserException& ex)
        {
            errorReporter->error(ex.reason());
        }
    }
    catch(const DbException& ex)
    {
        cerr << appName << ": database error: " << ex.what() << endl;
        status = EXIT_FAILURE;
    }
    catch(...)
    {
        try
        {
            if(txn)
            {
                txn->abort();
            }
            dbEnv.close(0);
        }
        catch(const DbException& ex)
        {
            cerr << appName << ": database error: " << ex.what() << endl;
        }
        if(connection)
        {
            connection->close();
            connection = 0;
        }
        throw;
    }

    try
    {
        if(txn)
        {
            txn->abort();
        }
        if(connection)
        {
            connection->close();
        }
        dbEnv.close(0);
    }
    catch(const DbException& ex)
    {
        cerr << appName << ": database error: " << ex.what() << endl;
        status = EXIT_FAILURE;
    }

    return status;
}
Пример #26
0
bool CDB::Rewrite(const string& strFile, BerkerleyDBUpgradeProgress &progress, const char* pszSkip, int previousVer, int currentVer)
{
    while (!fShutdown)
    {
        {
            LOCK(bitdb.cs_db);
            if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
            {
                // Flush log data to the dat file
                bitdb.CloseDb(strFile);
                bitdb.CheckpointLSN(strFile);
                bitdb.mapFileUseCount.erase(strFile);

                bool fSuccess = true;
                printf("Rewriting %s...\n", strFile.c_str());
                string strFileRes = strFile + ".rewrite";
                {
                    // surround usage of db with extra {}
                    CDB db(strFile.c_str(), "r");
                    Db* pdbCopy = new Db(&bitdb.dbenv, 0);

                    int ret = pdbCopy->open(NULL,                 // Txn pointer
                                            strFileRes.c_str(),   // Filename
                                            "main",    // Logical db name
                                            DB_BTREE,  // Database type
                                            DB_CREATE,    // Flags
                                            0);
                    if (ret > 0)
                    {
                        printf("Cannot create database file %s\n", strFileRes.c_str());
                        fSuccess = false;
                    }

                    Dbc* pcursor = db.GetCursor();
                    if (pcursor)

                        nTotalBytesCompleted = 0;
                        nProgressPercent = 0;

                        int numRows = 0;

                        CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                        CDataStream ssValue(SER_DISK, CLIENT_VERSION);

                        while (fSuccess)
                        {
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);

                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }

                            numRows++;
                        }

                        db.ReadAtCursor(pcursor, ssKey, ssValue, DB_FIRST);
                        nTotalBytes = numRows;
                        // Set up progress calculations and callbacks.
                        callbackTotalOperationProgress = &progress;
                        ExternalBlockFileProgress callbackProgress;
                        callbackProgress.connect(RewriteProgress);
                        (*callbackTotalOperationProgress)(0.0);

                        fSuccess = true;
                        while (fSuccess)
                        {
                            CDataStream ssKey(SER_DISK, CLIENT_VERSION);
                            CDataStream ssValue(SER_DISK, CLIENT_VERSION);
                            int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT);
                            if (ret == DB_NOTFOUND)
                            {
                                pcursor->close();
                                break;
                            }
                            else if (ret != 0)
                            {
                                pcursor->close();
                                fSuccess = false;
                                break;
                            }

                            /*
                            if (strncmp(&ssKey[0], "\x02tx", 3) != 0)
                            {
                                char* k = &ssKey[0];
                                int xx = 1;
                            }
*/

                            if (pszSkip && strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0)
                                continue;

                            if (strncmp(&ssKey[0], "\x07version", 8) == 0)
                            {
                                // Update version:
                                ssValue.clear();
                                ssValue << currentVer;
                            }

                            // update blockindex to include block hash
                            if (previousVer <= DB_MINVER_INCHASH && strncmp(&ssKey[0], "\nblockindex", 11) == 0)
                            {
                                CDiskBlockIndex diskindex(DB_PREV_VER);
                                ssValue >> diskindex;
                                diskindex.fileVersion = CLIENT_VERSION; // update version

                                /*
                                // Construct block index object
                                CBlockIndex* pindexNew = InsertBlockIndex(blockHash);
                                pindexNew->pprev          = InsertBlockIndex(diskindex.hashPrev);
                                pindexNew->pnext          = InsertBlockIndex(diskindex.hashNext);
                                pindexNew->nFile          = diskindex.nFile;
                                pindexNew->nBlockPos      = diskindex.nBlockPos;
                                pindexNew->nHeight        = diskindex.nHeight;
                                pindexNew->nMint          = diskindex.nMint;
                                pindexNew->nMoneySupply   = diskindex.nMoneySupply;
                                pindexNew->nFlags         = diskindex.nFlags;
                                pindexNew->nStakeModifier = diskindex.nStakeModifier;
                                pindexNew->prevoutStake   = diskindex.prevoutStake;
                                pindexNew->nStakeTime     = diskindex.nStakeTime;
                                pindexNew->hashProofOfStake = diskindex.hashProofOfStake;
                                pindexNew->nVersion       = diskindex.nVersion;
                                pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
                                pindexNew->nTime          = diskindex.nTime;
                                pindexNew->nBits          = diskindex.nBits;
                                pindexNew->nNonce         = diskindex.nNonce;
                                */
                                uint256 blockHash = diskindex.GetBlockHash(); // calc hash (force)
                                ssValue << diskindex; // serialize
                            }

                            Dbt datKey(&ssKey[0], ssKey.size());
                            Dbt datValue(&ssValue[0], ssValue.size());
                            (callbackProgress)(1);

                            int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE);
                            if (ret2 > 0)
                                fSuccess = false;
                        }
                    if (fSuccess)
                    {
                        db.Close();
                        bitdb.CloseDb(strFile);
                        if (pdbCopy->close(0))
                            fSuccess = false;
                        delete pdbCopy;
                    }
                }
                if (fSuccess)
                {
                    Db dbA(&bitdb.dbenv, 0);
                    if (dbA.remove(strFile.c_str(), NULL, 0))
                        fSuccess = false;
                    Db dbB(&bitdb.dbenv, 0);
                    if (dbB.rename(strFileRes.c_str(), NULL, strFile.c_str(), 0))
                        fSuccess = false;
                }
                if (!fSuccess)
                    printf("Rewriting of %s FAILED!\n", strFileRes.c_str());
                return fSuccess;
            }
        }
Пример #27
0
/* Get all scores of a certain patient. 
 * Returns 0 if everything is ok;
 * returns -1 if permission is denied, and error message is not sent out successfully;
 * returns  1 if permission is denied, but error message is sent out successfully;
 * returns -2 if patient ID is invalid, and error message is not sent out successfully;
 * returns  2 if patient ID is invalid, but error message is sent out successfully;
 * returns -3 if error occurs when searching score value table, and error message is not sent out successfully;
 * returns  3 if error occurs when searching score value table, but error message is sent out successfully;
 * returns -4 if no score value record is found, and error message is not sent out successfully;
 * returns  4 if no score value record is found, but error message is sent out successfully;
 * returns -5 if data size message is not sent out successfully;
 * returns -6 if score value data are not sent out successfully;
 * returns -7 if no session is available, and the message is not sent out successfully;
 * returns -8 if error occurs when searching session table, and error message is not sent out successfully;
 * returns  8 if error occurs when searching session table, but error message is sent out successfully;
 * returns -9 if session data are not sent out successfully. */
int srvSession::sendPatientScores()
{
  if (!permissions.size()) {
    statMsg = "Permission denied";
    if (sendStatMsg())
      return -1;
    return 1;
  }

  // send error message to client if patient ID is invalid or score values not found
  int32 pID;
  bool conv_stat = str2num(c_tokens[1], pID);
  if (!conv_stat || pID <= 0) {
    statMsg = "no_data: Invalid patient ID " + c_tokens[1];
    if (sendStatMsg())
      return -2;
    return 2;
  }

  // get score values
  set<int32> sid_set;
  DbTxn* txn = NULL;
  dbs.env.getEnv()->txn_begin(NULL, &txn, 0);
  Dbc* cursorp = NULL;
  if (dbs.scoreValueDB.getDb().cursor(txn, &cursorp, 0)) {
    txn->abort();    
    statMsg = "no_data: db error when searching score value table";
    if (sendStatMsg())
      return -3;
    return 3;
  }

  // Iterate over score values table
  Dbt key, data;
  int ret;
  int32 status = 0;
  while ((ret = cursorp->get(&key, &data, DB_NEXT_NODUP)) == 0) {
    DBscorevalue svData;
    svData.deserializeHdr(data.get_data());
    if (pID != svData.patient || svData.deleted)
      continue;
    string tmpPerm = getMaxPerm(svData, permissions);
    if (tmpPerm.empty())
      continue;
    
    /* Add session IDs into session_list vector (session 0 is ignored here 
     * because this session doesn't exist in session table anyway) */
    int32 sess_id = svData.sessionid;
    if (sess_id)
      sid_set.insert(sess_id);	

    // Add real score value records into DBscorevalue vector.
    status = 1;
    uint32 dat_size = data.get_size();
    statMsg = "scorevalue: " + num2str(dat_size) + " " + tmpPerm;
    if (sendStatMsg()) {
      cursorp->close();
      txn->abort();
      return -4;
    }
    if (sendBuffer(g_session, dat_size, (char*) data.get_data())) {
      statMsg = "Error when sending score value to client";
      cursorp->close();
      txn->abort();
      return -4;
    }
  }

  // Returns -1 if ret is non-zero and it doesn't reach the end of table 
  if (ret && ret != DB_NOTFOUND) {
    cursorp->close();
    txn->abort();    
    statMsg = "no_data: db error when searching score value table";
    if (sendStatMsg())
      return -3;
    return 3;
  }

  cursorp->close();

  if (status == 0) {
    txn->commit(0);    
    statMsg = "no_scorevalue";
    if (sendStatMsg())
      return -5;
    return 5;
  }

  // If session ID list is empty, tell client that no session info sent out
  if (sid_set.size() == 0) {
    txn->commit(0);
    statMsg = "no_session";
    if (sendStatMsg())
      return -7;
    return 0;
  }

  // get related DBsession
  vector<DBsession> sessList;
  int32 dat_size = getSessions(dbs.sessionDB, txn, sid_set, sessList);
  // Note that dat_size may be zero if all score values are static
  if (dat_size <= 0) { 
    txn->abort();
    statMsg = "no_data: Session record not found";
    if (sendStatMsg())
      return -8;
    return 8;
  }
  
  txn->commit(0);
  // send session data to client
  char sess_buff[dat_size];
  serialize(sessList, sess_buff);
  if (sendData(dat_size, sess_buff)) {
    statMsg = "Error when sending patient session data to client: " + statMsg;
    return -9;
  }
   
  return 0;
}