创建

可以创建带目录和不带目录的,都会产生主题数据文件和锁(lock)文件。锁文件可以删除,因为下次打开的时候会自动创建。

创建 env 之后,要先设置 mapsize 再创建打开文件;mapsize 可以设置很大,如果设置的太小,会导致加数据或提交时出现 MDB_MAP_FULL 错误。不同担心 mapsize 设置很大时,没开始写数据内存就爆,或写出去的数据文件会特别大,不会的,内存和文件只和你喂给它数据多少有关。

inline void check(int code)
{
if (code != MDB_SUCCESS)
{
auto msg = mdb_strerror(code);
throw std::runtime_error(msg);
}
}
void create(const fs::path& lmdbFilename, bool subdir)
{
MDB_env *env = nullptr;
check(mdb_env_create(&env));
check(mdb_env_set_mapsize(env, 1099511627776ul)); // 1 TB
check(mdb_env_open(env, lmdbFilename.u8string().c_str(), subdir ? 0 : MDB_NOSUBDIR, 0664));
MDB_txn *txn = nullptr;
check(mdb_txn_begin(env, nullptr, 0, &txn));
MDB_dbi dbi = 0;
check(mdb_dbi_open(txn, nullptr, 0, &dbi));
std::string str(u8"test");
std::vector<uint8_t> data(128, 0);
MDB_val key{0};
key.mv_data = (void*)str.data();
key.mv_size = str.size();
MDB_val val{0};
val.mv_data = (void*)data.data();
val.mv_size = data.size();
check(mdb_put(txn, dbi, &key, &val, 0));
check(mdb_txn_commit(txn));
mdb_dbi_close(env, dbi);
mdb_env_close(env);
}

读取

打开文件时建议加上 MDB_FIXEDMAP,加上读取时要相对快很多。

void read(const fs::path& lmdbFilename, bool subdir)
{
MDB_env *env = nullptr;
check(mdb_env_create(&env));
check(mdb_env_set_mapsize(env, 1099511627776ul)); // 1 TB
int flags = MDB_FIXEDMAP | MDB_RDONLY | (subdir ? 0 : MDB_NOSUBDIR);
check(mdb_env_open(env, lmdbFilename.u8string().c_str(), flags, 0664));
MDB_txn *txn = nullptr;
check(mdb_txn_begin(env, nullptr, flags, &txn));
MDB_dbi dbi = 0;
check(mdb_dbi_open(txn, nullptr, 0, &dbi));
MDB_cursor *cursor = nullptr;
check(mdb_cursor_open(txn, dbi, &cursor));
MDB_val key{0};
MDB_val val{0};
int ret = MDB_SUCCESS;
while ((ret = mdb_cursor_get(cursor, &key, &val, MDB_NEXT)) != MDB_NOTFOUND)
{
check(ret);
std::string str((const char*)key.mv_data, (const char*)key.mv_data + key.mv_size);
std::vector<uint8_t> data((const uint8_t*)val.mv_data, (const uint8_t*)val.mv_data + val.mv_size);
cout << str << endl;
}
mdb_txn_abort(txn);
mdb_dbi_close(env, dbi);
mdb_env_close(env);
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注