Electroneum
lmdb::database Class Reference

Manages a LMDB environment for safe memory-map resizing. Thread-safe. More...

#include <database.h>

Public Member Functions

 database (environment env)
 
 database (database &&)=delete
 
 database (database const &)=delete
 
virtual ~database () noexcept
 
databaseoperator= (database &&)=delete
 
databaseoperator= (database const &)=delete
 
expect< void > resize () noexcept
 
expect< read_txncreate_read_txn (suspended_txn txn=nullptr) noexcept
 
expect< suspended_txnreset_txn (read_txn txn) noexcept
 
expect< write_txncreate_write_txn () noexcept
 
expect< void > commit (write_txn txn) noexcept
 Commit the read-write transaction. More...
 
template<typename F >
std::result_of< F(MDB_txn &)>::type try_write (F f, unsigned attempts=3)
 

Detailed Description

Manages a LMDB environment for safe memory-map resizing. Thread-safe.

Definition at line 64 of file database.h.

Constructor & Destructor Documentation

◆ database() [1/3]

lmdb::database::database ( environment  env)

Definition at line 113 of file database.cpp.

114  : env(std::move(env)), ctx{{}, ATOMIC_FLAG_INIT}
115  {
116  if (handle())
117  {
118  const int err = mdb_env_set_userctx(handle(), std::addressof(ctx));
119  if (err)
120  ELECTRONEUM_THROW(lmdb::error(err), "Failed to set user context");
121  }
122  }
const T & move(const T &t)
Definition: gtest-port.h:1317
int mdb_env_set_userctx(MDB_env *env, void *ctx)
Set application information associated with the MDB_env.
#define ELECTRONEUM_THROW(code, msg)
Definition: expect.h:66
error
Tracks LMDB error codes.
Definition: error.h:44

◆ database() [2/3]

lmdb::database::database ( database &&  )
delete

◆ database() [3/3]

lmdb::database::database ( database const &  )
delete

◆ ~database()

lmdb::database::~database ( )
virtualnoexcept

Definition at line 124 of file database.cpp.

125  {
126  while (ctx.active);
127  }
std::atomic< std::size_t > active
Definition: database.h:59

Member Function Documentation

◆ commit()

expect< void > lmdb::database::commit ( write_txn  txn)
noexcept

Commit the read-write transaction.

Definition at line 179 of file database.cpp.

180  {
181  ELECTRONEUM_PRECOND(txn != nullptr);
183  txn.release();
184  release_context(ctx);
185  return success();
186  }
#define ELECTRONEUM_LMDB_CHECK(...)
Executes a LMDB command, and returns errors via lmdb::error enum.
Definition: error.h:33
int mdb_txn_commit(MDB_txn *txn)
Commit all the operations of a transaction into the database.
expect< void > success() noexcept
Definition: expect.h:397
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return ::error::kInvalidArgument in current scope.
Definition: expect.h:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_read_txn()

expect< read_txn > lmdb::database::create_read_txn ( suspended_txn  txn = nullptr)
noexcept
Returns
A read only LMDB transaction, reusing txn if provided.

Definition at line 147 of file database.cpp.

148  {
149  if (txn)
150  {
151  acquire_context(ctx);
152  const int err = mdb_txn_renew(txn.get());
153  if (err)
154  {
155  release_context(ctx);
156  return {lmdb::error(err)};
157  }
158  return read_txn{txn.release()};
159  }
160  auto new_txn = do_create_txn(MDB_RDONLY);
161  if (new_txn)
162  return read_txn{new_txn->release()};
163  return new_txn.error();
164  }
#define MDB_RDONLY
Definition: lmdb.h:320
std::unique_ptr< MDB_txn, release_read_txn > read_txn
Definition: transaction.h:93
int mdb_txn_renew(MDB_txn *txn)
Renew a read-only transaction.
error
Tracks LMDB error codes.
Definition: error.h:44
Here is the call graph for this function:

◆ create_write_txn()

expect< write_txn > lmdb::database::create_write_txn ( )
noexcept
Returns
A read-write LMDB transaction.

Definition at line 174 of file database.cpp.

175  {
176  return do_create_txn(0);
177  }
Here is the caller graph for this function:

