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,21 +2,20 @@
#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);
@ -26,8 +25,7 @@ std::string serToString(const T& 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);
@ -35,4 +33,4 @@ void serFromString(string_view str, T& ret)
ia >> ret; ia >> ret;
} }
} } // namespace LMDBSafe

View File

@ -6,14 +6,13 @@
#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);
@ -23,8 +22,7 @@ std::string serToString(const T& 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);
@ -33,4 +31,4 @@ void serFromString(string_view str, T& ret)
serializer.read(ret); serializer.read(ret);
} }
} } // namespace LMDBSafe

View File

@ -3,10 +3,10 @@
#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;
@ -77,11 +77,9 @@ int MDBEnv::getROTX()
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;
}; };
@ -114,8 +112,7 @@ std::shared_ptr<MDBEnv> getMDBEnv(const char* fname, unsigned int flags, mdb_mod
throw LMDBError("Can't open mdb with differing flags"); throw LMDBError("Can't open mdb with differing flags");
return sp; return sp;
} } else {
else {
s_envs.erase(iter); // useful if make_shared fails s_envs.erase(iter); // useful if make_shared fails
} }
} }
@ -126,7 +123,6 @@ std::shared_ptr<MDBEnv> getMDBEnv(const char* fname, unsigned int flags, mdb_mod
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;
@ -151,11 +147,10 @@ MDBDbi MDBEnv::openDB(const string_view dbname, unsigned int flags)
return ret; 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)
@ -180,8 +175,8 @@ MDB_txn *MDBRWTransactionImpl::openRWTransaction(MDBEnv *env, MDB_txn *parent, u
return result; 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))
{ {
} }
@ -217,12 +212,11 @@ void MDBRWTransactionImpl::abort()
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)
@ -260,10 +254,9 @@ void MDBROTransactionImpl::closeROCursors()
} }
} }
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()
@ -296,8 +289,6 @@ void MDBROTransactionImpl::commit()
} }
} }
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)) {
@ -307,7 +298,8 @@ void MDBRWTransactionImpl::clear(MDB_dbi dbi)
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)) { 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);
} }
@ -344,7 +336,6 @@ 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;
@ -368,4 +359,4 @@ MDBROCursor MDBROTransactionImpl::getROCursor(const MDBDbi &dbi)
return MDBROCursor(d_cursors, cursor); return MDBROCursor(d_cursors, cursor);
} }
} } // namespace LMDBSafe

View File

