Iterator* LMDBEngine::Find(const Slice& findkey, bool cache) { MDB_val k, data; k.mv_data = const_cast<char*>(findkey.data()); k.mv_size = findkey.size(); MDB_cursor *cursor = NULL; int rc = 0; LMDBContext& holder = m_ctx_local.GetValue(); if (NULL == holder.readonly_txn) { rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &holder.readonly_txn); if (rc != 0) { ERROR_LOG("Failed to create txn for iterator for reason:%s", mdb_strerror(rc)); holder.readonly_txn = NULL; return NULL; } } holder.readonly_txn_ref++; rc = mdb_cursor_open(holder.readonly_txn, m_dbi, &cursor); if (0 != rc) { ERROR_LOG("Failed to create cursor for reason:%s", mdb_strerror(rc)); CloseTransaction(); return NULL; } rc = mdb_cursor_get(cursor, &k, &data, MDB_SET_RANGE); LMDBIterator* iter = new LMDBIterator(this, cursor, rc == 0); return iter; }
/** * Return next source. Error if no next. */ std::string next_source(const std::string& file_binary_hash) const { if (file_binary_hash == "") { // program error to ask for next when at end std::cerr << "Usage error: the file_binary_hash value provided to next_source is empty.\n"; return ""; } // get context hashdb::lmdb_context_t context(env, false, false); context.open(); // set the cursor to last file binary hash context.key.mv_size = file_binary_hash.size(); context.key.mv_data = static_cast<void*>(const_cast<char*>(file_binary_hash.c_str())); int rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_SET_KEY); // the last file binary hash must exist if (rc == MDB_NOTFOUND) { std::cerr << "Usage error: the file_binary_hash value provided to next_source does not exist.\n"; context.close(); return ""; } // the attempt to read the last file binary hash must work if (rc != 0) { std::cerr << "LMDB error: " << mdb_strerror(rc) << "\n"; assert(0); } // move cursor to this file binary hash rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_NEXT_NODUP); if (rc == MDB_NOTFOUND) { // no values for this file binary hash context.close(); return ""; } else if (rc == 0) { #ifdef DEBUG_LMDB_HASH_DATA_MANAGER_HPP print_mdb_val("source_id_manager find_next key", context.key); print_mdb_val("source_id_manager find_next data", context.data); #endif // return the next file binary hash std::string next_file_binary_hash = std::string( static_cast<char*>(context.key.mv_data), context.key.mv_size); context.close(); return next_file_binary_hash; } else { // invalid rc std::cerr << "LMDB error: " << mdb_strerror(rc) << "\n"; assert(0); return ""; // for mingw } }
bool LmdbDataset<K, V, KCoder, VCoder>::commit() { DLOG(INFO) << "LMDB: Commit"; CHECK_NOTNULL(write_txn_); int retval; retval = mdb_txn_commit(write_txn_); if (MDB_SUCCESS != retval) { LOG(ERROR) << "mdb_txn_commit failed " << mdb_strerror(retval); return false; } mdb_txn_abort(read_txn_); retval = mdb_txn_begin(env_, NULL, 0, &write_txn_); if (MDB_SUCCESS != retval) { LOG(ERROR) << "mdb_txn_begin failed " << mdb_strerror(retval); return false; } retval = mdb_txn_begin(env_, NULL, MDB_RDONLY, &read_txn_); if (MDB_SUCCESS != retval) { LOG(ERROR) << "mdb_txn_begin failed " << mdb_strerror(retval); return false; } return true; }
long gcache_get(struct gcache *gc, char *k, char *buf, long buflen) { MDB_val key, data; MDB_txn *txn; int rc; long len = -1; if (gc == NULL) return (-1); rc = mdb_txn_begin(gc->env, NULL, MDB_RDONLY, &txn); if (rc) { olog(LOG_ERR, "gcache_get: mdb_txn_begin: (%d) %s", rc, mdb_strerror(rc)); return (-1); } key.mv_data = k; key.mv_size = strlen(k); rc = mdb_get(txn, gc->dbi, &key, &data); if (rc != 0) { if (rc != MDB_NOTFOUND) { printf("get: %s\n", mdb_strerror(rc)); } else { // printf(" [%s] not found\n", k); } } else { len = (data.mv_size < buflen) ? data.mv_size : buflen; memcpy(buf, data.mv_data, len); // printf("%s\n", (char *)data.mv_data); } mdb_txn_commit(txn); return (len); }
int gcache_del(struct gcache *gc, char *keystr) { int rc; MDB_val key; MDB_txn *txn; rc = mdb_txn_begin(gc->env, NULL, 0, &txn); if (rc != 0) { olog(LOG_ERR, "gcache_del: mdb_txn_begin: %s", mdb_strerror(rc)); return (rc); } key.mv_data = keystr; key.mv_size = strlen(keystr); rc = mdb_del(txn, gc->dbi, &key, NULL); if (rc != 0 && rc != MDB_NOTFOUND) { olog(LOG_ERR, "gcache_del: mdb_del: %s", mdb_strerror(rc)); /* fall through to commit */ } rc = mdb_txn_commit(txn); if (rc) { olog(LOG_ERR, "gcache_del: mdb_txn_commit: (%d) %s", rc, mdb_strerror(rc)); mdb_txn_abort(txn); } return (rc); }
bool B_ACCURATE_LMDB::end_load(JCR *jcr) { int result; /* * Commit any pending write transactions. */ if (m_db_rw_txn) { result = mdb_txn_commit(m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); return false; } result = mdb_txn_begin(m_db_env, NULL, 0, &m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create write transaction: %s\n"), mdb_strerror(result)); return false; } } /* * From now on we also will be doing read transactions so create a read transaction context. */ if (!m_db_ro_txn) { result = mdb_txn_begin(m_db_env, NULL, MDB_RDONLY, &m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to create read transaction: %s\n"), mdb_strerror(result)); return false; } } return true; }
typename LmdbDataset<K, V, KCoder, VCoder>::const_iterator LmdbDataset<K, V, KCoder, VCoder>::begin() const { int retval; MDB_txn* iter_txn; retval = mdb_txn_begin(env_, NULL, MDB_RDONLY, &iter_txn); CHECK_EQ(MDB_SUCCESS, retval) << "mdb_txn_begin failed " << mdb_strerror(retval); MDB_cursor* cursor; retval = mdb_cursor_open(iter_txn, dbi_, &cursor); CHECK_EQ(retval, MDB_SUCCESS) << mdb_strerror(retval); MDB_val key; MDB_val val; retval = mdb_cursor_get(cursor, &key, &val, MDB_FIRST); CHECK(MDB_SUCCESS == retval || MDB_NOTFOUND == retval) << mdb_strerror(retval); shared_ptr<DatasetState> state; if (MDB_SUCCESS == retval) { state.reset(new LmdbState(cursor, iter_txn, &dbi_)); } return const_iterator(this, state); }
bool LmdbDataset<K, V, KCoder, VCoder>::last_key(K* key) { DLOG(INFO) << "LMDB: Last key"; int retval; MDB_txn* iter_txn; retval = mdb_txn_begin(env_, NULL, MDB_RDONLY, &iter_txn); CHECK_EQ(MDB_SUCCESS, retval) << "mdb_txn_begin failed " << mdb_strerror(retval); MDB_cursor* cursor; retval = mdb_cursor_open(iter_txn, dbi_, &cursor); CHECK_EQ(retval, MDB_SUCCESS) << mdb_strerror(retval); MDB_val mdbkey; MDB_val mdbval; retval = mdb_cursor_get(cursor, &mdbkey, &mdbval, MDB_LAST); CHECK_EQ(retval, MDB_SUCCESS) << mdb_strerror(retval); mdb_cursor_close(cursor); mdb_txn_abort(iter_txn); if (!KCoder::deserialize(reinterpret_cast<char*>(mdbkey.mv_data), mdbkey.mv_size, key)) { LOG(ERROR) << "failed to deserialize key"; return false; } return true; }
bool B_ACCURATE_LMDB::send_base_file_list(JCR *jcr) { int result; int32_t LinkFIc; FF_PKT *ff_pkt; MDB_cursor *cursor; MDB_val key, data; bool retval = false; accurate_payload *payload; int stream = STREAM_UNIX_ATTRIBUTES; if (!jcr->accurate || jcr->getJobLevel() != L_FULL) { return true; } /* * Commit any pending write transactions. */ if (m_db_rw_txn) { result = mdb_txn_commit(m_db_rw_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable close write transaction: %s\n"), mdb_strerror(result)); goto bail_out; } m_db_rw_txn = NULL; } ff_pkt = init_find_files(); ff_pkt->type = FT_BASE; result = mdb_cursor_open(m_db_ro_txn, m_db_dbi, &cursor); if (result == 0) { while ((result = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { payload = (accurate_payload *)data.mv_data; if (bit_is_set(payload->filenr, m_seen_bitmap)) { Dmsg1(dbglvl, "base file fname=%s\n", key.mv_data); decode_stat(payload->lstat, &ff_pkt->statp, sizeof(struct stat), &LinkFIc); /* decode catalog stat */ ff_pkt->fname = (char *)key.mv_data; encode_and_send_attributes(jcr, ff_pkt, stream); } } mdb_cursor_close(cursor); } else { Jmsg1(jcr, M_FATAL, 0, _("Unable create cursor: %s\n"), mdb_strerror(result)); } mdb_txn_reset(m_db_ro_txn); result = mdb_txn_renew(m_db_ro_txn); if (result != 0) { Jmsg1(jcr, M_FATAL, 0, _("Unable to renew read transaction: %s\n"), mdb_strerror(result)); goto bail_out; } retval = true; bail_out: term_find_files(ff_pkt); return retval; }
/** * Find entry just after this one. */ lmdb_hash_it_data_t find_next(const lmdb_hash_it_data_t& hash_it_data) const { // get context lmdb_context_t context(env, false, true); context.open(); // set key lmdb_helper::point_to_string(hash_it_data.binary_hash, context.key); // truncate key if truncation is used and binary_hash is longer if (hash_truncation != 0 && context.key.mv_size > hash_truncation) { context.key.mv_size = hash_truncation; } // set data std::string encoding = lmdb_data_codec::encode_hash_data( lmdb_hash_data_t(hash_it_data.source_lookup_index, hash_it_data.file_offset / byte_alignment, hash_it_data.hash_label)); lmdb_helper::point_to_string(encoding, context.data); // set the cursor to this key,data pair which must exist int rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_GET_BOTH); if (rc != 0) { // invalid usage std::cerr << "LMDB find_next error: " << mdb_strerror(rc) << "\n"; assert(0); } // set cursor to next key, data pair rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_NEXT); lmdb_hash_it_data_t it_data; if (rc == 0) { // prepare hash_it_data std::string binary_hash = lmdb_helper::get_string(context.key); std::string next_encoding = lmdb_helper::get_string(context.data); lmdb_hash_data_t hash_data = lmdb_data_codec::decode_hash_data(next_encoding); it_data = lmdb_hash_it_data_t(binary_hash, hash_data.source_id, hash_data.offset_index * byte_alignment, hash_data.hash_label, true); } else if (rc == MDB_NOTFOUND) { // use default it_data for end } else { // program error std::cerr << "LMDB has_next error: " << mdb_strerror(rc) << "\n"; assert(0); } // close context context.close(); return it_data; }
// erase hash, return count erased // note: hashdb does not use erase. size_t erase(const std::string& binary_hash) { // get context lmdb_context_t context(env, true, true); context.open(); // set key lmdb_helper::point_to_string(binary_hash, context.key); // truncate key if truncation is used and binary_hash is longer if (hash_truncation != 0 && context.key.mv_size > hash_truncation) { context.key.mv_size = hash_truncation; } // set the cursor to this key int rc = mdb_cursor_get(context.cursor, &context.key, NULL, MDB_SET_RANGE); size_t key_count; if (rc == 0) { // DB has key so look up the key count rc = mdb_cursor_count(context.cursor, &key_count); if (rc != 0) { std::cerr << "LMDB erase count error: " << mdb_strerror(rc) << "\n"; assert(0); } } else if (rc == MDB_NOTFOUND) { // DB does not have key key_count = 0; } else { std::cerr << "LMDB erase cursor get error: " << mdb_strerror(rc) << "\n"; assert(0); } if (key_count > 0) { // delete rc = mdb_del(context.txn, context.dbi, &context.key, NULL); if (rc != 0) { std::cerr << "LMDB erase delete error: " << mdb_strerror(rc) << "\n"; assert(0); } } // close context context.close(); return key_count; }
int mdb_ad_get( struct mdb_info *mdb, MDB_txn *txn, AttributeDescription *ad ) { int i, rc; MDB_val key, val; rc = mdb_ad_read( mdb, txn ); if (rc) return rc; if ( mdb->mi_adxs[ad->ad_index] ) return 0; i = mdb->mi_numads+1; key.mv_size = sizeof(int); key.mv_data = &i; val.mv_size = ad->ad_cname.bv_len; val.mv_data = ad->ad_cname.bv_val; rc = mdb_put( txn, mdb->mi_ad2id, &key, &val, 0 ); if ( rc == MDB_SUCCESS ) { mdb->mi_adxs[ad->ad_index] = i; mdb->mi_ads[i] = ad; mdb->mi_numads++; } else { Debug( LDAP_DEBUG_ANY, "mdb_ad_get: mdb_put failed %s(%d)\n", mdb_strerror(rc), rc, 0); } return rc; }
/** * Return first file_binary_hash else false and "". */ std::string first_source() const { // get context hashdb::lmdb_context_t context(env, false, false); context.open(); int rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_FIRST); if (rc == 0) { #ifdef DEBUG_LMDB_SOURCE_ID_MANAGER_HPP print_mdb_val("source_id_manager find_begin key", context.key); print_mdb_val("source_id_manager find_begin data", context.data); #endif // return the key std::string file_binary_hash = std::string( static_cast<char*>(context.key.mv_data), context.key.mv_size); context.close(); return file_binary_hash; } else if (rc == MDB_NOTFOUND) { // no hash context.close(); return ""; } else { // invalid rc std::cerr << "LMDB error: " << mdb_strerror(rc) << "\n"; assert(0); return ""; // for mingw } }
bool LmdbDataset<K, V, KCoder, VCoder>::put(const K& key, const V& value) { DLOG(INFO) << "LMDB: Put"; vector<char> serialized_key; if (!KCoder::serialize(key, &serialized_key)) { LOG(ERROR) << "failed to serialize key"; return false; } vector<char> serialized_value; if (!VCoder::serialize(value, &serialized_value)) { LOG(ERROR) << "failed to serialized value"; return false; } MDB_val mdbkey, mdbdata; mdbdata.mv_size = serialized_value.size(); mdbdata.mv_data = serialized_value.data(); mdbkey.mv_size = serialized_key.size(); mdbkey.mv_data = serialized_key.data(); CHECK_NOTNULL(write_txn_); CHECK_NE(0, dbi_); int retval = mdb_put(write_txn_, dbi_, &mdbkey, &mdbdata, 0); if (MDB_SUCCESS != retval) { LOG(ERROR) << "mdb_put failed " << mdb_strerror(retval); return false; } return true; }
int64 LMDBFileIndex::get(const LMDBFileIndex::SIndexKey& key) { begin_txn(MDB_RDONLY); MDB_val mdb_tkey; mdb_tkey.mv_data=const_cast<void*>(static_cast<const void*>(&key)); mdb_tkey.mv_size=sizeof(SIndexKey); MDB_val mdb_tvalue; int rc=mdb_get(txn, dbi, &mdb_tkey, &mdb_tvalue); int64 ret = 0; if(rc==MDB_NOTFOUND) { } else if(rc) { Server->Log("LMDB: Failed to read ("+(std::string)mdb_strerror(rc)+")", LL_ERROR); _has_error=true; } else { CRData data((const char*)mdb_tvalue.mv_data, mdb_tvalue.mv_size); data.getVarInt(&ret); } abort_transaction(); return ret; }
static int lmdb_storage_get(void* handle, iid_t iid, paxos_accepted* out) { struct lmdb_storage* s = handle; int result; MDB_val key, data; memset(&data, 0, sizeof(data)); key.mv_data = &iid; key.mv_size = sizeof(iid_t); if ((result = mdb_get(s->txn, s->dbi, &key, &data)) != 0) { if (result == MDB_NOTFOUND) { paxos_log_debug("There is no record for iid: %d", iid); } else { paxos_log_error("Could not find record for iid: %d : %s", iid, mdb_strerror(result)); } return 0; } paxos_accepted_from_buffer(data.mv_data, out); assert(iid == out->iid); return 1; }
int mdb_next_id( BackendDB *be, MDB_cursor *mc, ID *out ) { struct mdb_info *mdb = (struct mdb_info *) be->be_private; int rc; ID id = 0; MDB_val key; rc = mdb_cursor_get(mc, &key, NULL, MDB_LAST); switch(rc) { case MDB_NOTFOUND: rc = 0; *out = 1; break; case 0: memcpy( &id, key.mv_data, sizeof( id )); *out = ++id; break; default: Debug( LDAP_DEBUG_ANY, "=> mdb_next_id: get failed: %s (%d)\n", mdb_strerror(rc), rc, 0 ); goto done; } mdb->mi_nextid = *out; done: return rc; }
int kvdb_lmdb_get(kvdb_t *kvdb, const char *key, uint32_t klen, void **ppVal, uint32_t *pnVal) { kvdb_lmdb_t *lmdb = (kvdb_lmdb_t*)kvdb; kvenv_lmdb_t *kvenv_lmdb = (kvenv_lmdb_t*)kvdb->kvenv; MDB_val m_key; MDB_txn *txn; m_key.mv_size = klen; m_key.mv_data = (void*)key; int rc = mdb_txn_begin(kvenv_lmdb->env, NULL, MDB_RDONLY, &txn); if( rc==0 ){ MDB_val m_val = {0, 0}; rc = mdb_get(txn, lmdb->dbi, &m_key, &m_val); if ( rc == 0 ) { uint32_t nVal = m_val.mv_size; char *pVal = m_val.mv_data; char *result = (char*)zmalloc(nVal); memcpy(result, pVal, nVal); *ppVal = result; *pnVal = nVal; } else if( rc==MDB_NOTFOUND ){ rc = 0; *ppVal = 0; *pnVal = -1; }else{ error_log("kvdb_lmdb_get() failure. error: %s", mdb_strerror(rc)); } mdb_txn_commit(txn); } return rc; }
common::Error LmdbRaw::put(const std::string& key, const std::string& value) { MDB_val mkey; mkey.mv_size = key.size(); mkey.mv_data = (void*)key.c_str(); MDB_val mval; mval.mv_size = value.size(); mval.mv_data = (void*)value.c_str(); MDB_txn *txn = NULL; int rc = mdb_txn_begin(lmdb_->env, NULL, 0, &txn); if (rc == LMDB_OK) { rc = mdb_put(txn, lmdb_->dbir, &mkey, &mval, 0); if (rc == LMDB_OK) { rc = mdb_txn_commit(txn); } else { mdb_txn_abort(txn); } } if (rc != LMDB_OK) { char buff[1024] = {0}; common::SNPrintf(buff, sizeof(buff), "put function error: %s", mdb_strerror(rc)); return common::make_error_value(buff, common::ErrorValue::E_ERROR); } return common::Error(); }
bool DBPrivWriteCursorEntry(DBCursorPriv *cursor, const void *value, int value_size) { MDB_val data; int rc; cursor->pending_delete = false; data.mv_data = (void *)value; data.mv_size = value_size; if (cursor->curkv) { MDB_val curkey; curkey.mv_data = cursor->curkv; curkey.mv_size = sizeof(cursor->curkv); if ((rc = mdb_cursor_put(cursor->mc, &curkey, &data, MDB_CURRENT)) != MDB_SUCCESS) { Log(LOG_LEVEL_ERR, "Could not write cursor entry: %s", mdb_strerror(rc)); } } else { Log(LOG_LEVEL_ERR, "Could not write cursor entry: cannot find current key"); rc = MDB_INVALID; } return rc == MDB_SUCCESS; }
FreqSchedulerError freq_scheduler_cursor_open(FreqScheduler *sch, MDB_cursor **cursor) { char *error1 = 0; char *error2 = 0; MDB_txn *txn = 0; if (txn_manager_begin(sch->txn_manager, 0, &txn) != 0) { error1 = "starting transaction"; error2 = sch->txn_manager->error->message; goto on_error; } MDB_dbi dbi; int mdb_rc = mdb_dbi_open(txn, "schedule", MDB_CREATE, &dbi) || mdb_set_compare(txn, dbi, schedule_entry_mdb_cmp_asc) || mdb_cursor_open(txn, dbi, cursor); if (mdb_rc != 0) { *cursor = 0; error1 = "opening cursor"; error2 = mdb_strerror(mdb_rc); } return sch->error->code; on_error: if (txn != 0) txn_manager_abort(sch->txn_manager, txn); freq_scheduler_set_error(sch, freq_scheduler_error_internal, __func__); freq_scheduler_add_error(sch, error1); freq_scheduler_add_error(sch, error2); return sch->error->code; }
lmdb_hash_it_data_t find_begin() const { // get context lmdb_context_t context(env, false, true); context.open(); int rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_FIRST); lmdb_hash_it_data_t it_data; if (rc == 0) { // prepare hash_it_data std::string binary_hash = lmdb_helper::get_string(context.key); std::string encoding = lmdb_helper::get_string(context.data); lmdb_hash_data_t hash_data = lmdb_data_codec::decode_hash_data(encoding); it_data = lmdb_hash_it_data_t(binary_hash, hash_data.source_id, hash_data.offset_index * byte_alignment, hash_data.hash_label, true); } else if (rc == MDB_NOTFOUND) { // use default it_data } else { // program error std::cerr << "LMDB find_begin error: " << mdb_strerror(rc) << "\n"; assert(0); } // close context context.close(); return it_data; }
void check(int x) { if(x) { fprintf(stderr, "eek %s\n", mdb_strerror(x)); _exit(1); } }
int LMDBEngine::Get(const Slice& key, std::string* value, bool fill_cache) { MDB_val k, v; k.mv_data = const_cast<char*>(key.data()); k.mv_size = key.size(); int rc; LMDBContext& holder = m_ctx_local.GetValue(); MDB_txn *txn = holder.readonly_txn; if (NULL == holder.readonly_txn) { rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn); if (rc != 0) { ERROR_LOG("Failed to create txn for get for reason:%s", mdb_strerror(rc)); return -1; } } rc = mdb_get(txn, m_dbi, &k, &v); if (NULL == holder.readonly_txn) { mdb_txn_commit(txn); } if (0 == rc && NULL != value && NULL != v.mv_data) { value->assign((const char*) v.mv_data, v.mv_size); } return rc; }
int kvdb_lmdb_put(kvdb_t *kvdb, const char *key, uint32_t klen, void *value, uint32_t vlen) { kvdb_lmdb_t *lmdb = (kvdb_lmdb_t*)kvdb; kvenv_lmdb_t *kvenv_lmdb = (kvenv_lmdb_t*)kvdb->kvenv; MDB_val m_val; MDB_val m_key; MDB_txn *txn; m_val.mv_size = vlen; m_val.mv_data = value; m_key.mv_size = klen; m_key.mv_data = (void*)key; int rc = mdb_txn_begin(kvenv_lmdb->env, NULL, 0, &txn); if( rc==0 ){ rc = mdb_put(txn, lmdb->dbi, &m_key, &m_val, 0); if( rc==0 ){ rc = mdb_txn_commit(txn); }else{ error_log("kvdb_lmdb_put() failure. error: %s", mdb_strerror(rc)); mdb_txn_abort(txn); } } return rc; }
common::Error LmdbRaw::dbsize(size_t* size) { if (!size) { return common::make_error_value("Invalid input argument", common::ErrorValue::E_ERROR); } MDB_cursor *cursor; MDB_txn *txn = NULL; int rc = mdb_txn_begin(lmdb_->env, NULL, MDB_RDONLY, &txn); if (rc == LMDB_OK) { rc = mdb_cursor_open(txn, lmdb_->dbir, &cursor); } if (rc != LMDB_OK) { mdb_txn_abort(txn); char buff[1024] = {0}; common::SNPrintf(buff, sizeof(buff), "dbsize function error: %s", mdb_strerror(rc)); return common::make_error_value(buff, common::ErrorValue::E_ERROR); } MDB_val key; MDB_val data; size_t sz = 0; while (mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == LMDB_OK) { sz++; } mdb_cursor_close(cursor); mdb_txn_abort(txn); *size = sz; return common::Error(); }
KeyValueEngine* LMDBEngineFactory::CreateDB(const std::string& name) { if (!m_env_opened) { make_dir(m_cfg.path); int env_opt = MDB_NOSYNC | MDB_NOMETASYNC | MDB_NOMETASYNC; int rc = mdb_env_open(m_env, m_cfg.path.c_str(), env_opt, 0664); if (rc != 0) { ERROR_LOG("Failed to open mdb:%s\n", mdb_strerror(rc)); return NULL; } m_env_opened = true; } LMDBEngine* engine = new LMDBEngine(); LMDBConfig cfg = m_cfg; if (engine->Init(cfg, m_env, name) != 0) { DELETE(engine); return NULL; } DEBUG_LOG( "Create DB:%s at path:%s success", name.c_str(), cfg.path.c_str()); return engine; }
bool LmdbDataset<K, V, KCoder, VCoder>::get(const K& key, V* value) { DLOG(INFO) << "LMDB: Get"; vector<char> serialized_key; if (!KCoder::serialize(key, &serialized_key)) { LOG(ERROR) << "failed to serialized key"; return false; } MDB_val mdbkey, mdbdata; mdbkey.mv_data = serialized_key.data(); mdbkey.mv_size = serialized_key.size(); int retval; retval = mdb_get(read_txn_, dbi_, &mdbkey, &mdbdata); if (MDB_SUCCESS != retval) { LOG(ERROR) << "mdb_get failed " << mdb_strerror(retval); return false; } if (!VCoder::deserialize(reinterpret_cast<char*>(mdbdata.mv_data), mdbdata.mv_size, value)) { LOG(ERROR) << "failed to deserialize value"; return false; } return true; }
DBCursorPriv *DBPrivOpenCursor(DBPriv *db) { DBCursorPriv *cursor = NULL; DBTxn *txn; int rc; MDB_cursor *mc; rc = GetWriteTransaction(db, &txn); if (rc == MDB_SUCCESS) { assert(!txn->cursor_open); rc = mdb_cursor_open(txn->txn, db->dbi, &mc); if (rc == MDB_SUCCESS) { cursor = xcalloc(1, sizeof(DBCursorPriv)); cursor->db = db; cursor->mc = mc; txn->cursor_open = true; } else { Log(LOG_LEVEL_ERR, "Could not open cursor: %s", mdb_strerror(rc)); AbortTransaction(db); } /* txn remains with cursor */ } return cursor; }
common::Error LmdbRaw::keys(const std::string &key_start, const std::string &key_end, uint64_t limit, std::vector<std::string> *ret) { MDB_cursor *cursor; MDB_txn *txn = NULL; int rc = mdb_txn_begin(lmdb_->env, NULL, MDB_RDONLY, &txn); if (rc == LMDB_OK) { rc = mdb_cursor_open(txn, lmdb_->dbir, &cursor); } if (rc != LMDB_OK) { mdb_txn_abort(txn); char buff[1024] = {0}; common::SNPrintf(buff, sizeof(buff), "Keys function error: %s", mdb_strerror(rc)); return common::make_error_value(buff, common::ErrorValue::E_ERROR); } MDB_val key; MDB_val data; while ((mdb_cursor_get(cursor, &key, &data, MDB_NEXT) == LMDB_OK) && limit > ret->size()) { std::string skey((const char*)key.mv_data, key.mv_size); if (key_start < skey && key_end > skey) { ret->push_back(skey); } } mdb_cursor_close(cursor); mdb_txn_abort(txn); return common::Error(); }