◆ operator=() [1/2]

database& lmdb::database::operator= ( database &&  )
delete

◆ operator=() [2/2]

database& lmdb::database::operator= ( database const &  )
delete

◆ reset_txn()

expect< suspended_txn > lmdb::database::reset_txn ( read_txn  txn)
noexcept
Returns
txn after releasing context.

Definition at line 166 of file database.cpp.

167  {
168  ELECTRONEUM_PRECOND(txn != nullptr);
169  mdb_txn_reset(txn.get());
170  release_context(ctx);
171  return suspended_txn{txn.release()};
172  }
std::unique_ptr< MDB_txn, abort_txn > suspended_txn
Definition: transaction.h:92
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return ::error::kInvalidArgument in current scope.
Definition: expect.h:39
Here is the call graph for this function:

◆ resize()

expect< void > lmdb::database::resize ( )
noexcept

Resize the memory map for the LMDB environment. Will block until all reads/writes on the environment complete.

Definition at line 129 of file database.cpp.

130  {
131  ELECTRONEUM_PRECOND(handle() != nullptr);
132 
133  while (ctx.lock.test_and_set());
134  while (ctx.active);
135 
136  MDB_envinfo info{};
138 
139  const mdb_size_t resize = std::min(info.me_mapsize, max_resize);
140  const int err = mdb_env_set_mapsize(handle(), info.me_mapsize + resize);
141  ctx.lock.clear();
142  if (err)
143  return {lmdb::error(err)};
144  return success();
145  }
int mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
Set the size of the memory map to use for this environment.
#define ELECTRONEUM_LMDB_CHECK(...)
Executes a LMDB command, and returns errors via lmdb::error enum.
Definition: error.h:33
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
std::atomic_flag lock
Definition: database.h:60
Information about the environment.
Definition: lmdb.h:501
expect< void > resize() noexcept
Definition: database.cpp:129
std::atomic< std::size_t > active
Definition: database.h:59
CXA_THROW_INFO_T * info
Definition: stack_trace.cpp:91
expect< void > success() noexcept
Definition: expect.h:397
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return ::error::kInvalidArgument in current scope.
Definition: expect.h:39
size_t mdb_size_t
Definition: lmdb.h:196
error
Tracks LMDB error codes.
Definition: error.h:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_write()

template<typename F >
std::result_of<F(MDB_txn&)>::type lmdb::database::try_write ( F  f,
unsigned  attempts = 3 
)
inline

Create a write transaction, pass it to f, then try to commit the write if f succeeds.

Template Parameters
Fmust be callable with signature expect<T>(MDB_txn&).
Parameters
fmust be re-startable if lmdb::error(MDB_MAP_FULL).
Returns
The result of calling f.

Definition at line 113 of file database.h.

114  {
115  for (unsigned i = 0; i < attempts; ++i)
116  {
118  if (!txn)
119  return txn.error();
120 
121  ELECTRONEUM_PRECOND(*txn != nullptr);
122  const auto wrote = f(*(*txn));
123  if (wrote)
124  {
126  return wrote;
127  }
128  if (wrote != lmdb::error(MDB_MAP_FULL))
129  return wrote;
130 
131  txn->reset();
132  ELECTRONEUM_CHECK(this->resize());
133  }
134  return {lmdb::error(MDB_MAP_FULL)};
135  }
std::error_code error() const noexcept
Definition: expect.h:276
expect< void > resize() noexcept
Definition: database.cpp:129
Definition: expect.h:70
expect< write_txn > create_write_txn() noexcept
Definition: database.cpp:174
#define ELECTRONEUM_CHECK(...)
Check expect<void> and return errors in current scope.
Definition: expect.h:47
expect< void > commit(write_txn txn) noexcept
Commit the read-write transaction.
Definition: database.cpp:179
#define MDB_MAP_FULL
Definition: lmdb.h:451
const T & move(const T &t)
Definition: gtest-port.h:1317
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return ::error::kInvalidArgument in current scope.
Definition: expect.h:39
error
Tracks LMDB error codes.
Definition: error.h:44
Here is the call graph for this function:

The documentation for this class was generated from the following files: