Apply uniform formatting via clang-format

This commit is contained in:
Martchus 2022-01-30 21:14:43 +01:00
parent ff1fc3ebd4
commit 2e7d278c9b
7 changed files with 1265 additions and 1335 deletions

3
.gitignore vendored
View File

@ -30,3 +30,6 @@
*.exe *.exe
*.out *.out
*.app *.app
# Misc
.clang-format

View File

@ -2,37 +2,35 @@
#include "./lmdb-safe.hh" #include "./lmdb-safe.hh"
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp> #include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp> #include <boost/serialization/string.hpp>
#include <boost/serialization/utility.hpp> #include <boost/serialization/utility.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp> #include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp> #include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
namespace LMDBSafe { namespace LMDBSafe {
template<typename T> template <typename T> std::string serToString(const T &t)
std::string serToString(const T& t)
{ {
auto ret = std::string(); auto ret = std::string();
auto inserter = boost::iostreams::back_insert_device<std::string>(ret); auto inserter = boost::iostreams::back_insert_device<std::string>(ret);
auto stream = boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>>(inserter); auto stream = boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>>(inserter);
auto oa = boost::archive::binary_oarchive(stream, boost::archive::no_header | boost::archive::no_codecvt); auto oa = boost::archive::binary_oarchive(stream, boost::archive::no_header | boost::archive::no_codecvt);
oa << t; oa << t;
return ret; return ret;
} }
template<typename T> template <typename T> void serFromString(string_view str, T &ret)
void serFromString(string_view str, T& ret)
{ {
auto source = boost::iostreams::array_source(str.data(), str.size()); auto source = boost::iostreams::array_source(str.data(), str.size());
auto stream = boost::iostreams::stream<boost::iostreams::array_source>(source); auto stream = boost::iostreams::stream<boost::iostreams::array_source>(source);
auto ia = boost::archive::binary_iarchive(stream, boost::archive::no_header|boost::archive::no_codecvt); auto ia = boost::archive::binary_iarchive(stream, boost::archive::no_header | boost::archive::no_codecvt);
ia >> ret; ia >> ret;
} }
} } // namespace LMDBSafe

View File

@ -6,31 +6,29 @@
#include <reflective-rapidjson/lib/binary/reflector.h> #include <reflective-rapidjson/lib/binary/reflector.h>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/stream.hpp> #include <boost/iostreams/stream.hpp>
#include <boost/iostreams/stream_buffer.hpp> #include <boost/iostreams/stream_buffer.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
namespace LMDBSafe { namespace LMDBSafe {
template<typename T> template <typename T> std::string serToString(const T &t)
std::string serToString(const T& t)
{ {
auto ret = std::string(); auto ret = std::string();
auto inserter = boost::iostreams::back_insert_device<std::string>(ret); auto inserter = boost::iostreams::back_insert_device<std::string>(ret);
auto stream = boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>>(inserter); auto stream = boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>>(inserter);
auto deserializer = ReflectiveRapidJSON::BinaryReflector::BinarySerializer(&stream); auto deserializer = ReflectiveRapidJSON::BinaryReflector::BinarySerializer(&stream);
deserializer.write(t); deserializer.write(t);
return ret; return ret;
} }
template<typename T> template <typename T> void serFromString(string_view str, T &ret)
void serFromString(string_view str, T& ret)
{ {
auto source = boost::iostreams::array_source(str.data(), str.size()); auto source = boost::iostreams::array_source(str.data(), str.size());
auto stream = boost::iostreams::stream<boost::iostreams::array_source>(source); auto stream = boost::iostreams::stream<boost::iostreams::array_source>(source);
auto serializer = ReflectiveRapidJSON::BinaryReflector::BinaryDeserializer(&stream); auto serializer = ReflectiveRapidJSON::BinaryReflector::BinaryDeserializer(&stream);
ret = T(); ret = T();
serializer.read(ret); serializer.read(ret);
} }
} } // namespace LMDBSafe

View File

