Electroneum
Loading...
Searching...
No Matches
database.h
Go to the documentation of this file.
1// Copyright (c) 2018, The Monero Project
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are
5// permitted provided that the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of
8// conditions and the following disclaimer.
9//
10// 2. Redistributions in binary form must reproduce the above copyright notice, this list
11// of conditions and the following disclaimer in the documentation and/or other
12// materials provided with the distribution.
13//
14// 3. Neither the name of the copyright holder nor the names of its contributors may be
15// used to endorse or promote products derived from this software without specific
16// prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
19// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#pragma once
28
29#include <atomic>
30#include <cstddef>
31#include <lmdb.h>
32#include <memory>
33#include <type_traits>
34
35#include "common/expect.h"
36#include "lmdb/error.h"
37#include "lmdb/transaction.h"
38
39namespace lmdb
40{
42 struct close_env
43 {
44 void operator()(MDB_env* ptr) const noexcept
45 {
46 if (ptr)
47 mdb_env_close(ptr);
48 }
49 };
50
51 using environment = std::unique_ptr<MDB_env, close_env>;
52
54 expect<environment> open_environment(const char* path, MDB_dbi max_dbs) noexcept;
55
57 struct context
58 {
59 std::atomic<std::size_t> active;
60 std::atomic_flag lock;
61 };
62
65 {
66 environment env;
67 context ctx;
68
70 MDB_env* handle() const noexcept { return env.get(); }
71
72 expect<write_txn> do_create_txn(unsigned int flags) noexcept;
73
74 public:
76
77 database(database&&) = delete;
78 database(database const&) = delete;
79
80 virtual ~database() noexcept;
81
82 database& operator=(database&&) = delete;
83 database& operator=(database const&) = delete;
84
89 expect<void> resize() noexcept;
90
92 expect<read_txn> create_read_txn(suspended_txn txn = nullptr) noexcept;
93
96
99
101 expect<void> commit(write_txn txn) noexcept;
102
112 template<typename F>
113 typename std::result_of<F(MDB_txn&)>::type try_write(F f, unsigned attempts = 3)
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 {
125 ELECTRONEUM_CHECK(commit(std::move(*txn)));
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 }
136 };
137} // lmdb
138
*return False if otherwise error()
database(database const &)=delete
expect< suspended_txn > reset_txn(read_txn txn) noexcept
Definition database.cpp:166
expect< void > commit(write_txn txn) noexcept
Commit the read-write transaction.
Definition database.cpp:179
expect< write_txn > create_write_txn() noexcept
Definition database.cpp:174
database(database &&)=delete
expect< void > resize() noexcept
Definition database.cpp:129
virtual ~database() noexcept
Definition database.cpp:124
std::result_of< F(MDB_txn &)>::type try_write(F f, unsigned attempts=3)
Definition database.h:113
expect< read_txn > create_read_txn(suspended_txn txn=nullptr) noexcept
Definition database.cpp:147
database(environment env)
Definition database.cpp:113
#define F(s)
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return error::kInvalidArgument in current scope.
Definition expect.h:39
#define ELECTRONEUM_CHECK(...)
Check expect<void> and return errors in current scope.
Definition expect.h:47
#define MDB_MAP_FULL
Definition lmdb.h:451
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
struct MDB_env MDB_env
Opaque structure for a database environment.
Definition lmdb.h:260
struct MDB_txn MDB_txn
Opaque structure for a transaction handle.
Definition lmdb.h:267
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition lmdb.h:270
Lightning memory-mapped database library.
std::unique_ptr< MDB_txn, abort_write_txn > write_txn
Definition transaction.h:94
std::unique_ptr< MDB_env, close_env > environment
Definition database.h:51
std::unique_ptr< MDB_txn, release_read_txn > read_txn
Definition transaction.h:93
error
Tracks LMDB error codes.
Definition error.h:45
expect< environment > open_environment(const char *path, MDB_dbi max_dbs) noexcept
Definition database.cpp:78
std::unique_ptr< MDB_txn, abort_txn > suspended_txn
Definition transaction.h:92
STL namespace.
Closes LMDB environment handle.
Definition database.h:43
void operator()(MDB_env *ptr) const noexcept
Definition database.h:44
Context given to LMDB.
Definition database.h:58
std::atomic< std::size_t > active
Definition database.h:59
std::atomic_flag lock
Definition database.h:60