Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
queries.cpp
Go to the documentation of this file.
6#include "lmdb.h"
7#include <cstdint>
8#include <vector>
9
11
13 Key& key, Value& data, const LMDBDatabase& db, bb::lmdblib::LMDBWriteTransaction& tx, bool duplicatesPermitted)
14{
15 MDB_val dbKey;
16 dbKey.mv_size = key.size();
17 dbKey.mv_data = (void*)key.data();
18
19 MDB_val dbVal;
20 dbVal.mv_size = data.size();
21 dbVal.mv_data = (void*)data.data();
22
23 // The database has been configured to allow duplicate keys, but we don't permit duplicate key/value pairs
24 // If we create a duplicate it will not insert it
25 unsigned int flags = duplicatesPermitted ? MDB_NODUPDATA : 0U;
26 auto code = call_lmdb_func_with_return(mdb_put, tx.underlying(), db.underlying(), &dbKey, &dbVal, flags);
27 if (code == MDB_KEYEXIST && duplicatesPermitted) {
28 return;
29 }
30
31 if (code != MDB_SUCCESS) {
32 throw_error("mdb_put", code);
33 }
34}
35
37 const uint64_t& data,
38 const LMDBDatabase& db,
40 bool duplicatesPermitted)
41{
42 MDB_val dbKey;
43 dbKey.mv_size = key.size();
44 dbKey.mv_data = (void*)key.data();
45
46 // use the serialise key method for serialising the index
47 Value serialised = serialise_key(data);
48
49 MDB_val dbVal;
50 dbVal.mv_size = serialised.size();
51 dbVal.mv_data = (void*)serialised.data();
52
53 // The database has been configured to allow duplicate keys, but we don't permit duplicate key/value pairs
54 // If we create a duplicate it will not insert it
55 unsigned int flags = duplicatesPermitted ? MDB_NODUPDATA : 0U;
56 call_lmdb_func("mdb_put", mdb_put, tx.underlying(), db.underlying(), &dbKey, &dbVal, flags);
57}
58
60{
61 MDB_val dbKey;
62 dbKey.mv_size = key.size();
63 dbKey.mv_data = (void*)key.data();
64
65 MDB_val* dbVal = nullptr;
66 int code = call_lmdb_func_with_return(mdb_del, tx.underlying(), db.underlying(), &dbKey, dbVal);
67 if (code != MDB_SUCCESS && code != MDB_NOTFOUND) {
68 throw_error("mdb_del", code);
69 }
70}
71
73{
74 MDB_val dbKey;
75 dbKey.mv_size = key.size();
76 dbKey.mv_data = (void*)key.data();
77
78 MDB_val dbVal;
79 dbVal.mv_size = value.size();
80 dbVal.mv_data = (void*)value.data();
81
82 int code = call_lmdb_func_with_return(mdb_del, tx.underlying(), db.underlying(), &dbKey, &dbVal);
83 if (code != MDB_SUCCESS && code != MDB_NOTFOUND) {
84 throw_error("mdb_del", code);
85 }
86}
87
89{
90 MDB_val dbKey;
91 dbKey.mv_size = key.size();
92 dbKey.mv_data = (void*)key.data();
93
94 MDB_val dbVal;
95 if (!call_lmdb_func(mdb_get, tx.underlying(), db.underlying(), &dbKey, &dbVal)) {
96 return false;
97 }
98 copy_to_vector(dbVal, data);
99 return true;
100}
101
102bool get_value(Key& key, uint64_t& data, const LMDBDatabase& db, const bb::lmdblib::LMDBTransaction& tx)
103{
104 MDB_val dbKey;
105 dbKey.mv_size = key.size();
106 dbKey.mv_data = (void*)key.data();
107
108 MDB_val dbVal;
109 if (!call_lmdb_func(mdb_get, tx.underlying(), db.underlying(), &dbKey, &dbVal)) {
110 return false;
111 }
112 // use the deserialise key method for deserializing the index
113 deserialise_key(dbVal.mv_data, data);
114 return true;
115}
116
117bool set_at_key(const LMDBCursor& cursor, Key& key)
118{
119 MDB_val dbKey;
120 dbKey.mv_size = key.size();
121 dbKey.mv_data = (void*)key.data();
122
123 MDB_val dbVal;
124 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_SET);
125 return code == MDB_SUCCESS;
126}
127
128bool set_at_key_gte(const LMDBCursor& cursor, Key& key)
129{
130 MDB_val dbKey;
131 dbKey.mv_size = key.size();
132 dbKey.mv_data = (void*)key.data();
133
134 MDB_val dbVal;
135 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_SET_RANGE);
136 return code == MDB_SUCCESS;
137}
138
139bool set_at_start(const LMDBCursor& cursor)
140{
141 MDB_val dbKey;
142 MDB_val dbVal;
143 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_FIRST);
144 return code == MDB_SUCCESS;
145}
146
147bool set_at_end(const LMDBCursor& cursor)
148{
149 MDB_val dbKey;
150 MDB_val dbVal;
151 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_LAST);
152 return code == MDB_SUCCESS;
153}
154
155bool read_next(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead, MDB_cursor_op op)
156{
157 uint64_t numKeysRead = 0;
158 MDB_val dbKey;
159 MDB_val dbVal;
160 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_GET_CURRENT);
161 while (numKeysRead < numKeysToRead && code == MDB_SUCCESS) {
162 // extract the key and value
163 Value value;
164 Key key;
165 copy_to_vector(dbVal, value);
166 copy_to_vector(dbKey, key);
167 ValuesVector values;
168 values.emplace_back(std::move(value));
169 keyValues.emplace_back(std::move(key), std::move(values));
170 ++numKeysRead;
171 // move to the next key
172 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, op);
173 }
174
175 return code != MDB_SUCCESS; // we're done
176}
177
178bool count_until_next(const LMDBCursor& cursor, const Key& targetKey, uint64_t& count, MDB_cursor_op op)
179{
180 count = 0;
181 MDB_val dbKey;
182 MDB_val dbVal;
183 MDB_val dbTargetKey;
184 dbTargetKey.mv_size = targetKey.size();
185 dbTargetKey.mv_data = (void*)targetKey.data();
186 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_GET_CURRENT);
187 while (code == MDB_SUCCESS) {
188 int result = mdb_cmp(cursor.underlying_tx(), cursor.underlying_db(), &dbKey, &dbTargetKey);
189 if ((result >= 0 && op == MDB_NEXT) || (result <= 0 && op == MDB_PREV)) {
190 return false;
191 }
192 ++count;
193 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, op);
194 }
195 return true; // we must have run out of keys
196}
197
198bool read_next_dup(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead, MDB_cursor_op op)
199{
200 uint64_t numKeysRead = 0;
201 MDB_val dbKey;
202 MDB_val dbVal;
203 ValuesVector values;
204
205 // ensure we are positioned at first data item of current key
206 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_FIRST_DUP);
207 while (numKeysRead < numKeysToRead && code == MDB_SUCCESS) {
208 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_GET_CURRENT);
209 // extract the key and value
210 Value value;
211 Key key;
212 copy_to_vector(dbVal, value);
213 copy_to_vector(dbKey, key);
214 values.push_back(value);
215
216 // move to the next value at this key
217 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_NEXT_DUP);
218 if (code == MDB_NOTFOUND) {
219 // No more values at this key
220 ++numKeysRead;
221 keyValues.emplace_back(std::move(key), std::move(values));
222 values = ValuesVector();
223 // move to the next key
224 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, op);
225 if (code == MDB_SUCCESS) {
226 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_FIRST_DUP);
227 } else {
228 // no more keys to read
229 return true;
230 }
231 }
232 }
233
234 return false;
235}
236
237bool count_until_next_dup(const LMDBCursor& cursor, const Key& targetKey, uint64_t& count, MDB_cursor_op op)
238{
239 count = 0;
240 MDB_val dbKey;
241 MDB_val dbVal;
242 Key currentKey;
243 bool newKey = true;
244 MDB_val dbTargetKey;
245 dbTargetKey.mv_size = targetKey.size();
246 dbTargetKey.mv_data = (void*)targetKey.data();
247
248 // ensure we are positioned at first data item of current key
249 int code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_FIRST_DUP);
250 while (code == MDB_SUCCESS) {
251 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_GET_CURRENT);
252 if (newKey) {
253 int result = mdb_cmp(cursor.underlying_tx(), cursor.underlying_db(), &dbKey, &dbTargetKey);
254 if ((result >= 0 && op == MDB_NEXT_NODUP) || (result <= 0 && op == MDB_PREV_NODUP)) {
255 return false;
256 }
257 newKey = false;
258 }
259 ++count;
260 // move to the next value at this key
261 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_NEXT_DUP);
262 if (code == MDB_NOTFOUND) {
263 // move to the next key
264 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, op);
265 if (code == MDB_SUCCESS) {
266 newKey = true;
267 code = mdb_cursor_get(cursor.underlying(), &dbKey, &dbVal, MDB_FIRST_DUP);
268 } else {
269 // no more keys to read
270 return true;
271 }
272 }
273 }
274 return true;
275}
276
277bool read_next(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead)
278{
279 return read_next(cursor, keyValues, numKeysToRead, MDB_NEXT);
280}
281bool read_prev(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead)
282{
283 return read_next(cursor, keyValues, numKeysToRead, MDB_PREV);
284}
285
286bool read_next_dup(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead)
287{
288 return read_next_dup(cursor, keyValues, numKeysToRead, MDB_NEXT_NODUP);
289}
290bool read_prev_dup(const LMDBCursor& cursor, KeyDupValuesVector& keyValues, uint64_t numKeysToRead)
291{
292 return read_next_dup(cursor, keyValues, numKeysToRead, MDB_PREV_NODUP);
293}
294
295bool count_until_next(const LMDBCursor& cursor, const Key& key, uint64_t& count)
296{
297 return count_until_next(cursor, key, count, MDB_NEXT);
298}
299
300bool count_until_prev(const LMDBCursor& cursor, const Key& key, uint64_t& count)
301{
302 return count_until_next(cursor, key, count, MDB_PREV);
303}
304
305bool count_until_next_dup(const LMDBCursor& cursor, const Key& key, uint64_t& count)
306{
307 return count_until_next_dup(cursor, key, count, MDB_NEXT_NODUP);
308}
309
310bool count_until_prev_dup(const LMDBCursor& cursor, const Key& key, uint64_t& count)
311{
312 return count_until_next_dup(cursor, key, count, MDB_PREV_NODUP);
313}
314} // namespace bb::lmdblib::lmdb_queries
const MDB_dbi & underlying_db() const
MDB_txn * underlying_tx() const
MDB_cursor * underlying() const
const MDB_dbi & underlying() const
const std::vector< FF > data
void delete_value(Key &key, const LMDBDatabase &db, bb::lmdblib::LMDBWriteTransaction &tx)
Definition queries.cpp:59
bool read_prev_dup(const LMDBCursor &cursor, KeyDupValuesVector &keyValues, uint64_t numKeysToRead)
Definition queries.cpp:290
bool read_next(const LMDBCursor &cursor, KeyDupValuesVector &keyValues, uint64_t numKeysToRead, MDB_cursor_op op)
Definition queries.cpp:155
bool set_at_start(const LMDBCursor &cursor)
Definition queries.cpp:139
bool get_value(Key &key, Value &data, const LMDBDatabase &db, const bb::lmdblib::LMDBTransaction &tx)
Definition queries.cpp:88
bool count_until_next_dup(const LMDBCursor &cursor, const Key &targetKey, uint64_t &count, MDB_cursor_op op)
Definition queries.cpp:237
bool read_next_dup(const LMDBCursor &cursor, KeyDupValuesVector &keyValues, uint64_t numKeysToRead, MDB_cursor_op op)
Definition queries.cpp:198
bool set_at_key_gte(const LMDBCursor &cursor, Key &key)
Definition queries.cpp:128
bool count_until_prev(const LMDBCursor &cursor, const Key &key, uint64_t &count)
Definition queries.cpp:300
void put_value(Key &key, Value &data, const LMDBDatabase &db, bb::lmdblib::LMDBWriteTransaction &tx, bool duplicatesPermitted)
Definition queries.cpp:12
bool set_at_key(const LMDBCursor &cursor, Key &key)
Definition queries.cpp:117
bool read_prev(const LMDBCursor &cursor, KeyDupValuesVector &keyValues, uint64_t numKeysToRead)
Definition queries.cpp:281
bool set_at_end(const LMDBCursor &cursor)
Definition queries.cpp:147
bool count_until_next(const LMDBCursor &cursor, const Key &targetKey, uint64_t &count, MDB_cursor_op op)
Definition queries.cpp:178
bool count_until_prev_dup(const LMDBCursor &cursor, const Key &key, uint64_t &count)
Definition queries.cpp:310
std::vector< uint8_t > Key
Definition types.hpp:11
void deserialise_key(void *data, uint8_t &key)
std::vector< uint8_t > serialise_key(uint8_t key)
std::vector< uint8_t > Value
Definition types.hpp:12
void throw_error(const std::string &errorString, int error)
std::vector< KeyValuesPair > KeyDupValuesVector
Definition types.hpp:18
void copy_to_vector(const MDB_val &dbVal, std::vector< uint8_t > &target)
std::vector< Value > ValuesVector
Definition types.hpp:14
bool call_lmdb_func(int(*f)(TArgs...), TArgs... args)
int call_lmdb_func_with_return(int(*f)(TArgs...), TArgs... args)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13