@ -3,369 +3,360 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <mutex>
#include <memory>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <memory>
#include <mutex>
using namespace std; using namespace std;
namespace LMDBSafe { namespace LMDBSafe {
MDBDbi::MDBDbi(MDB_env* env, MDB_txn* txn, const string_view dbname, unsigned int flags) MDBDbi::MDBDbi(MDB_env *env, MDB_txn *txn, const string_view dbname, unsigned int flags)
{ {
(void)env; (void)env;
// A transaction that uses this function must finish (either commit or abort) before any other transaction in the process may use this function. // A transaction that uses this function must finish (either commit or abort) before any other transaction in the process may use this function.
if(const auto rc = mdb_dbi_open(txn, dbname.empty() ? 0 : &dbname[0], flags, &d_dbi)) if (const auto rc = mdb_dbi_open(txn, dbname.empty() ? 0 : &dbname[0], flags, &d_dbi))
throw LMDBError("Unable to open named database: ", rc); throw LMDBError("Unable to open named database: ", rc);
// Database names are keys in the unnamed database, and may be read but not written. // Database names are keys in the unnamed database, and may be read but not written.
} }
MDBEnv::MDBEnv(const char* fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs) MDBEnv::MDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs)
{ {
mdb_env_create(&d_env); mdb_env_create(&d_env);
if(const auto rc = mdb_env_set_mapsize(d_env, 16ULL * 4096 * 244140ULL)) { // 4GB if (const auto rc = mdb_env_set_mapsize(d_env, 16ULL * 4096 * 244140ULL)) { // 4GB
throw LMDBError("Setting map size: ", rc); throw LMDBError("Setting map size: ", rc);
} }
// Various other options may also need to be set before opening the handle, e.g. mdb_env_set_mapsize(), mdb_env_set_maxreaders(), mdb_env_set_maxdbs(), // Various other options may also need to be set before opening the handle, e.g. mdb_env_set_mapsize(), mdb_env_set_maxreaders(), mdb_env_set_maxdbs(),
if (const auto rc = mdb_env_set_maxdbs(d_env, maxDBs)) { if (const auto rc = mdb_env_set_maxdbs(d_env, maxDBs)) {
throw LMDBError("Setting maxdbs: ", rc); throw LMDBError("Setting maxdbs: ", rc);
} }
// we need MDB_NOTLS since we rely on its semantics // we need MDB_NOTLS since we rely on its semantics
if(const auto rc = mdb_env_open(d_env, fname, flags | MDB_NOTLS, mode)) { if (const auto rc = mdb_env_open(d_env, fname, flags | MDB_NOTLS, mode)) {
// If this function fails, mdb_env_close() must be called to discard the MDB_env handle. // If this function fails, mdb_env_close() must be called to discard the MDB_env handle.
mdb_env_close(d_env); mdb_env_close(d_env);
throw LMDBError("Unable to open database file " + std::string(fname) + ": ", rc); throw LMDBError("Unable to open database file " + std::string(fname) + ": ", rc);
} }
} }
void MDBEnv::incROTX() void MDBEnv::incROTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
++d_ROtransactionsOut[std::this_thread::get_id()]; ++d_ROtransactionsOut[std::this_thread::get_id()];
} }
void MDBEnv::decROTX() void MDBEnv::decROTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
--d_ROtransactionsOut[std::this_thread::get_id()]; --d_ROtransactionsOut[std::this_thread::get_id()];
} }
void MDBEnv::incRWTX() void MDBEnv::incRWTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
++d_RWtransactionsOut[std::this_thread::get_id()]; ++d_RWtransactionsOut[std::this_thread::get_id()];
} }
void MDBEnv::decRWTX() void MDBEnv::decRWTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
--d_RWtransactionsOut[std::this_thread::get_id()]; --d_RWtransactionsOut[std::this_thread::get_id()];
} }
int MDBEnv::getRWTX() int MDBEnv::getRWTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
return d_RWtransactionsOut[std::this_thread::get_id()]; return d_RWtransactionsOut[std::this_thread::get_id()];
} }
int MDBEnv::getROTX() int MDBEnv::getROTX()
{ {
std::lock_guard<std::mutex> l(d_countmutex); std::lock_guard<std::mutex> l(d_countmutex);
return d_ROtransactionsOut[std::this_thread::get_id()]; return d_ROtransactionsOut[std::this_thread::get_id()];
} }
std::shared_ptr<MDBEnv> getMDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs)
std::shared_ptr<MDBEnv> getMDBEnv(const char* fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs)
{ {
struct Value struct Value {
{ weak_ptr<MDBEnv> wp;
weak_ptr<MDBEnv> wp; unsigned int flags;
unsigned int flags; };
};
static std::map<tuple<dev_t, ino_t>, Value> s_envs; static std::map<tuple<dev_t, ino_t>, Value> s_envs;
static std::mutex mut; static std::mutex mut;
struct stat statbuf; struct stat statbuf;
if(stat(fname, &statbuf)) { if (stat(fname, &statbuf)) {
if(errno != ENOENT) if (errno != ENOENT)
throw LMDBError("Unable to stat prospective mdb database: " + string(strerror(errno))); throw LMDBError("Unable to stat prospective mdb database: " + string(strerror(errno)));
else { else {
std::lock_guard<std::mutex> l(mut); std::lock_guard<std::mutex> l(mut);
auto fresh = std::make_shared<MDBEnv>(fname, flags, mode, maxDBs); auto fresh = std::make_shared<MDBEnv>(fname, flags, mode, maxDBs);
if(stat(fname, &statbuf)) if (stat(fname, &statbuf))
throw LMDBError("Unable to stat prospective mdb database: " + string(strerror(errno))); throw LMDBError("Unable to stat prospective mdb database: " + string(strerror(errno)));
auto key = std::tie(statbuf.st_dev, statbuf.st_ino); auto key = std::tie(statbuf.st_dev, statbuf.st_ino);
s_envs[key] = {fresh, flags}; s_envs[key] = { fresh, flags };
return fresh; return fresh;
}
} }
}
std::lock_guard<std::mutex> l(mut); std::lock_guard<std::mutex> l(mut);
auto key = std::tie(statbuf.st_dev, statbuf.st_ino); auto key = std::tie(statbuf.st_dev, statbuf.st_ino);
auto iter = s_envs.find(key); auto iter = s_envs.find(key);
if(iter != s_envs.end()) { if (iter != s_envs.end()) {
auto sp = iter->second.wp.lock(); auto sp = iter->second.wp.lock();
if(sp) { if (sp) {
if(iter->second.flags != flags) if (iter->second.flags != flags)
throw LMDBError("Can't open mdb with differing flags"); throw LMDBError("Can't open mdb with differing flags");
return sp; return sp;
} else {
s_envs.erase(iter); // useful if make_shared fails
}
} }
else {
s_envs.erase(iter); // useful if make_shared fails
}
}
auto fresh = std::make_shared<MDBEnv>(fname, flags, mode, maxDBs); auto fresh = std::make_shared<MDBEnv>(fname, flags, mode, maxDBs);
s_envs[key] = {fresh, flags}; s_envs[key] = { fresh, flags };
return fresh; return fresh;
} }
MDBDbi MDBEnv::openDB(const string_view dbname, unsigned int flags) MDBDbi MDBEnv::openDB(const string_view dbname, unsigned int flags)
{ {
unsigned int envflags; unsigned int envflags;
mdb_env_get_flags(d_env, &envflags); mdb_env_get_flags(d_env, &envflags);
/* /*
This function must not be called from multiple concurrent transactions in the same process. A transaction that uses this function must finish (either commit or abort) before any other transaction in the process may use this function. This function must not be called from multiple concurrent transactions in the same process. A transaction that uses this function must finish (either commit or abort) before any other transaction in the process may use this function.
*/ */
std::lock_guard<std::mutex> l(d_openmut); std::lock_guard<std::mutex> l(d_openmut);
if(!(envflags & MDB_RDONLY)) { if (!(envflags & MDB_RDONLY)) {
auto rwt = getRWTransaction(); auto rwt = getRWTransaction();
MDBDbi ret = rwt->openDB(dbname, flags); MDBDbi ret = rwt->openDB(dbname, flags);
rwt->commit(); rwt->commit();
return ret;
}
MDBDbi ret;
{
auto rwt = getROTransaction();
ret = rwt->openDB(dbname, flags);
}
return ret; return ret;
}
MDBDbi ret;
{
auto rwt = getROTransaction();
ret = rwt->openDB(dbname, flags);
}
return ret;
} }
MDBRWTransactionImpl::MDBRWTransactionImpl(MDBEnv *parent, MDB_txn *txn): MDBRWTransactionImpl::MDBRWTransactionImpl(MDBEnv *parent, MDB_txn *txn)
MDBROTransactionImpl(parent, txn) : MDBROTransactionImpl(parent, txn)
{ {
} }
MDB_txn *MDBRWTransactionImpl::openRWTransaction(MDBEnv *env, MDB_txn *parent, unsigned int flags) MDB_txn *MDBRWTransactionImpl::openRWTransaction(MDBEnv *env, MDB_txn *parent, unsigned int flags)
{ {
MDB_txn *result; MDB_txn *result;
if(env->getRWTX()) if (env->getRWTX())
throw LMDBError("Duplicate RW transaction"); throw LMDBError("Duplicate RW transaction");
for(int tries =0 ; tries < 3; ++tries) { // it might happen twice, who knows for (int tries = 0; tries < 3; ++tries) { // it might happen twice, who knows
if(int rc=mdb_txn_begin(env->d_env, parent, flags, &result)) { if (int rc = mdb_txn_begin(env->d_env, parent, flags, &result)) {
if(rc == MDB_MAP_RESIZED && tries < 2) { if (rc == MDB_MAP_RESIZED && tries < 2) {
// "If the mapsize is increased by another process (..) mdb_txn_begin() will return MDB_MAP_RESIZED. // "If the mapsize is increased by another process (..) mdb_txn_begin() will return MDB_MAP_RESIZED.
// call mdb_env_set_mapsize with a size of zero to adopt the new size." // call mdb_env_set_mapsize with a size of zero to adopt the new size."
mdb_env_set_mapsize(env->d_env, 0); mdb_env_set_mapsize(env->d_env, 0);
continue; continue;
} }
throw LMDBError("Unable to start RW transaction: ", rc); throw LMDBError("Unable to start RW transaction: ", rc);
}
break;
} }
break; env->incRWTX();
} return result;
env->incRWTX();
return result;
} }
MDBRWTransactionImpl::MDBRWTransactionImpl(MDBEnv* parent, unsigned int flags): MDBRWTransactionImpl::MDBRWTransactionImpl(MDBEnv *parent, unsigned int flags)
MDBRWTransactionImpl(parent, openRWTransaction(parent, nullptr, flags)) : MDBRWTransactionImpl(parent, openRWTransaction(parent, nullptr, flags))
{ {
} }
MDBRWTransactionImpl::~MDBRWTransactionImpl() MDBRWTransactionImpl::~MDBRWTransactionImpl()
{ {
MDBRWTransactionImpl::abort(); MDBRWTransactionImpl::abort();
} }
void MDBRWTransactionImpl::commit() void MDBRWTransactionImpl::commit()
{ {
closeRORWCursors(); closeRORWCursors();
if (!d_txn) { if (!d_txn) {
return; return;
} }
if(const auto rc = mdb_txn_commit(d_txn)) { if (const auto rc = mdb_txn_commit(d_txn)) {
throw LMDBError("Committing transaction: ", rc); throw LMDBError("Committing transaction: ", rc);
} }
environment().decRWTX(); environment().decRWTX();
d_txn = nullptr; d_txn = nullptr;
} }
void MDBRWTransactionImpl::abort() void MDBRWTransactionImpl::abort()
{ {
closeRORWCursors(); closeRORWCursors();
if (!d_txn) { if (!d_txn) {
return; return;
} }
mdb_txn_abort(d_txn); mdb_txn_abort(d_txn);
// prevent the RO destructor from cleaning up the transaction itself // prevent the RO destructor from cleaning up the transaction itself
environment().decRWTX(); environment().decRWTX();
d_txn = nullptr; d_txn = nullptr;
} }
MDBROTransactionImpl::MDBROTransactionImpl(MDBEnv *parent, MDB_txn *txn): MDBROTransactionImpl::MDBROTransactionImpl(MDBEnv *parent, MDB_txn *txn)
d_parent(parent), : d_parent(parent)
d_cursors(), , d_cursors()
d_txn(txn) , d_txn(txn)
{ {
} }
MDB_txn *MDBROTransactionImpl::openROTransaction(MDBEnv *env, MDB_txn *parent, unsigned int flags) MDB_txn *MDBROTransactionImpl::openROTransaction(MDBEnv *env, MDB_txn *parent, unsigned int flags)
{ {
if(env->getRWTX()) if (env->getRWTX())
throw LMDBError("Duplicate RO transaction"); throw LMDBError("Duplicate RO transaction");
/* /*
A transaction and its cursors must only be used by a single thread, and a thread may only have a single transaction at a time. If MDB_NOTLS is in use, this does not apply to read-only transactions. */ A transaction and its cursors must only be used by a single thread, and a thread may only have a single transaction at a time. If MDB_NOTLS is in use, this does not apply to read-only transactions. */
MDB_txn *result = nullptr; MDB_txn *result = nullptr;
for(int tries = 0; tries < 3; ++tries) { // it might happen twice, who knows for (int tries = 0; tries < 3; ++tries) { // it might happen twice, who knows
if(const auto rc = mdb_txn_begin(env->d_env, parent, MDB_RDONLY | flags, &result)) { if (const auto rc = mdb_txn_begin(env->d_env, parent, MDB_RDONLY | flags, &result)) {
if(rc == MDB_MAP_RESIZED && tries < 2) { if (rc == MDB_MAP_RESIZED && tries < 2) {
// "If the mapsize is increased by another process (..) mdb_txn_begin() will return MDB_MAP_RESIZED. // "If the mapsize is increased by another process (..) mdb_txn_begin() will return MDB_MAP_RESIZED.
// call mdb_env_set_mapsize with a size of zero to adopt the new size." // call mdb_env_set_mapsize with a size of zero to adopt the new size."
mdb_env_set_mapsize(env->d_env, 0); mdb_env_set_mapsize(env->d_env, 0);
continue; continue;
} }
throw LMDBError("Unable to start RO transaction: ", rc); throw LMDBError("Unable to start RO transaction: ", rc);
}
break;
} }
break; env->incROTX();
}
env->incROTX();
return result; return result;
} }
void MDBROTransactionImpl::closeROCursors() void MDBROTransactionImpl::closeROCursors()
{ {
// we need to move the vector away to ensure that the cursors dont mess with our iteration. // we need to move the vector away to ensure that the cursors dont mess with our iteration.
std::vector<MDBROCursor*> buf; std::vector<MDBROCursor *> buf;
std::swap(d_cursors, buf); std::swap(d_cursors, buf);
for (auto &cursor: buf) { for (auto &cursor : buf) {
cursor->close(); cursor->close();
} }
} }
MDBROTransactionImpl::MDBROTransactionImpl(MDBEnv *parent, unsigned int flags): MDBROTransactionImpl::MDBROTransactionImpl(MDBEnv *parent, unsigned int flags)
MDBROTransactionImpl(parent, openROTransaction(parent, nullptr, flags)) : MDBROTransactionImpl(parent, openROTransaction(parent, nullptr, flags))
{ {
} }
MDBROTransactionImpl::~MDBROTransactionImpl() MDBROTransactionImpl::~MDBROTransactionImpl()
{ {
// this is safe because C++ will not call overrides of virtual methods in destructors. // this is safe because C++ will not call overrides of virtual methods in destructors.
MDBROTransactionImpl::commit(); MDBROTransactionImpl::commit();
} }
void MDBROTransactionImpl::abort() void MDBROTransactionImpl::abort()
{ {
closeROCursors(); closeROCursors();
// if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort). // if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort).
if (d_txn) { if (d_txn) {
d_parent->decROTX(); d_parent->decROTX();
mdb_txn_abort(d_txn); // this appears to work better than abort for r/o database opening mdb_txn_abort(d_txn); // this appears to work better than abort for r/o database opening
d_txn = nullptr; d_txn = nullptr;
} }
} }
void MDBROTransactionImpl::commit() void MDBROTransactionImpl::commit()
{ {
closeROCursors(); closeROCursors();
// if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort). // if d_txn is non-nullptr here, either the transaction object was invalidated earlier (e.g. by moving from it), or it is an RW transaction which has already cleaned up the d_txn pointer (with an abort).
if (d_txn) { if (d_txn) {
d_parent->decROTX(); d_parent->decROTX();
if (const auto rc = mdb_txn_commit(d_txn)) { // this appears to work better than abort for r/o database opening if (const auto rc = mdb_txn_commit(d_txn)) { // this appears to work better than abort for r/o database opening
throw LMDBError("Error comitting transaction: ", rc); throw LMDBError("Error comitting transaction: ", rc);
}
d_txn = nullptr;
} }
d_txn = nullptr;
}
} }
void MDBRWTransactionImpl::clear(MDB_dbi dbi) void MDBRWTransactionImpl::clear(MDB_dbi dbi)
{ {
if(const auto rc = mdb_drop(d_txn, dbi, 0)) { if (const auto rc = mdb_drop(d_txn, dbi, 0)) {
throw LMDBError("Error clearing database: ", rc); throw LMDBError("Error clearing database: ", rc);
} }
} }
MDBRWCursor MDBRWTransactionImpl::getRWCursor(const MDBDbi& dbi) MDBRWCursor MDBRWTransactionImpl::getRWCursor(const MDBDbi &dbi)
{ {
MDB_cursor *cursor;; MDB_cursor *cursor;
if(const auto rc = mdb_cursor_open(d_txn, dbi, &cursor)) { ;
throw LMDBError("Error creating RO cursor: ", rc); if (const auto rc = mdb_cursor_open(d_txn, dbi, &cursor)) {
} throw LMDBError("Error creating RO cursor: ", rc);
return MDBRWCursor(d_rw_cursors, cursor); }
return MDBRWCursor(d_rw_cursors, cursor);
} }
MDBRWCursor MDBRWTransactionImpl::getCursor(const MDBDbi &dbi) MDBRWCursor MDBRWTransactionImpl::getCursor(const MDBDbi &dbi)
{ {
return getRWCursor(dbi); return getRWCursor(dbi);
} }
MDBRWTransaction MDBRWTransactionImpl::getRWTransaction() MDBRWTransaction MDBRWTransactionImpl::getRWTransaction()
{ {
MDB_txn *txn; MDB_txn *txn;
if (const auto rc = mdb_txn_begin(environment(), *this, 0, &txn)) { if (const auto rc = mdb_txn_begin(environment(), *this, 0, &txn)) {
throw LMDBError("Failed to start child transaction: ", rc); throw LMDBError("Failed to start child transaction: ", rc);
} }
// we need to increase the counter here because commit/abort on the child transaction will decrease it // we need to increase the counter here because commit/abort on the child transaction will decrease it
environment().incRWTX(); environment().incRWTX();
return MDBRWTransaction(new MDBRWTransactionImpl(&environment(), txn)); return MDBRWTransaction(new MDBRWTransactionImpl(&environment(), txn));
} }
MDBROTransaction MDBRWTransactionImpl::getROTransaction() MDBROTransaction MDBRWTransactionImpl::getROTransaction()
{ {
return getRWTransaction(); return getRWTransaction();
} }
MDBROTransaction MDBEnv::getROTransaction() MDBROTransaction MDBEnv::getROTransaction()
{ {
return MDBROTransaction(new MDBROTransactionImpl(this)); return MDBROTransaction(new MDBROTransactionImpl(this));
} }
MDBRWTransaction MDBEnv::getRWTransaction() MDBRWTransaction MDBEnv::getRWTransaction()
{ {
return MDBRWTransaction(new MDBRWTransactionImpl(this)); return MDBRWTransaction(new MDBRWTransactionImpl(this));
} }
void MDBRWTransactionImpl::closeRWCursors() void MDBRWTransactionImpl::closeRWCursors()
{ {
decltype(d_rw_cursors) buf; decltype(d_rw_cursors) buf;
std::swap(d_rw_cursors, buf); std::swap(d_rw_cursors, buf);
for (auto &cursor: buf) { for (auto &cursor : buf) {
cursor->close(); cursor->close();
} }
} }
MDBROCursor MDBROTransactionImpl::getCursor(const MDBDbi& dbi) MDBROCursor MDBROTransactionImpl::getCursor(const MDBDbi &dbi)
{ {
return getROCursor(dbi); return getROCursor(dbi);
} }
MDBROCursor MDBROTransactionImpl::getROCursor(const MDBDbi &dbi) MDBROCursor MDBROTransactionImpl::getROCursor(const MDBDbi &dbi)
{ {
MDB_cursor *cursor; MDB_cursor *cursor;
if(const auto rc = mdb_cursor_open(d_txn, dbi, &cursor)) { if (const auto rc = mdb_cursor_open(d_txn, dbi, &cursor)) {
throw LMDBError("Error creating RO cursor: ", rc); throw LMDBError("Error creating RO cursor: ", rc);
} }
return MDBROCursor(d_cursors, cursor); return MDBROCursor(d_cursors, cursor);
} }
} } // namespace LMDBSafe

File diff suppressed because it is too large Load Diff

View File

@ -2,15 +2,15 @@
namespace LMDBSafe { namespace LMDBSafe {
unsigned int MDBGetMaxID(MDBRWTransaction& txn, MDBDbi& dbi) unsigned int MDBGetMaxID(MDBRWTransaction &txn, MDBDbi &dbi)
{ {
auto cursor = txn->getRWCursor(dbi); auto cursor = txn->getRWCursor(dbi);
MDBOutVal maxidval, maxcontent; MDBOutVal maxidval, maxcontent;
unsigned int maxid{0}; unsigned int maxid{ 0 };
if(!cursor.get(maxidval, maxcontent, MDB_LAST)) { if (!cursor.get(maxidval, maxcontent, MDB_LAST)) {
maxid = maxidval.get<unsigned int>(); maxid = maxidval.get<unsigned int>();
} }
return maxid; return maxid;
} }
} } // namespace LMDBSafe

File diff suppressed because it is too large Load Diff