@ -4,19 +4,19 @@
#include <lmdb.h> #include <lmdb.h>
#include <iostream>
#include <fstream>
#include <set>
#include <map>
#include <thread>
#include <memory>
#include <string>
#include <cstring>
#include <mutex>
#include <vector>
#include <algorithm> #include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
#include <limits> #include <limits>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <thread>
#include <vector>
/*! /*!
* \brief The LMDBSafe namespace contains all classes/types contained by the lmdb-safe and * \brief The LMDBSafe namespace contains all classes/types contained by the lmdb-safe and
@ -43,8 +43,7 @@ using string_view = boost::string_ref;
#endif #endif
#endif #endif
class LMDB_SAFE_EXPORT LMDBError : public std::runtime_error class LMDB_SAFE_EXPORT LMDBError : public std::runtime_error {
{
public: public:
explicit LMDBError(const std::string &error) noexcept explicit LMDBError(const std::string &error) noexcept
: std::runtime_error(error) : std::runtime_error(error)
@ -65,8 +64,7 @@ public:
* \brief The MDBDbi class is our only 'value type' object as 1) a dbi is actually an integer * \brief The MDBDbi class is our only 'value type' object as 1) a dbi is actually an integer
* and 2) per LMDB documentation, we never close it. * and 2) per LMDB documentation, we never close it.
*/ */
class LMDB_SAFE_EXPORT MDBDbi class LMDB_SAFE_EXPORT MDBDbi {
{
public: public:
MDBDbi() MDBDbi()
{ {
@ -88,8 +86,7 @@ class MDBROTransactionImpl;
using MDBROTransaction = std::unique_ptr<MDBROTransactionImpl>; using MDBROTransaction = std::unique_ptr<MDBROTransactionImpl>;
using MDBRWTransaction = std::unique_ptr<MDBRWTransactionImpl>; using MDBRWTransaction = std::unique_ptr<MDBRWTransactionImpl>;
class LMDB_SAFE_EXPORT MDBEnv class LMDB_SAFE_EXPORT MDBEnv {
{
public: public:
MDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs = 10); MDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs = 10);
@ -117,6 +114,7 @@ public:
int getROTX(); int getROTX();
void incROTX(); void incROTX();
void decROTX(); void decROTX();
private: private:
std::mutex d_openmut; std::mutex d_openmut;
std::mutex d_countmutex; std::mutex d_countmutex;
@ -126,17 +124,13 @@ private:
LMDB_SAFE_EXPORT std::shared_ptr<MDBEnv> getMDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs = 128); LMDB_SAFE_EXPORT std::shared_ptr<MDBEnv> getMDBEnv(const char *fname, unsigned int flags, mdb_mode_t mode, MDB_dbi maxDBs = 128);
struct LMDB_SAFE_EXPORT MDBOutVal struct LMDB_SAFE_EXPORT MDBOutVal {
{
operator MDB_val &() operator MDB_val &()
{ {
return d_mdbval; return d_mdbval;
} }
template <class T, template <class T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type * = nullptr> const T get()
typename std::enable_if<std::is_arithmetic<T>::value,
T>::type* = nullptr> const
T get()
{ {
T ret; T ret;
if (d_mdbval.mv_size != sizeof(T)) if (d_mdbval.mv_size != sizeof(T))
@ -146,12 +140,9 @@ struct LMDB_SAFE_EXPORT MDBOutVal
return ret; return ret;
} }
template <class T, template <class T, typename std::enable_if<std::is_class<T>::value, T>::type * = nullptr> T get() const;
typename std::enable_if<std::is_class<T>::value,T>::type* = nullptr>
T get() const;
template<class T> template <class T> T get_struct() const
T get_struct() const
{ {
T ret; T ret;
if (d_mdbval.mv_size != sizeof(T)) if (d_mdbval.mv_size != sizeof(T))
@ -161,8 +152,7 @@ struct LMDB_SAFE_EXPORT MDBOutVal
return ret; return ret;
} }
template<class T> template <class T> const T *get_struct_ptr() const
const T* get_struct_ptr() const
{ {
if (d_mdbval.mv_size != sizeof(T)) if (d_mdbval.mv_size != sizeof(T))
throw LMDBError("MDB data has wrong length for type"); throw LMDBError("MDB data has wrong length for type");
@ -170,7 +160,6 @@ struct LMDB_SAFE_EXPORT MDBOutVal
return reinterpret_cast<const T *>(d_mdbval.mv_data); return reinterpret_cast<const T *>(d_mdbval.mv_data);
} }
MDB_val d_mdbval; MDB_val d_mdbval;
}; };
@ -184,22 +173,19 @@ template<> inline string_view MDBOutVal::get<string_view>() const
return string_view(static_cast<char *>(d_mdbval.mv_data), d_mdbval.mv_size); return string_view(static_cast<char *>(d_mdbval.mv_data), d_mdbval.mv_size);
} }
class LMDB_SAFE_EXPORT MDBInVal class LMDB_SAFE_EXPORT MDBInVal {
{
public: public:
MDBInVal(const MDBOutVal &rhs) MDBInVal(const MDBOutVal &rhs)
{ {
d_mdbval = rhs.d_mdbval; d_mdbval = rhs.d_mdbval;
} }
template <class T, template <class T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type * = nullptr> MDBInVal(T i)
typename std::enable_if<std::is_arithmetic<T>::value,
T>::type* = nullptr>
MDBInVal(T i)
{ {
memcpy(&d_memory[0], &i, sizeof(i)); memcpy(&d_memory[0], &i, sizeof(i));
d_mdbval.mv_size = sizeof(T); d_mdbval.mv_size = sizeof(T);
d_mdbval.mv_data = d_memory;; d_mdbval.mv_data = d_memory;
;
} }
MDBInVal(const char *s) MDBInVal(const char *s)
@ -220,9 +206,7 @@ public:
d_mdbval.mv_data = static_cast<void *>(const_cast<char *>(v.data())); d_mdbval.mv_data = static_cast<void *>(const_cast<char *>(v.data()));
} }
template <typename T> static MDBInVal fromStruct(const T &t)
template<typename T>
static MDBInVal fromStruct(const T& t)
{ {
MDBInVal ret; MDBInVal ret;
ret.d_mdbval.mv_size = sizeof(T); ret.d_mdbval.mv_size = sizeof(T);
@ -235,16 +219,17 @@ public:
return d_mdbval; return d_mdbval;
} }
MDB_val d_mdbval; MDB_val d_mdbval;
private:
MDBInVal(){}
char d_memory[sizeof(double)];
private:
MDBInVal()
{
}
char d_memory[sizeof(double)];
}; };
class MDBROCursor; class MDBROCursor;
class LMDB_SAFE_EXPORT MDBROTransactionImpl class LMDB_SAFE_EXPORT MDBROTransactionImpl {
{
protected: protected:
MDBROTransactionImpl(MDBEnv *parent, MDB_txn *txn); MDBROTransactionImpl(MDBEnv *parent, MDB_txn *txn);
@ -279,8 +264,7 @@ public:
if (!d_txn) if (!d_txn)
throw LMDBError("Attempt to use a closed RO transaction for get"); throw LMDBError("Attempt to use a closed RO transaction for get");
const auto rc = mdb_get(d_txn, dbi, const_cast<MDB_val*>(&key.d_mdbval), const auto rc = mdb_get(d_txn, dbi, const_cast<MDB_val *>(&key.d_mdbval), &val.d_mdbval);
&val.d_mdbval);
if (rc && rc != MDB_NOTFOUND) if (rc && rc != MDB_NOTFOUND)
throw LMDBError("Getting data: ", rc); throw LMDBError("Getting data: ", rc);
@ -296,7 +280,6 @@ public:
return rc; return rc;
} }
// this is something you can do, readonly // this is something you can do, readonly
MDBDbi openDB(string_view dbname, unsigned int flags) MDBDbi openDB(string_view dbname, unsigned int flags)
{ {
@ -311,7 +294,8 @@ public:
return d_txn; return d_txn;
} }
inline operator bool() const { inline operator bool() const
{
return d_txn; return d_txn;
} }
@ -328,24 +312,21 @@ public:
* It can be reused with mdb_cursor_renew() before finally closing it. * It can be reused with mdb_cursor_renew() before finally closing it.
* - "If the parent transaction commits, the cursor must not be used again." * - "If the parent transaction commits, the cursor must not be used again."
*/ */
template<class Transaction, class T> template <class Transaction, class T> class MDBGenCursor {
class MDBGenCursor
{
private: private:
std::vector<T *> *d_registry; std::vector<T *> *d_registry;
MDB_cursor *d_cursor; MDB_cursor *d_cursor;
public: public:
MDBGenCursor(): MDBGenCursor()
d_registry(nullptr), : d_registry(nullptr)
d_cursor(nullptr) , d_cursor(nullptr)
{ {
} }
MDBGenCursor(std::vector<T*> &registry, MDB_cursor *cursor): MDBGenCursor(std::vector<T *> &registry, MDB_cursor *cursor)
d_registry(&registry), : d_registry(&registry)
d_cursor(cursor) , d_cursor(cursor)
{ {
registry.emplace_back(static_cast<T *>(this)); registry.emplace_back(static_cast<T *>(this));
} }
@ -357,9 +338,7 @@ private:
return; return;
} }
auto iter = std::find(d_registry->begin(), auto iter = std::find(d_registry->begin(), d_registry->end(), src);
d_registry->end(),
src);
if (iter != d_registry->end()) { if (iter != d_registry->end()) {
*iter = static_cast<T *>(this); *iter = static_cast<T *>(this);
} else { } else {
@ -370,9 +349,9 @@ private:
public: public:
MDBGenCursor(const MDBGenCursor &src) = delete; MDBGenCursor(const MDBGenCursor &src) = delete;
MDBGenCursor(MDBGenCursor &&src) noexcept: MDBGenCursor(MDBGenCursor &&src) noexcept
d_registry(src.d_registry), : d_registry(src.d_registry)
d_cursor(src.d_cursor) , d_cursor(src.d_cursor)
{ {
move_from(&src); move_from(&src);
src.d_registry = nullptr; src.d_registry = nullptr;
@ -424,7 +403,6 @@ public:
return rc; return rc;
} }
int nextprev(MDBOutVal &key, MDBOutVal &data, MDB_cursor_op op) int nextprev(MDBOutVal &key, MDBOutVal &data, MDB_cursor_op op)
{ {
const auto rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op); const auto rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op);
@ -477,9 +455,7 @@ public:
void close() void close()
{ {
if (d_registry) { if (d_registry) {
auto iter = std::find(d_registry->begin(), auto iter = std::find(d_registry->begin(), d_registry->end(), static_cast<T *>(this));
d_registry->end(),
static_cast<T*>(this));
if (iter != d_registry->end()) { if (iter != d_registry->end()) {
d_registry->erase(iter); d_registry->erase(iter);
} }
@ -492,8 +468,7 @@ public:
} }
}; };
class LMDB_SAFE_EXPORT MDBROCursor : public MDBGenCursor<MDBROTransactionImpl, MDBROCursor> class LMDB_SAFE_EXPORT MDBROCursor : public MDBGenCursor<MDBROTransactionImpl, MDBROCursor> {
{
public: public:
MDBROCursor() = default; MDBROCursor() = default;
using MDBGenCursor<MDBROTransactionImpl, MDBROCursor>::MDBGenCursor; using MDBGenCursor<MDBROTransactionImpl, MDBROCursor>::MDBGenCursor;
@ -502,13 +477,11 @@ public:
MDBROCursor &operator=(const MDBROCursor &src) = delete; MDBROCursor &operator=(const MDBROCursor &src) = delete;
MDBROCursor &operator=(MDBROCursor &&src) = default; MDBROCursor &operator=(MDBROCursor &&src) = default;
~MDBROCursor() = default; ~MDBROCursor() = default;
}; };
class MDBRWCursor; class MDBRWCursor;
class LMDB_SAFE_EXPORT MDBRWTransactionImpl: public MDBROTransactionImpl class LMDB_SAFE_EXPORT MDBRWTransactionImpl : public MDBROTransactionImpl {
{
protected: protected:
MDBRWTransactionImpl(MDBEnv *parent, MDB_txn *txn); MDBRWTransactionImpl(MDBEnv *parent, MDB_txn *txn);
@ -519,7 +492,8 @@ private:
std::vector<MDBRWCursor *> d_rw_cursors; std::vector<MDBRWCursor *> d_rw_cursors;
void closeRWCursors(); void closeRWCursors();
inline void closeRORWCursors() { inline void closeRORWCursors()
{
closeROCursors(); closeROCursors();
closeRWCursors(); closeRWCursors();
} }
@ -543,13 +517,10 @@ public:
{ {
if (!d_txn) if (!d_txn)
throw LMDBError("Attempt to use a closed RW transaction for put"); throw LMDBError("Attempt to use a closed RW transaction for put");
if(const auto rc = mdb_put(d_txn, dbi, if (const auto rc = mdb_put(d_txn, dbi, const_cast<MDB_val *>(&key.d_mdbval), const_cast<MDB_val *>(&val.d_mdbval), flags))
const_cast<MDB_val*>(&key.d_mdbval),
const_cast<MDB_val*>(&val.d_mdbval), flags))
throw LMDBError("Putting data: ", rc); throw LMDBError("Putting data: ", rc);
} }
int del(MDBDbi &dbi, const MDBInVal &key, const MDBInVal &val) int del(MDBDbi &dbi, const MDBInVal &key, const MDBInVal &val)
{ {
const auto rc = mdb_del(d_txn, dbi, const_cast<MDB_val *>(&key.d_mdbval), const_cast<MDB_val *>(&val.d_mdbval)); const auto rc = mdb_del(d_txn, dbi, const_cast<MDB_val *>(&key.d_mdbval), const_cast<MDB_val *>(&val.d_mdbval));
@ -566,14 +537,12 @@ public:
return rc; return rc;
} }
int get(MDBDbi &dbi, const MDBInVal &key, MDBOutVal &val) int get(MDBDbi &dbi, const MDBInVal &key, MDBOutVal &val)
{ {
if (!d_txn) if (!d_txn)
throw LMDBError("Attempt to use a closed RW transaction for get"); throw LMDBError("Attempt to use a closed RW transaction for get");
const auto rc = mdb_get(d_txn, dbi, const_cast<MDB_val*>(&key.d_mdbval), const auto rc = mdb_get(d_txn, dbi, const_cast<MDB_val *>(&key.d_mdbval), &val.d_mdbval);
&val.d_mdbval);
if (rc && rc != MDB_NOTFOUND) if (rc && rc != MDB_NOTFOUND)
throw LMDBError("Getting data: ", rc); throw LMDBError("Getting data: ", rc);
return rc; return rc;
@ -607,8 +576,7 @@ public:
* be closed when its transaction ends." This is a problem for us since it may means we are closing * be closed when its transaction ends." This is a problem for us since it may means we are closing
* the cursor twice, which is bad. * the cursor twice, which is bad.
*/ */
class LMDB_SAFE_EXPORT MDBRWCursor : public MDBGenCursor<MDBRWTransactionImpl, MDBRWCursor> class LMDB_SAFE_EXPORT MDBRWCursor : public MDBGenCursor<MDBRWTransactionImpl, MDBRWCursor> {
{
public: public:
MDBRWCursor() = default; MDBRWCursor() = default;
using MDBGenCursor<MDBRWTransactionImpl, MDBRWCursor>::MDBGenCursor; using MDBGenCursor<MDBRWTransactionImpl, MDBRWCursor>::MDBGenCursor;
@ -620,18 +588,13 @@ public:
void put(const MDBOutVal &key, const MDBInVal &data) void put(const MDBOutVal &key, const MDBInVal &data)
{ {
if(const auto rc = mdb_cursor_put(*this, if (const auto rc = mdb_cursor_put(*this, const_cast<MDB_val *>(&key.d_mdbval), const_cast<MDB_val *>(&data.d_mdbval), MDB_CURRENT))
const_cast<MDB_val*>(&key.d_mdbval),
const_cast<MDB_val*>(&data.d_mdbval), MDB_CURRENT))
throw LMDBError("Putting data via mdb_cursor_put: ", rc); throw LMDBError("Putting data via mdb_cursor_put: ", rc);
} }
void put(const MDBOutVal &key, const MDBOutVal &data, unsigned int flags = 0) void put(const MDBOutVal &key, const MDBOutVal &data, unsigned int flags = 0)
{ {
if (const auto rc = mdb_cursor_put(*this, if (const auto rc = mdb_cursor_put(*this, const_cast<MDB_val *>(&key.d_mdbval), const_cast<MDB_val *>(&data.d_mdbval), flags))
const_cast<MDB_val*>(&key.d_mdbval),
const_cast<MDB_val*>(&data.d_mdbval), flags))
throw LMDBError("Putting data via mdb_cursor_put: ", rc); throw LMDBError("Putting data via mdb_cursor_put: ", rc);
} }
@ -640,7 +603,6 @@ public:
if (const auto rc = mdb_cursor_del(*this, flags)) if (const auto rc = mdb_cursor_del(*this, flags))
throw LMDBError("Deleting data via mdb_cursor_del: ", rc); throw LMDBError("Deleting data via mdb_cursor_del: ", rc);
} }
}; };
} } // namespace LMDBSafe

View File

@ -13,4 +13,4 @@ unsigned int MDBGetMaxID(MDBRWTransaction& txn, MDBDbi& dbi)
return maxid; return maxid;
} }
} } // namespace LMDBSafe

