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; }
/* Bulk fill a database. */ void BulkExample::bulkUpdate( int num, int dups, int *countp, int *iterp, int verbose) { Dbt key, data; u_int32_t flag; DbTxn *txnp; int count, i, iter, ret; DbMultipleDataBuilder *ptrd, *ptrk; DbMultipleKeyDataBuilder *ptrkd; txnp = NULL; count = flag = iter = ret = 0; ptrk = ptrd = NULL; if (data_val == NULL) data_val = (struct data *)malloc(DATALEN); memset(data_val, 0, DATALEN); memset(&key, 0, sizeof(Dbt)); memset(&data, 0, sizeof(Dbt)); /* * The buffer must be at least as large as the page size of * the underlying database and aligned for unsigned integer * access. Its size must be a multiple of 1024 bytes. */ if (klen != (u_int32_t) UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024) { klen = (u_int32_t) UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024; kbuf = realloc(kbuf, klen); } memset(kbuf, 0, klen); key.set_ulen(klen); key.set_flags(DB_DBT_USERMEM | DB_DBT_BULK); key.set_data(kbuf); if (dlen != (u_int32_t) UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024) { dlen = (u_int32_t) UPDATES_PER_BULK_PUT * (sizeof(u_int32_t) + DATALEN) * 1024; dbuf = realloc(dbuf, dlen); } memset(dbuf, 0, dlen); data.set_ulen(dlen); data.set_flags(DB_DBT_USERMEM | DB_DBT_BULK); data.set_data(dbuf); /* * Bulk insert with either DB_MULTIPLE in two buffers or * DB_MULTIPLE_KEY in a single buffer. With DB_MULTIPLE, all keys are * constructed in the key Dbt, and all data is constructed in the data * Dbt. With DB_MULTIPLE_KEY, all key/data pairs are constructed in the * key Dbt. We use DB_MULTIPLE mode when there are duplicate records. */ flag |= (dups) ? DB_MULTIPLE : DB_MULTIPLE_KEY; if (dups) { ptrk = new DbMultipleDataBuilder(key); ptrd = new DbMultipleDataBuilder(data); } else ptrkd = new DbMultipleKeyDataBuilder(key); try { for (i = 0; i < num; i++) { if (i % UPDATES_PER_BULK_PUT == 0) { if (txnp != NULL) { ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); } if ((ret = dbenv->txn_begin(NULL, &txnp, 0)) != 0) throwException(dbenv, NULL, ret, "DB_ENV->txn_begin"); } data_val->id = 0; get_string(tstring, data_val->str, i); do { if (dups) { if (ptrk->append(&i, sizeof(i)) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleDataBuilder->append"); if (ptrd->append(data_val, DATALEN) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleDataBuilder->append"); } else { if (ptrkd->append(&i, sizeof(i), data_val, DATALEN) == false) throwException(dbenv, txnp, EXIT_FAILURE, "DbMultipleKeyDataBuilder->append"); } if (verbose) printf( "Insert key: %d, \t data: (id %d, str %s)\n", i, data_val->id, data_val->str); count++; } while (data_val->id++ < dups); if ((i + 1) % UPDATES_PER_BULK_PUT == 0) { if ((ret = dbp->put(txnp, &key, &data, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->put"); iter++; if (dups) { ptrk = new DbMultipleDataBuilder(key); ptrd = new DbMultipleDataBuilder(data); } else ptrkd = new DbMultipleKeyDataBuilder(key); } } if ((num % UPDATES_PER_BULK_PUT) != 0) { if ((ret = dbp->put(txnp, &key, &data, flag)) != 0) throwException(dbenv, txnp, ret, "Bulk DB->put"); iter++; } ret = txnp->commit(0); txnp = NULL; if (ret != 0) throwException(dbenv, NULL, ret, "DB_TXN->commit"); *countp = count; *iterp = iter; } catch (DbException &dbe) { cerr << "bulkUpdate " << dbe.what() << endl; if (txnp != NULL) (void)txnp->abort(); throw dbe; } }
// A function that performs a series of writes to a // Berkeley DB database. The information written // to the database is largely nonsensical, but the // mechanism of transactional commit/abort and // deadlock detection is illustrated here. void * writerThread(void *args) { int j, thread_num; int max_retries = 20; // Max retry on a deadlock const char *key_strings[] = {"key 1", "key 2", "key 3", "key 4", "key 5", "key 6", "key 7", "key 8", "key 9", "key 10"}; Db *dbp = (Db *)args; DbEnv *envp = dbp->get_env(); // Get the thread number (void)mutex_lock(&thread_num_lock); global_thread_num++; thread_num = global_thread_num; (void)mutex_unlock(&thread_num_lock); // Initialize the random number generator srand(thread_num); // Perform 50 transactions for (int i=0; i<50; i++) { DbTxn *txn; bool retry = true; int retry_count = 0; // while loop is used for deadlock retries while (retry) { // try block used for deadlock detection and // general db exception handling try { // Begin our transaction. We group multiple writes in // this thread under a single transaction so as to // (1) show that you can atomically perform multiple // writes at a time, and (2) to increase the chances // of a deadlock occurring so that we can observe our // deadlock detection at work. // Normally we would want to avoid the potential for // deadlocks, so for this workload the correct thing // would be to perform our puts with autocommit. But // that would excessively simplify our example, so we // do the "wrong" thing here instead. txn = NULL; envp->txn_begin(NULL, &txn, 0); // Perform the database write for this transaction. for (j = 0; j < 10; j++) { Dbt key, value; key.set_data((void *)key_strings[j]); key.set_size((u_int32_t)strlen(key_strings[j]) + 1); int payload = rand() + i; value.set_data(&payload); value.set_size(sizeof(int)); // Perform the database put dbp->put(txn, &key, &value, 0); } // countRecords runs a cursor over the entire database. // We do this to illustrate issues of deadlocking std::cout << thread_num << " : Found " << countRecords(dbp, NULL) << " records in the database." << std::endl; std::cout << thread_num << " : committing txn : " << i << std::endl; // commit try { txn->commit(0); retry = false; txn = NULL; } catch (DbException &e) { std::cout << "Error on txn commit: " << e.what() << std::endl; } } catch (DbDeadlockException &) { // First thing that we MUST do is abort the transaction. if (txn != NULL) (void)txn->abort(); // Now we decide if we want to retry the operation. // If we have retried less than max_retries, // increment the retry count and goto retry. if (retry_count < max_retries) { std::cout << "############### Writer " << thread_num << ": Got DB_LOCK_DEADLOCK.\n" << "Retrying write operation." << std::endl; retry_count++; retry = true; } else { // Otherwise, just give up. std::cerr << "Writer " << thread_num << ": Got DeadLockException and out of " << "retries. Giving up." << std::endl; retry = false; } } catch (DbException &e) { std::cerr << "db put failed" << std::endl; std::cerr << e.what() << std::endl; if (txn != NULL) txn->abort(); retry = false; } catch (std::exception &ee) { std::cerr << "Unknown exception: " << ee.what() << std::endl; return (0); } } } return (0); }
int RepMgr::doloop() { Db *dbp; Dbt key, data; char buf[BUFSIZE], *rbuf; int ret; dbp = NULL; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); ret = 0; for (;;) { if (dbp == NULL) { dbp = new Db(&dbenv, 0); try { dbp->open(NULL, DATABASE, NULL, DB_BTREE, DB_CREATE | DB_AUTO_COMMIT, 0); } catch(DbException dbe) { dbenv.err(ret, "DB->open"); throw dbe; } } cout << "QUOTESERVER" ; cout << "> " << flush; if (fgets(buf, sizeof(buf), stdin) == NULL) break; if (strtok(&buf[0], " \t\n") == NULL) { switch ((ret = print_stocks(dbp))) { case 0: continue; default: dbp->err(ret, "Error traversing data"); goto err; } } rbuf = strtok(NULL, " \t\n"); if (rbuf == NULL || rbuf[0] == '\0') { if (strncmp(buf, "exit", 4) == 0 || strncmp(buf, "quit", 4) == 0) break; dbenv.errx("Format: TICKER VALUE"); continue; } key.set_data(buf); key.set_size((u_int32_t)strlen(buf)); data.set_data(rbuf); data.set_size((u_int32_t)strlen(rbuf)); if ((ret = dbp->put(NULL, &key, &data, 0)) != 0) { dbp->err(ret, "DB->put"); if (ret != DB_KEYEXIST) goto err; } } err: if (dbp != NULL) (void)dbp->close(DB_NOSYNC); return (ret); }
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; } }
int main(int argc, char *argv[]) { try { Db *db = new Db(NULL, 0); db->open(NULL, "my.db", NULL, DB_BTREE, DB_CREATE, 0644); // populate our massive database. // all our strings include null for convenience. // Note we have to cast for idiomatic // usage, since newer gcc requires it. Dbt *keydbt = new Dbt((char*)"key", 4); Dbt *datadbt = new Dbt((char*)"data", 5); db->put(NULL, keydbt, datadbt, 0); // Now, retrieve. We could use keydbt over again, // but that wouldn't be typical in an application. Dbt *goodkeydbt = new Dbt((char*)"key", 4); Dbt *badkeydbt = new Dbt((char*)"badkey", 7); Dbt *resultdbt = new Dbt(); resultdbt->set_flags(DB_DBT_MALLOC); int ret; if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { cout << "get: " << DbEnv::strerror(ret) << "\n"; } else { char *result = (char *)resultdbt->get_data(); cout << "got data: " << result << "\n"; } if ((ret = db->get(NULL, badkeydbt, resultdbt, 0)) != 0) { // We expect this... cout << "get using bad key: " << DbEnv::strerror(ret) << "\n"; } else { char *result = (char *)resultdbt->get_data(); cout << "*** got data using bad key!!: " << result << "\n"; } // Now, truncate and make sure that it's really gone. cout << "truncating data...\n"; u_int32_t nrecords; db->truncate(NULL, &nrecords, 0); cout << "truncate returns " << nrecords << "\n"; if ((ret = db->get(NULL, goodkeydbt, resultdbt, 0)) != 0) { // We expect this... cout << "after truncate get: " << DbEnv::strerror(ret) << "\n"; } else { char *result = (char *)resultdbt->get_data(); cout << "got data: " << result << "\n"; } db->close(0); cout << "finished test\n"; } catch (DbException &dbe) { cerr << "Db Exception: " << dbe.what(); } return 0; }
int main(int argc, const char* argv[]) { if (argc !=3) { cout << "usage: "<< argv[0] << " <filename> <db filename>" << endl; return 1; } const char* kDatabaseName = argv[2]; const char* filename = argv[1]; DbEnv env(0); Db* pdb; string line; bool datamode = false; try { env.set_error_stream(&cerr); env.open("./", DB_CREATE | DB_INIT_MPOOL, 0); pdb = new Db(&env, 0); // If you want to support duplicated records and make duplicated // records sorted by data, you need to call: // pdb->set_flags(DB_DUPSORT); // Note that only Btree-typed database supports sorted duplicated // records // If the database does not exist, create it. If it exists, clear // its content after openning. pdb->set_flags( DB_DUP );// | DB_DUPSORT); pdb->open(NULL, kDatabaseName, NULL, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0); ifstream myfile (filename); if (myfile.is_open()) { int count = 0; while ( myfile.good() ) { //if (count++ > 10) { // break; //} getline (myfile,line); if (!datamode) { if ("[DATA]" == line ) { datamode = true; } continue; } //cout << (int)line[8] << endl; int index = 0; while (32 != (char)line[index]) { index++; } string cjkey = line.substr(0, index); while (32 == line[index]) { index++; } string cjdata = line.substr(index, (line.size()-index)); cout << cjkey << "---" << cjdata << endl; Dbt key(const_cast<char*>(cjkey.data()), cjkey.size()); Dbt value(const_cast<char*>(cjdata.data()), cjdata.size()); pdb->put(NULL, &key, &value, 0); } myfile.close(); } else { cout << "Unable to open file"; } // You need to set ulen and flags=DB_DBT_USERMEM to prevent Dbt // from allocate its own memory but use the memory provided by you. string search("aa"); Dbt key(const_cast<char*>(search.c_str()), search.size()); char buffer[1024]; Dbt data; data.set_data(buffer); data.set_ulen(1024); data.set_flags(DB_DBT_USERMEM); if (pdb->get(NULL, &key, &data, 0) == DB_NOTFOUND) { cerr << "Not found" << endl; } else { cout << "Found: " << "PPPPPP" <<buffer << "PPPPPP" << endl; } if (pdb != NULL) { pdb->close(0); delete pdb; // You have to close and delete an exisiting handle, then create // a new one before you can use it to remove a database (file). pdb = new Db(NULL, 0); //pdb->remove("access.db", NULL, 0); delete pdb; } env.close(0); } catch (DbException& e) { cerr << "DbException: " << e.what() << endl; return -1; } catch (std::exception& e) { cerr << e.what() << endl; return -1; } return 0; }
int RepMgrGSG::doloop() { Dbt key, data; Db *dbp; char buf[BUFSIZE], *rbuf; int ret; dbp = 0; memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); ret = 0; for (;;) { if (dbp == 0) { dbp = new Db(&dbenv, 0); try { dbp->open(NULL, DATABASE, NULL, DB_BTREE, app_data.is_master ? DB_CREATE | DB_AUTO_COMMIT : DB_AUTO_COMMIT, 0); } catch(DbException dbe) { // It is expected that this condition will be triggered // when client sites start up. It can take a while for // the master site to be found and synced, and no DB will // be available until then. if (dbe.get_errno() == ENOENT) { cout << "No stock db available yet - retrying." << endl; try { dbp->close(0); } catch (DbException dbe2) { cout << "Unexpected error closing after failed" << " open, message: " << dbe2.what() << endl; dbp = NULL; goto err; } dbp = NULL; sleep(SLEEPTIME); continue; } else { dbenv.err(ret, "DB->open"); throw dbe; } } } cout << "QUOTESERVER" ; if (!app_data.is_master) cout << "(read-only)"; cout << "> " << flush; if (fgets(buf, sizeof(buf), stdin) == NULL) break; if (strtok(&buf[0], " \t\n") == NULL) { switch ((ret = print_stocks(dbp))) { case 0: continue; case DB_REP_HANDLE_DEAD: (void)dbp->close(DB_NOSYNC); cout << "closing db handle due to rep handle dead" << endl; dbp = NULL; continue; default: dbp->err(ret, "Error traversing data"); goto err; } } rbuf = strtok(NULL, " \t\n"); if (rbuf == NULL || rbuf[0] == '\0') { if (strncmp(buf, "exit", 4) == 0 || strncmp(buf, "quit", 4) == 0) break; dbenv.errx("Format: TICKER VALUE"); continue; } if (!app_data.is_master) { dbenv.errx("Can't update at client"); continue; } key.set_data(buf); key.set_size((u_int32_t)strlen(buf)); data.set_data(rbuf); data.set_size((u_int32_t)strlen(rbuf)); if ((ret = dbp->put(NULL, &key, &data, 0)) != 0) { dbp->err(ret, "DB->put"); if (ret != DB_KEYEXIST) goto err; } } err: if (dbp != 0) { (void)dbp->close(DB_NOSYNC); } return (ret); }
void put(const char* skey, const char* sval){ Dbt key((void*)skey, strlen(skey)); Dbt value((void*)sval, ::strlen(sval)+1); _db->put(nullptr, &key, &value, 0); };
int main(int argc, const char* argv[]) { if (argc !=3) { cout << "usage: "<< argv[0] << " <filename> <db filename>" << endl; return 1; } const char* kDatabaseName = argv[2]; const char* filename = argv[1]; DbEnv env(0); Db* pdb; string line; try { env.set_error_stream(&cerr); env.open("./", DB_CREATE | DB_INIT_MPOOL, 0); pdb = new Db(&env, 0); // If you want to support duplicated records and make duplicated // records sorted by data, you need to call: // pdb->set_flags(DB_DUPSORT); // Note that only Btree-typed database supports sorted duplicated // records // If the database does not exist, create it. If it exists, clear // its content after openning. //pdb->set_flags( DB_DUP );// | DB_DUPSORT); pdb->open(NULL, kDatabaseName, NULL, DB_BTREE, DB_CREATE | DB_TRUNCATE, 0); ifstream myfile (filename); if (myfile.is_open()) { while ( myfile.good() ) { getline (myfile,line); // Ignore empty and commented lines if ((line.length() == 0) || (startswith(line, std::string("#")))) { continue; } std::vector<std::string> cj = split(line, ' '); int freq = atoi(cj[1].c_str()); Dbt key(const_cast<char*>(cj[0].data()), cj[0].size()); Dbt value(&freq, sizeof(int)); pdb->put(NULL, &key, &value, 0); } myfile.close(); } else { cout << "Unable to open file"; } // You need to set ulen and flags=DB_DBT_USERMEM to prevent Dbt // from allocate its own memory but use the memory provided by you. if (pdb != NULL) { pdb->close(0); delete pdb; } env.close(0); } catch (DbException& e) { cerr << "DbException: " << e.what() << endl; return -1; } catch (std::exception& e) { cerr << e.what() << endl; return -1; } return 0; }