View File

@ -24,32 +24,26 @@ LMDB_SAFE_EXPORT unsigned int MDBGetMaxID(MDBRWTransaction& txn, MDBDbi& dbi);
/** This is the serialization interface. /** This is the serialization interface.
You need to define your these functions for the types you'd like to store. You need to define your these functions for the types you'd like to store.
*/ */
template<typename T> template <typename T> std::string serToString(const T &t);
std::string serToString(const T& t);
template<typename T> template <typename T> void serFromString(string_view str, T &ret);
void serFromString(string_view str, T& ret);
/** This is the serialization interface for keys. /** This is the serialization interface for keys.
You need to define your these functions for the types you'd like to use as keys. You need to define your these functions for the types you'd like to use as keys.
*/ */
template <class T, class Enable> template <class T, class Enable> inline std::string keyConv(const T &t);
inline std::string keyConv(const T& t);
template <class T, typename std::enable_if<std::is_arithmetic<T>::value,T>::type* = nullptr> template <class T, typename std::enable_if<std::is_arithmetic<T>::value, T>::type * = nullptr> inline string_view keyConv(const T &t)
inline string_view keyConv(const T& t)
{ {
return string_view(reinterpret_cast<const char *>(&t), sizeof(t)); return string_view(reinterpret_cast<const char *>(&t), sizeof(t));
} }
template<class T, typename std::enable_if<std::is_same<T, std::string>::value,T>::type* = nullptr> template <class T, typename std::enable_if<std::is_same<T, std::string>::value, T>::type * = nullptr> inline string_view keyConv(const T &t)
inline string_view keyConv(const T& t)
{ {
return t; return t;
} }
template<class T, typename std::enable_if<std::is_same<T, string_view>::value,T>::type* = nullptr> template <class T, typename std::enable_if<std::is_same<T, string_view>::value, T>::type * = nullptr> inline string_view keyConv(string_view t)
inline string_view keyConv(string_view t)
{ {
return t; return t;
} }
@ -65,10 +59,11 @@ inline string_view keyConv(string_view t)
* size<t> or get<t>. People ask for those themselves, and should no do that on indexes that * size<t> or get<t>. People ask for those themselves, and should no do that on indexes that
* don't exist. * don't exist.
*/ */
template<class Class,typename Type, typename Parent> template <class Class, typename Type, typename Parent> struct LMDB_SAFE_EXPORT LMDBIndexOps {
struct LMDB_SAFE_EXPORT LMDBIndexOps explicit LMDBIndexOps(Parent *parent)
: d_parent(parent)
{ {
explicit LMDBIndexOps(Parent* parent) : d_parent(parent){} }
void put(MDBRWTransaction &txn, const Class &t, uint32_t id, unsigned int flags = 0) void put(MDBRWTransaction &txn, const Class &t, uint32_t id, unsigned int flags = 0)
{ {
txn->put(d_idx, keyConv(d_parent->getMember(t)), id, flags); txn->put(d_idx, keyConv(d_parent->getMember(t)), id, flags);
@ -98,11 +93,11 @@ struct LMDB_SAFE_EXPORT LMDBIndexOps
/** This is an index on a field in a struct, it derives from the LMDBIndexOps */ /** This is an index on a field in a struct, it derives from the LMDBIndexOps */
template<class Class,typename Type,Type Class::*PtrToMember> template <class Class, typename Type, Type Class::*PtrToMember> struct index_on : LMDBIndexOps<Class, Type, index_on<Class, Type, PtrToMember>> {
struct index_on : LMDBIndexOps<Class, Type, index_on<Class, Type, PtrToMember>> index_on()
: LMDBIndexOps<Class, Type, index_on<Class, Type, PtrToMember>>(this)
{ {
index_on() : LMDBIndexOps<Class, Type, index_on<Class, Type, PtrToMember>>(this) }
{}
static Type getMember(const Class &c) static Type getMember(const Class &c)
{ {
return c.*PtrToMember; return c.*PtrToMember;
@ -112,11 +107,11 @@ struct index_on : LMDBIndexOps<Class, Type, index_on<Class, Type, PtrToMember>>
}; };
/** This is a calculated index */ /** This is a calculated index */
template<class Class, typename Type, class Func> template <class Class, typename Type, class Func> struct index_on_function : LMDBIndexOps<Class, Type, index_on_function<Class, Type, Func>> {
struct index_on_function : LMDBIndexOps<Class, Type, index_on_function<Class, Type, Func> > index_on_function()
: LMDBIndexOps<Class, Type, index_on_function<Class, Type, Func>>(this)
{ {
index_on_function() : LMDBIndexOps<Class, Type, index_on_function<Class, Type, Func> >(this) }
{}
static Type getMember(const Class &c) static Type getMember(const Class &c)
{ {
Func f; Func f;
@ -127,25 +122,21 @@ struct index_on_function : LMDBIndexOps<Class, Type, index_on_function<Class, Ty
}; };
/** nop index, so we can fill our N indexes, even if you don't use them all */ /** nop index, so we can fill our N indexes, even if you don't use them all */
struct nullindex_t struct nullindex_t {
{ template <typename Class> void put(MDBRWTransaction &txn, const Class &t, uint32_t id, unsigned int flags = 0)
template<typename Class>
void put(MDBRWTransaction& txn, const Class& t, uint32_t id, unsigned int flags=0)
{ {
(void)txn; (void)txn;
(void)t; (void)t;
(void)id; (void)id;
(void)flags; (void)flags;
} }
template<typename Class> template <typename Class> void del(MDBRWTransaction &txn, const Class &t, uint32_t id)
void del(MDBRWTransaction& txn, const Class& t, uint32_t id)
{ {
(void)txn; (void)txn;
(void)t; (void)t;
(void)id; (void)id;
} }
template<typename Class> template <typename Class> void clear(Class &txn)
void clear(Class& txn)
{ {
(void)txn; (void)txn;
} }
@ -159,14 +150,13 @@ struct nullindex_t
typedef uint32_t type; // dummy typedef uint32_t type; // dummy
}; };
/** The main class. Templatized only on the indexes and typename right now */ /** The main class. Templatized only on the indexes and typename right now */
template <typename T, class I1 = nullindex_t, class I2 = nullindex_t, class I3 = nullindex_t, class I4 = nullindex_t> template <typename T, class I1 = nullindex_t, class I2 = nullindex_t, class I3 = nullindex_t, class I4 = nullindex_t>
class LMDB_SAFE_EXPORT TypedDBI class LMDB_SAFE_EXPORT TypedDBI {
{
public: public:
TypedDBI(std::shared_ptr<MDBEnv> env, string_view name) TypedDBI(std::shared_ptr<MDBEnv> env, string_view name)
: d_env(env), d_name(name) : d_env(env)
, d_name(name)
{ {
d_main = d_env->openDB(name, MDB_CREATE | MDB_INTEGERKEY); d_main = d_env->openDB(name, MDB_CREATE | MDB_INTEGERKEY);
@ -181,18 +171,17 @@ public:
#undef openMacro #undef openMacro
} }
// we get a lot of our smarts from this tuple, it enables get<0> etc // we get a lot of our smarts from this tuple, it enables get<0> etc
typedef std::tuple<I1, I2, I3, I4> tuple_t; typedef std::tuple<I1, I2, I3, I4> tuple_t;
tuple_t d_tuple; tuple_t d_tuple;
// We support readonly and rw transactions. Here we put the Readonly operations // We support readonly and rw transactions. Here we put the Readonly operations
// which get sourced by both kinds of transactions // which get sourced by both kinds of transactions
template<class Parent> template <class Parent> struct ReadonlyOperations {
struct ReadonlyOperations ReadonlyOperations(Parent &parent)
: d_parent(parent)
{ {
ReadonlyOperations(Parent& parent) : d_parent(parent) }
{}
//! Number of entries in main database //! Number of entries in main database
size_t size() size_t size()
@ -203,8 +192,7 @@ public:
} }
//! Number of entries in the various indexes - should be the same //! Number of entries in the various indexes - should be the same
template<int N> template <int N> size_t size()
size_t size()
{ {
MDB_stat stat; MDB_stat stat;
mdb_stat(**d_parent.d_txn, std::get<N>(d_parent.d_parent->d_tuple).d_idx, &stat); mdb_stat(**d_parent.d_txn, std::get<N>(d_parent.d_parent->d_tuple).d_idx, &stat);
@ -223,8 +211,7 @@ public:
} }
//! Get item through index N, then via the main database //! Get item through index N, then via the main database
template<std::size_t N> template <std::size_t N> uint32_t get(const typename std::tuple_element<N, tuple_t>::type::type &key, T &out)
uint32_t get(const typename std::tuple_element<N, tuple_t>::type::type& key, T& out)
{ {
MDBOutVal id; MDBOutVal id;
if (!(*d_parent.d_txn)->get(std::get<N>(d_parent.d_parent->d_tuple).d_idx, keyConv(key), id)) { if (!(*d_parent.d_txn)->get(std::get<N>(d_parent.d_parent->d_tuple).d_idx, keyConv(key), id)) {
@ -235,8 +222,7 @@ public:
} }
//! Cardinality of index N //! Cardinality of index N
template<std::size_t N> template <std::size_t N> uint32_t cardinality()
uint32_t cardinality()
{ {
auto cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx); auto cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
bool first = true; bool first = true;
@ -250,21 +236,22 @@ public:
} }
//! End iderator type //! End iderator type
struct eiter_t struct eiter_t {
{}; };
// can be on main, or on an index // can be on main, or on an index
// when on main, return data directly // when on main, return data directly
// when on index, indirect // when on index, indirect
// we can be limited to one key, or iterate over entire database // we can be limited to one key, or iterate over entire database
// iter requires you to put the cursor in the right place first! // iter requires you to put the cursor in the right place first!
struct iter_t struct iter_t {
{ explicit iter_t(Parent *parent, typename Parent::cursor_t &&cursor, bool on_index, bool one_key, bool end = false)
explicit iter_t(Parent* parent, typename Parent::cursor_t&& cursor, bool on_index, bool one_key, bool end=false) : : d_parent(parent)
d_parent(parent), , d_cursor(std::move(cursor))
d_cursor(std::move(cursor)), , d_on_index(on_index)
d_on_index(on_index), // is this an iterator on main database or on index? , // is this an iterator on main database or on index?
d_one_key(one_key), // should we stop at end of key? (equal range) d_one_key(one_key)
, // should we stop at end of key? (equal range)
d_end(end) d_end(end)
{ {
if (d_end) if (d_end)
@ -280,18 +267,18 @@ public:
if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data)) if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
throw LMDBError("Missing id in constructor"); throw LMDBError("Missing id in constructor");
serFromString(d_data.get<string_view>(), d_t); serFromString(d_data.get<string_view>(), d_t);
} } else
else
serFromString(d_id.get<string_view>(), d_t); serFromString(d_id.get<string_view>(), d_t);
} }
explicit iter_t(Parent* parent, typename Parent::cursor_t&& cursor, string_view prefix) : explicit iter_t(Parent *parent, typename Parent::cursor_t &&cursor, string_view prefix)
d_parent(parent), : d_parent(parent)
d_cursor(std::move(cursor)), , d_cursor(std::move(cursor))
d_on_index(true), // is this an iterator on main database or on index? , d_on_index(true)
d_one_key(false), , // is this an iterator on main database or on index?
d_prefix(prefix), d_one_key(false)
d_end(false) , d_prefix(prefix)
, d_end(false)
{ {
if (d_end) if (d_end)
return; return;
@ -305,12 +292,10 @@ public:
if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data)) if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, d_data))
throw LMDBError("Missing id in constructor"); throw LMDBError("Missing id in constructor");
serFromString(d_data.get<string_view>(), d_t); serFromString(d_data.get<string_view>(), d_t);
} } else
else
serFromString(d_id.get<string_view>(), d_t); serFromString(d_id.get<string_view>(), d_t);
} }
std::function<bool(const MDBOutVal &)> filter; std::function<bool(const MDBOutVal &)> filter;
void del() void del()
{ {
@ -350,14 +335,11 @@ public:
const auto rc = d_cursor.get(d_key, d_id, d_one_key ? dupop : op); const auto rc = d_cursor.get(d_key, d_id, d_one_key ? dupop : op);
if (rc == MDB_NOTFOUND) { if (rc == MDB_NOTFOUND) {
d_end = true; d_end = true;
} } else if (rc) {
else if(rc) {
throw LMDBError("Unable to get in genoperator: ", rc); throw LMDBError("Unable to get in genoperator: ", rc);
} } else if (!d_prefix.empty() && d_key.get<std::string>().rfind(d_prefix, 0) != 0) {
else if(!d_prefix.empty() && d_key.get<std::string>().rfind(d_prefix, 0)!=0) {
d_end = true; d_end = true;
} } else {
else {
if (d_on_index) { if (d_on_index) {
if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, data)) if ((*d_parent->d_txn)->get(d_parent->d_parent->d_main, d_id, data))
throw LMDBError("Missing id field in genoperator"); throw LMDBError("Missing id field in genoperator");
@ -365,8 +347,7 @@ public:
goto next; goto next;
serFromString(data.get<string_view>(), d_t); serFromString(data.get<string_view>(), d_t);
} } else {
else {
if (filter && !filter(data)) if (filter && !filter(data))
goto next; goto next;
@ -399,7 +380,6 @@ public:
return d_key; return d_key;
} }
// transaction we are part of // transaction we are part of
Parent *d_parent; Parent *d_parent;
typename Parent::cursor_t d_cursor; typename Parent::cursor_t d_cursor;
@ -413,8 +393,7 @@ public:
T d_t; T d_t;
}; };
template<int N> template <int N> iter_t genbegin(MDB_cursor_op op)
iter_t genbegin(MDB_cursor_op op)
{ {
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx); typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
@ -428,14 +407,12 @@ public:
return iter_t{ &d_parent, std::move(cursor), true, false }; return iter_t{ &d_parent, std::move(cursor), true, false };
}; };
template<int N> template <int N> iter_t begin()
iter_t begin()
{ {
return genbegin<N>(MDB_FIRST); return genbegin<N>(MDB_FIRST);
} }
template<int N> template <int N> iter_t rbegin()
iter_t rbegin()
{ {
return genbegin<N>(MDB_LAST); return genbegin<N>(MDB_LAST);
} }
@ -460,8 +437,7 @@ public:
} }
// basis for find, lower_bound // basis for find, lower_bound
template<std::size_t N> template <std::size_t N> iter_t genfind(const typename std::tuple_element<N, tuple_t>::type::type &key, MDB_cursor_op op)
iter_t genfind(const typename std::tuple_element<N, tuple_t>::type::type& key, MDB_cursor_op op)
{ {
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx); typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
@ -478,22 +454,18 @@ public:
return iter_t{ &d_parent, std::move(cursor), true, false }; return iter_t{ &d_parent, std::move(cursor), true, false };
}; };
template<std::size_t N> template <std::size_t N> iter_t find(const typename std::tuple_element<N, tuple_t>::type::type &key)
iter_t find(const typename std::tuple_element<N, tuple_t>::type::type& key)
{ {
return genfind<N>(key, MDB_SET); return genfind<N>(key, MDB_SET);
} }
template<std::size_t N> template <std::size_t N> iter_t lower_bound(const typename std::tuple_element<N, tuple_t>::type::type &key)
iter_t lower_bound(const typename std::tuple_element<N, tuple_t>::type::type& key)
{ {
return genfind<N>(key, MDB_SET_RANGE); return genfind<N>(key, MDB_SET_RANGE);
} }
//! equal range - could possibly be expressed through genfind //! equal range - could possibly be expressed through genfind
template<std::size_t N> template <std::size_t N> std::pair<iter_t, eiter_t> equal_range(const typename std::tuple_element<N, tuple_t>::type::type &key)
std::pair<iter_t,eiter_t> equal_range(const typename std::tuple_element<N, tuple_t>::type::type& key)
{ {
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx); typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
@ -511,8 +483,7 @@ public:
}; };
//! equal range - could possibly be expressed through genfind //! equal range - could possibly be expressed through genfind
template<std::size_t N> template <std::size_t N> std::pair<iter_t, eiter_t> prefix_range(const typename std::tuple_element<N, tuple_t>::type::type &key)
std::pair<iter_t,eiter_t> prefix_range(const typename std::tuple_element<N, tuple_t>::type::type& key)
{ {
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx); typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
@ -529,24 +500,29 @@ public:
return { iter_t(&d_parent, std::move(cursor), keyString), eiter_t() }; return { iter_t(&d_parent, std::move(cursor), keyString), eiter_t() };
}; };
Parent &d_parent; Parent &d_parent;
}; };
class LMDB_SAFE_EXPORT ROTransaction : public ReadonlyOperations<ROTransaction> class LMDB_SAFE_EXPORT ROTransaction : public ReadonlyOperations<ROTransaction> {
{
public: public:
explicit ROTransaction(TypedDBI* parent) : ReadonlyOperations<ROTransaction>(*this), d_parent(parent), d_txn(std::make_shared<MDBROTransaction>(d_parent->d_env->getROTransaction())) explicit ROTransaction(TypedDBI *parent)
: ReadonlyOperations<ROTransaction>(*this)
, d_parent(parent)
, d_txn(std::make_shared<MDBROTransaction>(d_parent->d_env->getROTransaction()))
{ {
} }
explicit ROTransaction(TypedDBI* parent, std::shared_ptr<MDBROTransaction> txn) : ReadonlyOperations<ROTransaction>(*this), d_parent(parent), d_txn(txn) explicit ROTransaction(TypedDBI *parent, std::shared_ptr<MDBROTransaction> txn)
: ReadonlyOperations<ROTransaction>(*this)
, d_parent(parent)
, d_txn(txn)
{ {
} }
ROTransaction(ROTransaction &&rhs)
ROTransaction(ROTransaction&& rhs) : : ReadonlyOperations<ROTransaction>(*this)
ReadonlyOperations<ROTransaction>(*this), d_parent(rhs.d_parent),d_txn(std::move(rhs.d_txn)) , d_parent(rhs.d_parent)
, d_txn(std::move(rhs.d_txn))
{ {
rhs.d_parent = 0; rhs.d_parent = 0;
@ -563,23 +539,26 @@ public:
std::shared_ptr<MDBROTransaction> d_txn; std::shared_ptr<MDBROTransaction> d_txn;
}; };
class LMDB_SAFE_EXPORT RWTransaction : public ReadonlyOperations<RWTransaction> {
class LMDB_SAFE_EXPORT RWTransaction : public ReadonlyOperations<RWTransaction>
{
public: public:
explicit RWTransaction(TypedDBI* parent) : ReadonlyOperations<RWTransaction>(*this), d_parent(parent) explicit RWTransaction(TypedDBI *parent)
: ReadonlyOperations<RWTransaction>(*this)
, d_parent(parent)
{ {
d_txn = std::make_shared<MDBRWTransaction>(d_parent->d_env->getRWTransaction()); d_txn = std::make_shared<MDBRWTransaction>(d_parent->d_env->getRWTransaction());
} }
explicit RWTransaction(TypedDBI* parent, std::shared_ptr<MDBRWTransaction> txn) : ReadonlyOperations<RWTransaction>(*this), d_parent(parent), d_txn(txn) explicit RWTransaction(TypedDBI *parent, std::shared_ptr<MDBRWTransaction> txn)
: ReadonlyOperations<RWTransaction>(*this)
, d_parent(parent)
, d_txn(txn)
{ {
} }
RWTransaction(RWTransaction &&rhs)
RWTransaction(RWTransaction&& rhs) : : ReadonlyOperations<RWTransaction>(*this)
ReadonlyOperations<RWTransaction>(*this), , d_parent(rhs.d_parent)
d_parent(rhs.d_parent), d_txn(std::move(rhs.d_txn)) , d_txn(std::move(rhs.d_txn))
{ {
rhs.d_parent = 0; rhs.d_parent = 0;
} }
@ -660,7 +639,6 @@ public:
return d_txn; return d_txn;
} }
private: private:
// clear this ID from all indexes // clear this ID from all indexes
void clearIndex(uint32_t id, const T &t) void clearIndex(uint32_t id, const T &t)
@ -713,4 +691,4 @@ private:
std::string d_name; std::string d_name;
}; };
} } // namespace LMDBSafe