NCBI C++ ToolKit
lmdb++.h
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* This is free and unencumbered software released into the public domain. */
2 
3 #ifndef LMDBXX_H
4 #define LMDBXX_H
5 
6 /**
7  * <lmdb++.h> - C++11 wrapper for LMDB.
8  *
9  * @author Arto Bendiken <arto@bendiken.net>
10  * @see https://sourceforge.net/projects/lmdbxx/
11  */
12 
13 #ifndef __cplusplus
14 #error "<lmdb++.h> requires a C++ compiler"
15 #endif
16 
17 #if __cplusplus < 201103L
18 #if !defined(_MSC_VER) || _MSC_VER < 1900
19 #error "<lmdb++.h> requires a C++11 compiler (CXXFLAGS='-std=c++11')"
20 #endif // _MSC_VER check
21 #endif
22 
23 ////////////////////////////////////////////////////////////////////////////////
24 
25 #include <lmdb.h> /* for MDB_*, mdb_*() */
26 
27 #ifdef LMDBXX_DEBUG
28 #include <cassert> /* for assert() */
29 #endif
30 #include <cstddef> /* for std::size_t */
31 #include <cstdio> /* for std::snprintf() */
32 #include <cstring> /* for std::strlen() */
33 #include <stdexcept> /* for std::runtime_error */
34 #include <string> /* for std::string */
35 #include <type_traits> /* for std::is_pod<> */
36 
37 namespace lmdb {
38  using mode = mdb_mode_t;
39 }
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /* Error Handling */
43 
44 namespace lmdb {
45  class error;
46  class logic_error;
47  class fatal_error;
48  class runtime_error;
49  class key_exist_error;
50  class not_found_error;
51  class corrupted_error;
52  class panic_error;
53  class version_mismatch_error;
54  class map_full_error;
55  class bad_dbi_error;
56 }
57 
58 /**
59  * Base class for LMDB exception conditions.
60  *
61  * @see http://symas.com/mdb/doc/group__errors.html
62  */
63 class lmdb::error : public std::runtime_error {
64 protected:
65  const int _code;
66 
67 public:
68  /**
69  * Throws an error based on the given LMDB return code.
70  */
71  [[noreturn]] static inline void raise(const char* origin, int rc);
72 
73  /**
74  * Constructor.
75  */
76  error(const char* const origin,
77  const int rc) noexcept
79  _code{rc} {}
80 
81  /**
82  * Returns the underlying LMDB error code.
83  */
84  int code() const noexcept {
85  return _code;
86  }
87 
88  /**
89  * Returns the origin of the LMDB error.
90  */
91  const char* origin() const noexcept {
92  return runtime_error::what();
93  }
94 
95  /**
96  * Returns the underlying LMDB error code.
97  */
98  virtual const char* what() const noexcept {
99 #if !defined(__APPLE__)
100  static thread_local char buffer[1024];
101 #else
102  static char buffer[1024]; /* FIXME: need to provide locking */
103 #endif
104 #if defined(_MSC_VER)
105  snprintf(buffer, sizeof(buffer),
106  "%s: %s", origin(), ::mdb_strerror(code()));
107 #else
108  std::snprintf(buffer, sizeof(buffer),
109  "%s: %s", origin(), ::mdb_strerror(code()));
110 #endif
111  return buffer;
112  }
113 };
114 
115 /**
116  * Base class for logic error conditions.
117  */
119 public:
120  using error::error;
121 };
122 
123 /**
124  * Base class for fatal error conditions.
125  */
127 public:
128  using error::error;
129 };
130 
131 /**
132  * Base class for runtime error conditions.
133  */
135 public:
136  using error::error;
137 };
138 
139 /**
140  * Exception class for `MDB_KEYEXIST` errors.
141  *
142  * @see http://symas.com/mdb/doc/group__errors.html#ga05dc5bbcc7da81a7345bd8676e8e0e3b
143  */
145 public:
146  using runtime_error::runtime_error;
147 };
148 
149 /**
150  * Exception class for `MDB_NOTFOUND` errors.
151  *
152  * @see http://symas.com/mdb/doc/group__errors.html#gabeb52e4c4be21b329e31c4add1b71926
153  */
155 public:
156  using runtime_error::runtime_error;
157 };
158 
159 /**
160  * Exception class for `MDB_CORRUPTED` errors.
161  *
162  * @see http://symas.com/mdb/doc/group__errors.html#gaf8148bf1b85f58e264e57194bafb03ef
163  */
165 public:
167 };
168 
169 /**
170  * Exception class for `MDB_PANIC` errors.
171  *
172  * @see http://symas.com/mdb/doc/group__errors.html#gae37b9aedcb3767faba3de8c1cf6d3473
173  */
174 class lmdb::panic_error final : public lmdb::fatal_error {
175 public:
177 };
178 
179 /**
180  * Exception class for `MDB_VERSION_MISMATCH` errors.
181  *
182  * @see http://symas.com/mdb/doc/group__errors.html#ga909b2db047fa90fb0d37a78f86a6f99b
183  */
185 public:
187 };
188 
189 /**
190  * Exception class for `MDB_MAP_FULL` errors.
191  *
192  * @see http://symas.com/mdb/doc/group__errors.html#ga0a83370402a060c9175100d4bbfb9f25
193  */
195 public:
196  using runtime_error::runtime_error;
197 };
198 
199 /**
200  * Exception class for `MDB_BAD_DBI` errors.
201  *
202  * @since 0.9.14 (2014/09/20)
203  * @see http://symas.com/mdb/doc/group__errors.html#gab4c82e050391b60a18a5df08d22a7083
204  */
206 public:
207  using runtime_error::runtime_error;
208 };
209 
210 inline void
211 lmdb::error::raise(const char* const origin,
212  const int rc) {
213  switch (rc) {
214  case MDB_KEYEXIST: throw key_exist_error{origin, rc};
215  case MDB_NOTFOUND: throw not_found_error{origin, rc};
216  case MDB_CORRUPTED: throw corrupted_error{origin, rc};
217  case MDB_PANIC: throw panic_error{origin, rc};
219  case MDB_MAP_FULL: throw map_full_error{origin, rc};
220 #ifdef MDB_BAD_DBI
221  case MDB_BAD_DBI: throw bad_dbi_error{origin, rc};
222 #endif
223  default: throw lmdb::runtime_error{origin, rc};
224  }
225 }
226 
227 ////////////////////////////////////////////////////////////////////////////////
228 /* Procedural Interface: Metadata */
229 
230 namespace lmdb {
231  // TODO: mdb_version()
232  // TODO: mdb_strerror()
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /* Procedural Interface: Environment */
237 
238 namespace lmdb {
239  static inline void env_create(MDB_env** env);
240  static inline void env_open(MDB_env* env,
241  const char* path, unsigned int flags, mode mode);
242 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
243  static inline void env_copy(MDB_env* env, const char* path, unsigned int flags);
244  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd, unsigned int flags);
245 #else
246  static inline void env_copy(MDB_env* env, const char* path);
247  static inline void env_copy_fd(MDB_env* env, mdb_filehandle_t fd);
248 #endif
249  static inline void env_stat(MDB_env* env, MDB_stat* stat);
250  static inline void env_info(MDB_env* env, MDB_envinfo* stat);
251  static inline void env_sync(MDB_env* env, bool force);
252  static inline void env_close(MDB_env* env) noexcept;
253  static inline void env_set_flags(MDB_env* env, unsigned int flags, bool onoff);
254  static inline void env_get_flags(MDB_env* env, unsigned int* flags);
255  static inline void env_get_path(MDB_env* env, const char** path);
256  static inline void env_get_fd(MDB_env* env, mdb_filehandle_t* fd);
257  static inline void env_set_mapsize(MDB_env* env, std::size_t size);
258  static inline void env_set_max_readers(MDB_env* env, unsigned int count);
259  static inline void env_get_max_readers(MDB_env* env, unsigned int* count);
260  static inline void env_set_max_dbs(MDB_env* env, MDB_dbi count);
261  static inline unsigned int env_get_max_keysize(MDB_env* env);
262 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
263  static inline void env_set_userctx(MDB_env* env, void* ctx);
264  static inline void* env_get_userctx(MDB_env* env);
265 #endif
266  // TODO: mdb_env_set_assert()
267  // TODO: mdb_reader_list()
268  // TODO: mdb_reader_check()
269 }
270 
271 /**
272  * @throws lmdb::error on failure
273  * @see http://symas.com/mdb/doc/group__mdb.html#gaad6be3d8dcd4ea01f8df436f41d158d4
274  */
275 static inline void
277  const int rc = ::mdb_env_create(env);
278  if (rc != MDB_SUCCESS) {
279  error::raise("mdb_env_create", rc);
280  }
281 }
282 
283 /**
284  * @throws lmdb::error on failure
285  * @see http://symas.com/mdb/doc/group__mdb.html#ga32a193c6bf4d7d5c5d579e71f22e9340
286  */
287 static inline void
289  const char* const path,
290  const unsigned int flags,
291  const mode mode) {
292  const int rc = ::mdb_env_open(env, path, flags, mode);
293  if (rc != MDB_SUCCESS) {
294  error::raise("mdb_env_open", rc);
295  }
296 }
297 
298 /**
299  * @throws lmdb::error on failure
300  * @see http://symas.com/mdb/doc/group__mdb.html#ga3bf50d7793b36aaddf6b481a44e24244
301  * @see http://symas.com/mdb/doc/group__mdb.html#ga5d51d6130325f7353db0955dbedbc378
302  */
303 static inline void
305 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
306  const char* const path,
307  const unsigned int flags = 0) {
308  const int rc = ::mdb_env_copy2(env, path, flags);
309 #else
310  const char* const path) {
311  const int rc = ::mdb_env_copy(env, path);
312 #endif
313  if (rc != MDB_SUCCESS) {
314  error::raise("mdb_env_copy2", rc);
315  }
316 }
317 
318 /**
319  * @throws lmdb::error on failure
320  * @see http://symas.com/mdb/doc/group__mdb.html#ga5040d0de1f14000fa01fc0b522ff1f86
321  * @see http://symas.com/mdb/doc/group__mdb.html#ga470b0bcc64ac417de5de5930f20b1a28
322  */
323 static inline void
325 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 14)
326  const mdb_filehandle_t fd,
327  const unsigned int flags = 0) {
328  const int rc = ::mdb_env_copyfd2(env, fd, flags);
329 #else
330  const mdb_filehandle_t fd) {
331  const int rc = ::mdb_env_copyfd(env, fd);
332 #endif
333  if (rc != MDB_SUCCESS) {
334  error::raise("mdb_env_copyfd2", rc);
335  }
336 }
337 
338 /**
339  * @throws lmdb::error on failure
340  * @see http://symas.com/mdb/doc/group__mdb.html#gaf881dca452050efbd434cd16e4bae255
341  */
342 static inline void
344  MDB_stat* const stat) {
345  const int rc = ::mdb_env_stat(env, stat);
346  if (rc != MDB_SUCCESS) {
347  error::raise("mdb_env_stat", rc);
348  }
349 }
350 
351 /**
352  * @throws lmdb::error on failure
353  * @see http://symas.com/mdb/doc/group__mdb.html#ga18769362c7e7d6cf91889a028a5c5947
354  */
355 static inline void
357  MDB_envinfo* const stat) {
358  const int rc = ::mdb_env_info(env, stat);
359  if (rc != MDB_SUCCESS) {
360  error::raise("mdb_env_info", rc);
361  }
362 }
363 
364 /**
365  * @throws lmdb::error on failure
366  * @see http://symas.com/mdb/doc/group__mdb.html#ga85e61f05aa68b520cc6c3b981dba5037
367  */
368 static inline void
370  const bool force = true) {
371  const int rc = ::mdb_env_sync(env, force);
372  if (rc != MDB_SUCCESS) {
373  error::raise("mdb_env_sync", rc);
374  }
375 }
376 
377 /**
378  * @see http://symas.com/mdb/doc/group__mdb.html#ga4366c43ada8874588b6a62fbda2d1e95
379  */
380 static inline void
381 lmdb::env_close(MDB_env* const env) noexcept {
383 }
384 
385 /**
386  * @throws lmdb::error on failure
387  * @see http://symas.com/mdb/doc/group__mdb.html#ga83f66cf02bfd42119451e9468dc58445
388  */
389 static inline void
391  const unsigned int flags,
392  const bool onoff = true) {
393  const int rc = ::mdb_env_set_flags(env, flags, onoff ? 1 : 0);
394  if (rc != MDB_SUCCESS) {
395  error::raise("mdb_env_set_flags", rc);
396  }
397 }
398 
399 /**
400  * @throws lmdb::error on failure
401  * @see http://symas.com/mdb/doc/group__mdb.html#ga2733aefc6f50beb49dd0c6eb19b067d9
402  */
403 static inline void
405  unsigned int* const flags) {
406  const int rc = ::mdb_env_get_flags(env, flags);
407  if (rc != MDB_SUCCESS) {
408  error::raise("mdb_env_get_flags", rc);
409  }
410 }
411 
412 /**
413  * @throws lmdb::error on failure
414  * @see http://symas.com/mdb/doc/group__mdb.html#gac699fdd8c4f8013577cb933fb6a757fe
415  */
416 static inline void
418  const char** path) {
419  const int rc = ::mdb_env_get_path(env, path);
420  if (rc != MDB_SUCCESS) {
421  error::raise("mdb_env_get_path", rc);
422  }
423 }
424 
425 /**
426  * @throws lmdb::error on failure
427  * @see http://symas.com/mdb/doc/group__mdb.html#gaf1570e7c0e5a5d860fef1032cec7d5f2
428  */
429 static inline void
431  mdb_filehandle_t* const fd) {
432  const int rc = ::mdb_env_get_fd(env, fd);
433  if (rc != MDB_SUCCESS) {
434  error::raise("mdb_env_get_fd", rc);
435  }
436 }
437 
438 /**
439  * @throws lmdb::error on failure
440  * @see http://symas.com/mdb/doc/group__mdb.html#gaa2506ec8dab3d969b0e609cd82e619e5
441  */
442 static inline void
444  const std::size_t size) {
445  const int rc = ::mdb_env_set_mapsize(env, size);
446  if (rc != MDB_SUCCESS) {
447  error::raise("mdb_env_set_mapsize", rc);
448  }
449 }
450 
451 /**
452  * @throws lmdb::error on failure
453  * @see http://symas.com/mdb/doc/group__mdb.html#gae687966c24b790630be2a41573fe40e2
454  */
455 static inline void
457  const unsigned int count) {
458  const int rc = ::mdb_env_set_maxreaders(env, count);
459  if (rc != MDB_SUCCESS) {
460  error::raise("mdb_env_set_maxreaders", rc);
461  }
462 }
463 
464 /**
465  * @throws lmdb::error on failure
466  * @see http://symas.com/mdb/doc/group__mdb.html#ga70e143cf11760d869f754c9c9956e6cc
467  */
468 static inline void
470  unsigned int* const count) {
471  const int rc = ::mdb_env_get_maxreaders(env, count);
472  if (rc != MDB_SUCCESS) {
473  error::raise("mdb_env_get_maxreaders", rc);
474  }
475 }
476 
477 /**
478  * @throws lmdb::error on failure
479  * @see http://symas.com/mdb/doc/group__mdb.html#gaa2fc2f1f37cb1115e733b62cab2fcdbc
480  */
481 static inline void
483  const MDB_dbi count) {
484  const int rc = ::mdb_env_set_maxdbs(env, count);
485  if (rc != MDB_SUCCESS) {
486  error::raise("mdb_env_set_maxdbs", rc);
487  }
488 }
489 
490 /**
491  * @see http://symas.com/mdb/doc/group__mdb.html#gaaf0be004f33828bf2fb09d77eb3cef94
492  */
493 static inline unsigned int
495  const int rc = ::mdb_env_get_maxkeysize(env);
496 #ifdef LMDBXX_DEBUG
497  assert(rc >= 0);
498 #endif
499  return static_cast<unsigned int>(rc);
500 }
501 
502 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
503 /**
504  * @throws lmdb::error on failure
505  * @since 0.9.11 (2014/01/15)
506  * @see http://symas.com/mdb/doc/group__mdb.html#gaf2fe09eb9c96eeb915a76bf713eecc46
507  */
508 static inline void
510  void* const ctx) {
511  const int rc = ::mdb_env_set_userctx(env, ctx);
512  if (rc != MDB_SUCCESS) {
513  error::raise("mdb_env_set_userctx", rc);
514  }
515 }
516 #endif
517 
518 #if MDB_VERSION_FULL >= MDB_VERINT(0, 9, 11)
519 /**
520  * @since 0.9.11 (2014/01/15)
521  * @see http://symas.com/mdb/doc/group__mdb.html#ga45df6a4fb150cda2316b5ae224ba52f1
522  */
523 static inline void*
526 }
527 #endif
528 
529 ////////////////////////////////////////////////////////////////////////////////
530 /* Procedural Interface: Transactions */
531 
532 namespace lmdb {
533  static inline void txn_begin(
534  MDB_env* env, MDB_txn* parent, unsigned int flags, MDB_txn** txn);
535  static inline MDB_env* txn_env(MDB_txn* txn) noexcept;
536 #ifdef LMDBXX_TXN_ID
537  static inline std::size_t txn_id(MDB_txn* txn) noexcept;
538 #endif
539  static inline void txn_commit(MDB_txn* txn);
540  static inline void txn_abort(MDB_txn* txn) noexcept;
541  static inline void txn_reset(MDB_txn* txn) noexcept;
542  static inline void txn_renew(MDB_txn* txn);
543 }
544 
545 /**
546  * @throws lmdb::error on failure
547  * @see http://symas.com/mdb/doc/group__mdb.html#gad7ea55da06b77513609efebd44b26920
548  */
549 static inline void
551  MDB_txn* const parent,
552  const unsigned int flags,
553  MDB_txn** txn) {
554  const int rc = ::mdb_txn_begin(env, parent, flags, txn);
555  if (rc != MDB_SUCCESS) {
556  error::raise("mdb_txn_begin", rc);
557  }
558 }
559 
560 /**
561  * @see http://symas.com/mdb/doc/group__mdb.html#gaeb17735b8aaa2938a78a45cab85c06a0
562  */
563 static inline MDB_env*
564 lmdb::txn_env(MDB_txn* const txn) noexcept {
566 }
567 
568 #ifdef LMDBXX_TXN_ID
569 /**
570  * @note Only available in HEAD, not yet in any 0.9.x release (as of 0.9.16).
571  */
572 static inline std::size_t
573 lmdb::txn_id(MDB_txn* const txn) noexcept {
574  return ::mdb_txn_id(txn);
575 }
576 #endif
577 
578 /**
579  * @throws lmdb::error on failure
580  * @see http://symas.com/mdb/doc/group__mdb.html#ga846fbd6f46105617ac9f4d76476f6597
581  */
582 static inline void
584  const int rc = ::mdb_txn_commit(txn);
585  if (rc != MDB_SUCCESS) {
586  error::raise("mdb_txn_commit", rc);
587  }
588 }
589 
590 /**
591  * @see http://symas.com/mdb/doc/group__mdb.html#ga73a5938ae4c3239ee11efa07eb22b882
592  */
593 static inline void
594 lmdb::txn_abort(MDB_txn* const txn) noexcept {
596 }
597 
598 /**
599  * @see http://symas.com/mdb/doc/group__mdb.html#ga02b06706f8a66249769503c4e88c56cd
600  */
601 static inline void
602 lmdb::txn_reset(MDB_txn* const txn) noexcept {
604 }
605 
606 /**
607  * @throws lmdb::error on failure
608  * @see http://symas.com/mdb/doc/group__mdb.html#ga6c6f917959517ede1c504cf7c720ce6d
609  */
610 static inline void
612  const int rc = ::mdb_txn_renew(txn);
613  if (rc != MDB_SUCCESS) {
614  error::raise("mdb_txn_renew", rc);
615  }
616 }
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /* Procedural Interface: Databases */
620 
621 namespace lmdb {
622  static inline void dbi_open(
623  MDB_txn* txn, const char* name, unsigned int flags, MDB_dbi* dbi);
624  static inline void dbi_stat(MDB_txn* txn, MDB_dbi dbi, MDB_stat* stat);
625  static inline void dbi_flags(MDB_txn* txn, MDB_dbi dbi, unsigned int* flags);
626  static inline void dbi_close(MDB_env* env, MDB_dbi dbi) noexcept;
627  static inline void dbi_drop(MDB_txn* txn, MDB_dbi dbi, bool del);
628  static inline void dbi_set_compare(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
629  static inline void dbi_set_dupsort(MDB_txn* txn, MDB_dbi dbi, MDB_cmp_func* cmp);
630  static inline void dbi_set_relfunc(MDB_txn* txn, MDB_dbi dbi, MDB_rel_func* rel);
631  static inline void dbi_set_relctx(MDB_txn* txn, MDB_dbi dbi, void* ctx);
632  static inline bool dbi_get(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data);
633  static inline bool dbi_put(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, MDB_val* data, unsigned int flags);
634  static inline bool dbi_del(MDB_txn* txn, MDB_dbi dbi, const MDB_val* key, const MDB_val* data);
635  // TODO: mdb_cmp()
636  // TODO: mdb_dcmp()
637 }
638 
639 /**
640  * @throws lmdb::error on failure
641  * @see http://symas.com/mdb/doc/group__mdb.html#gac08cad5b096925642ca359a6d6f0562a
642  */
643 static inline void
645  const char* const name,
646  const unsigned int flags,
647  MDB_dbi* const dbi) {
648  const int rc = ::mdb_dbi_open(txn, name, flags, dbi);
649  if (rc != MDB_SUCCESS) {
650  error::raise("mdb_dbi_open", rc);
651  }
652 }
653 
654 /**
655  * @throws lmdb::error on failure
656  * @see http://symas.com/mdb/doc/group__mdb.html#gae6c1069febe94299769dbdd032fadef6
657  */
658 static inline void
660  const MDB_dbi dbi,
661  MDB_stat* const result) {
662  const int rc = ::mdb_stat(txn, dbi, result);
663  if (rc != MDB_SUCCESS) {
664  error::raise("mdb_stat", rc);
665  }
666 }
667 
668 /**
669  * @throws lmdb::error on failure
670  * @see http://symas.com/mdb/doc/group__mdb.html#ga95ba4cb721035478a8705e57b91ae4d4
671  */
672 static inline void
674  const MDB_dbi dbi,
675  unsigned int* const flags) {
676  const int rc = ::mdb_dbi_flags(txn, dbi, flags);
677  if (rc != MDB_SUCCESS) {
678  error::raise("mdb_dbi_flags", rc);
679  }
680 }
681 
682 /**
683  * @see http://symas.com/mdb/doc/group__mdb.html#ga52dd98d0c542378370cd6b712ff961b5
684  */
685 static inline void
687  const MDB_dbi dbi) noexcept {
689 }
690 
691 /**
692  * @see http://symas.com/mdb/doc/group__mdb.html#gab966fab3840fc54a6571dfb32b00f2db
693  */
694 static inline void
696  const MDB_dbi dbi,
697  const bool del = false) {
698  const int rc = ::mdb_drop(txn, dbi, del ? 1 : 0);
699  if (rc != MDB_SUCCESS) {
700  error::raise("mdb_drop", rc);
701  }
702 }
703 
704 /**
705  * @throws lmdb::error on failure
706  * @see http://symas.com/mdb/doc/group__mdb.html#ga68e47ffcf72eceec553c72b1784ee0fe
707  */
708 static inline void
710  const MDB_dbi dbi,
711  MDB_cmp_func* const cmp = nullptr) {
712  const int rc = ::mdb_set_compare(txn, dbi, cmp);
713  if (rc != MDB_SUCCESS) {
714  error::raise("mdb_set_compare", rc);
715  }
716 }
717 
718 /**
719  * @throws lmdb::error on failure
720  * @see http://symas.com/mdb/doc/group__mdb.html#gacef4ec3dab0bbd9bc978b73c19c879ae
721  */
722 static inline void
724  const MDB_dbi dbi,
725  MDB_cmp_func* const cmp = nullptr) {
726  const int rc = ::mdb_set_dupsort(txn, dbi, cmp);
727  if (rc != MDB_SUCCESS) {
728  error::raise("mdb_set_dupsort", rc);
729  }
730 }
731 
732 /**
733  * @throws lmdb::error on failure
734  * @see http://symas.com/mdb/doc/group__mdb.html#ga697d82c7afe79f142207ad5adcdebfeb
735  */
736 static inline void
738  const MDB_dbi dbi,
739  MDB_rel_func* const rel) {
740  const int rc = ::mdb_set_relfunc(txn, dbi, rel);
741  if (rc != MDB_SUCCESS) {
742  error::raise("mdb_set_relfunc", rc);
743  }
744 }
745 
746 /**
747  * @throws lmdb::error on failure
748  * @see http://symas.com/mdb/doc/group__mdb.html#ga7c34246308cee01724a1839a8f5cc594
749  */
750 static inline void
752  const MDB_dbi dbi,
753  void* const ctx) {
754  const int rc = ::mdb_set_relctx(txn, dbi, ctx);
755  if (rc != MDB_SUCCESS) {
756  error::raise("mdb_set_relctx", rc);
757  }
758 }
759 
760 /**
761  * @retval true if the key/value pair was retrieved
762  * @retval false if the key wasn't found
763  * @see http://symas.com/mdb/doc/group__mdb.html#ga8bf10cd91d3f3a83a34d04ce6b07992d
764  */
765 static inline bool
767  const MDB_dbi dbi,
768  const MDB_val* const key,
769  MDB_val* const data) {
770  const int rc = ::mdb_get(txn, dbi, const_cast<MDB_val*>(key), data);
771  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
772  error::raise("mdb_get", rc);
773  }
774  return (rc == MDB_SUCCESS);
775 }
776 
777 /**
778  * @retval true if the key/value pair was inserted
779  * @retval false if the key already existed
780  * @see http://symas.com/mdb/doc/group__mdb.html#ga4fa8573d9236d54687c61827ebf8cac0
781  */
782 static inline bool
784  const MDB_dbi dbi,
785  const MDB_val* const key,
786  MDB_val* const data,
787  const unsigned int flags = 0) {
788  const int rc = ::mdb_put(txn, dbi, const_cast<MDB_val*>(key), data, flags);
789  if (rc != MDB_SUCCESS && rc != MDB_KEYEXIST) {
790  error::raise("mdb_put", rc);
791  }
792  return (rc == MDB_SUCCESS);
793 }
794 
795 /**
796  * @retval true if the key/value pair was removed
797  * @retval false if the key wasn't found
798  * @see http://symas.com/mdb/doc/group__mdb.html#gab8182f9360ea69ac0afd4a4eaab1ddb0
799  */
800 static inline bool
802  const MDB_dbi dbi,
803  const MDB_val* const key,
804  const MDB_val* const data = nullptr) {
805  const int rc = ::mdb_del(txn, dbi, const_cast<MDB_val*>(key), const_cast<MDB_val*>(data));
806  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
807  error::raise("mdb_del", rc);
808  }
809  return (rc == MDB_SUCCESS);
810 }
811 
812 ////////////////////////////////////////////////////////////////////////////////
813 /* Procedural Interface: Cursors */
814 
815 namespace lmdb {
816  static inline void cursor_open(MDB_txn* txn, MDB_dbi dbi, MDB_cursor** cursor);
817  static inline void cursor_close(MDB_cursor* cursor) noexcept;
818  static inline void cursor_renew(MDB_txn* txn, MDB_cursor* cursor);
819  static inline MDB_txn* cursor_txn(MDB_cursor* cursor) noexcept;
820  static inline MDB_dbi cursor_dbi(MDB_cursor* cursor) noexcept;
821  static inline bool cursor_get(MDB_cursor* cursor, MDB_val* key, MDB_val* data, MDB_cursor_op op);
822  static inline void cursor_put(MDB_cursor* cursor, MDB_val* key, MDB_val* data, unsigned int flags);
823  static inline void cursor_del(MDB_cursor* cursor, unsigned int flags);
824  static inline void cursor_count(MDB_cursor* cursor, std::size_t& count);
825 }
826 
827 /**
828  * @throws lmdb::error on failure
829  * @see http://symas.com/mdb/doc/group__mdb.html#ga9ff5d7bd42557fd5ee235dc1d62613aa
830  */
831 static inline void
833  const MDB_dbi dbi,
834  MDB_cursor** const cursor) {
835  const int rc = ::mdb_cursor_open(txn, dbi, cursor);
836  if (rc != MDB_SUCCESS) {
837  error::raise("mdb_cursor_open", rc);
838  }
839 }
840 
841 /**
842  * @see http://symas.com/mdb/doc/group__mdb.html#gad685f5d73c052715c7bd859cc4c05188
843  */
844 static inline void
847 }
848 
849 /**
850  * @throws lmdb::error on failure
851  * @see http://symas.com/mdb/doc/group__mdb.html#gac8b57befb68793070c85ea813df481af
852  */
853 static inline void
855  MDB_cursor* const cursor) {
856  const int rc = ::mdb_cursor_renew(txn, cursor);
857  if (rc != MDB_SUCCESS) {
858  error::raise("mdb_cursor_renew", rc);
859  }
860 }
861 
862 /**
863  * @see http://symas.com/mdb/doc/group__mdb.html#ga7bf0d458f7f36b5232fcb368ebda79e0
864  */
865 static inline MDB_txn*
868 }
869 
870 /**
871  * @see http://symas.com/mdb/doc/group__mdb.html#ga2f7092cf70ee816fb3d2c3267a732372
872  */
873 static inline MDB_dbi
876 }
877 
878 /**
879  * @throws lmdb::error on failure
880  * @see http://symas.com/mdb/doc/group__mdb.html#ga48df35fb102536b32dfbb801a47b4cb0
881  */
882 static inline bool
884  MDB_val* const key,
885  MDB_val* const data,
886  const MDB_cursor_op op) {
887  const int rc = ::mdb_cursor_get(cursor, key, data, op);
888  if (rc != MDB_SUCCESS && rc != MDB_NOTFOUND) {
889  error::raise("mdb_cursor_get", rc);
890  }
891  return (rc == MDB_SUCCESS);
892 }
893 
894 /**
895  * @throws lmdb::error on failure
896  * @see http://symas.com/mdb/doc/group__mdb.html#ga1f83ccb40011837ff37cc32be01ad91e
897  */
898 static inline void
900  MDB_val* const key,
901  MDB_val* const data,
902  const unsigned int flags = 0) {
903  const int rc = ::mdb_cursor_put(cursor, key, data, flags);
904  if (rc != MDB_SUCCESS) {
905  error::raise("mdb_cursor_put", rc);
906  }
907 }
908 
909 /**
910  * @throws lmdb::error on failure
911  * @see http://symas.com/mdb/doc/group__mdb.html#ga26a52d3efcfd72e5bf6bd6960bf75f95
912  */
913 static inline void
915  const unsigned int flags = 0) {
916  const int rc = ::mdb_cursor_del(cursor, flags);
917  if (rc != MDB_SUCCESS) {
918  error::raise("mdb_cursor_del", rc);
919  }
920 }
921 
922 /**
923  * @throws lmdb::error on failure
924  * @see http://symas.com/mdb/doc/group__mdb.html#ga4041fd1e1862c6b7d5f10590b86ffbe2
925  */
926 static inline void
928  std::size_t& count) {
929  const int rc = ::mdb_cursor_count(cursor, &count);
930  if (rc != MDB_SUCCESS) {
931  error::raise("mdb_cursor_count", rc);
932  }
933 }
934 
935 ////////////////////////////////////////////////////////////////////////////////
936 /* Resource Interface: Values */
937 
938 namespace lmdb {
939  class val;
940 }
941 
942 /**
943  * Wrapper class for `MDB_val` structures.
944  *
945  * @note Instances of this class are movable and copyable both.
946  * @see http://symas.com/mdb/doc/group__mdb.html#structMDB__val
947  */
948 class lmdb::val {
949 protected:
951 
952 public:
953  /**
954  * Default constructor.
955  */
956  val() noexcept = default;
957 
958  /**
959  * Constructor.
960  */
961  val(const std::string& data) noexcept
962  : val{data.data(), data.size()} {}
963 
964  /**
965  * Constructor.
966  */
967  val(const char* const data) noexcept
968  : val{data, std::strlen(data)} {}
969 
970  /**
971  * Constructor.
972  */
973  val(const void* const data,
974  const std::size_t size) noexcept
975  : _val{size, const_cast<void*>(data)} {}
976 
977  /**
978  * Move constructor.
979  */
980  val(val&& other) noexcept = default;
981 
982  /**
983  * Move assignment operator.
984  */
985  val& operator=(val&& other) noexcept = default;
986 
987  /**
988  * Destructor.
989  */
990  ~val() noexcept = default;
991 
992  /**
993  * Returns an `MDB_val*` pointer.
994  */
995  operator MDB_val*() noexcept {
996  return &_val;
997  }
998 
999  /**
1000  * Returns an `MDB_val*` pointer.
1001  */
1002  operator const MDB_val*() const noexcept {
1003  return &_val;
1004  }
1005 
1006  /**
1007  * Determines whether this value is empty.
1008  */
1009  bool empty() const noexcept {
1010  return size() == 0;
1011  }
1012 
1013  /**
1014  * Returns the size of the data.
1015  */
1016  std::size_t size() const noexcept {
1017  return _val.mv_size;
1018  }
1019 
1020  /**
1021  * Returns a pointer to the data.
1022  */
1023  template<typename T>
1024  T* data() noexcept {
1025  return reinterpret_cast<T*>(_val.mv_data);
1026  }
1027 
1028  /**
1029  * Returns a pointer to the data.
1030  */
1031  template<typename T>
1032  const T* data() const noexcept {
1033  return reinterpret_cast<T*>(_val.mv_data);
1034  }
1035 
1036  /**
1037  * Returns a pointer to the data.
1038  */
1039  char* data() noexcept {
1040  return reinterpret_cast<char*>(_val.mv_data);
1041  }
1042 
1043  /**
1044  * Returns a pointer to the data.
1045  */
1046  const char* data() const noexcept {
1047  return reinterpret_cast<char*>(_val.mv_data);
1048  }
1049 
1050  /**
1051  * Assigns the value.
1052  */
1053  template<typename T>
1054  val& assign(const T* const data,
1055  const std::size_t size) noexcept {
1056  _val.mv_size = size;
1057  _val.mv_data = const_cast<void*>(reinterpret_cast<const void*>(data));
1058  return *this;
1059  }
1060 
1061  /**
1062  * Assigns the value.
1063  */
1064  val& assign(const char* const data) noexcept {
1065  return assign(data, std::strlen(data));
1066  }
1067 
1068  /**
1069  * Assigns the value.
1070  */
1071  val& assign(const std::string& data) noexcept {
1072  return assign(data.data(), data.size());
1073  }
1074 };
1075 
1076 #if !(defined(__COVERITY__) || defined(_MSC_VER))
1077 static_assert(std::is_pod<lmdb::val>::value, "lmdb::val must be a POD type");
1078 static_assert(sizeof(lmdb::val) == sizeof(MDB_val), "sizeof(lmdb::val) != sizeof(MDB_val)");
1079 #endif
1080 
1081 ////////////////////////////////////////////////////////////////////////////////
1082 /* Resource Interface: Environment */
1083 
1084 namespace lmdb {
1085  class env;
1086 }
1087 
1088 /**
1089  * Resource class for `MDB_env*` handles.
1090  *
1091  * @note Instances of this class are movable, but not copyable.
1092  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__env
1093  */
1094 class lmdb::env {
1095 protected:
1096  MDB_env* _handle{nullptr};
1097 
1098 public:
1099  static constexpr unsigned int default_flags = 0;
1100  static constexpr mode default_mode = 0644; /* -rw-r--r-- */
1101 
1102  /**
1103  * Creates a new LMDB environment.
1104  *
1105  * @param flags
1106  * @throws lmdb::error on failure
1107  */
1108  static env create(const unsigned int flags = default_flags) {
1109  MDB_env* handle{nullptr};
1111 #ifdef LMDBXX_DEBUG
1112  assert(handle != nullptr);
1113 #endif
1114  if (flags) {
1115  try {
1117  }
1118  catch (const lmdb::error&) {
1120  throw;
1121  }
1122  }
1123  return env{handle};
1124  }
1125 
1126  /**
1127  * Constructor.
1128  *
1129  * @param handle a valid `MDB_env*` handle
1130  */
1131  env(MDB_env* const handle) noexcept
1132  : _handle{handle} {}
1133 
1134  /**
1135  * Move constructor.
1136  */
1137  env(env&& other) noexcept {
1138  std::swap(_handle, other._handle);
1139  }
1140 
1141  /**
1142  * Move assignment operator.
1143  */
1144  env& operator=(env&& other) noexcept {
1145  if (this != &other) {
1146  std::swap(_handle, other._handle);
1147  }
1148  return *this;
1149  }
1150 
1151  /**
1152  * Destructor.
1153  */
1154  ~env() noexcept {
1155  try { close(); } catch (...) {}
1156  }
1157 
1158  /**
1159  * Returns the underlying `MDB_env*` handle.
1160  */
1161  operator MDB_env*() const noexcept {
1162  return _handle;
1163  }
1164 
1165  /**
1166  * Returns the underlying `MDB_env*` handle.
1167  */
1168  MDB_env* handle() const noexcept {
1169  return _handle;
1170  }
1171 
1172  /**
1173  * Flushes data buffers to disk.
1174  *
1175  * @param force
1176  * @throws lmdb::error on failure
1177  */
1178  void sync(const bool force = true) {
1179  lmdb::env_sync(handle(), force);
1180  }
1181 
1182  /**
1183  * Closes this environment, releasing the memory map.
1184  *
1185  * @note this method is idempotent
1186  * @post `handle() == nullptr`
1187  */
1188  void close() noexcept {
1189  if (handle()) {
1191  _handle = nullptr;
1192  }
1193  }
1194 
1195  /**
1196  * Opens this environment.
1197  *
1198  * @param path
1199  * @param flags
1200  * @param mode
1201  * @throws lmdb::error on failure
1202  */
1203  env& open(const char* const path,
1204  const unsigned int flags = default_flags,
1205  const mode mode = default_mode) {
1206  lmdb::env_open(handle(), path, flags, mode);
1207  return *this;
1208  }
1209 
1210  /**
1211  * @param flags
1212  * @param onoff
1213  * @throws lmdb::error on failure
1214  */
1215  env& set_flags(const unsigned int flags,
1216  const bool onoff = true) {
1217  lmdb::env_set_flags(handle(), flags, onoff);
1218  return *this;
1219  }
1220 
1221  /**
1222  * @param size
1223  * @throws lmdb::error on failure
1224  */
1225  env& set_mapsize(const std::size_t size) {
1227  return *this;
1228  }
1229 
1230  /**
1231  * @param count
1232  * @throws lmdb::error on failure
1233  */
1234  env& set_max_readers(const unsigned int count) {
1236  return *this;
1237  }
1238 
1239  /**
1240  * @param count
1241  * @throws lmdb::error on failure
1242  */
1245  return *this;
1246  }
1247 };
1248 
1249 ////////////////////////////////////////////////////////////////////////////////
1250 /* Resource Interface: Transactions */
1251 
1252 namespace lmdb {
1253  class txn;
1254 }
1255 
1256 /**
1257  * Resource class for `MDB_txn*` handles.
1258  *
1259  * @note Instances of this class are movable, but not copyable.
1260  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__txn
1261  */
1262 class lmdb::txn {
1263 protected:
1264  MDB_txn* _handle{nullptr};
1265 
1266 public:
1267  static constexpr unsigned int default_flags = 0;
1268 
1269  /**
1270  * Creates a new LMDB transaction.
1271  *
1272  * @param env the environment handle
1273  * @param parent
1274  * @param flags
1275  * @throws lmdb::error on failure
1276  */
1277  static txn begin(MDB_env* const env,
1278  MDB_txn* const parent = nullptr,
1279  const unsigned int flags = default_flags) {
1280  MDB_txn* handle{nullptr};
1281  lmdb::txn_begin(env, parent, flags, &handle);
1282 #ifdef LMDBXX_DEBUG
1283  assert(handle != nullptr);
1284 #endif
1285  return txn{handle};
1286  }
1287 
1288  /**
1289  * Constructor.
1290  *
1291  * @param handle a valid `MDB_txn*` handle
1292  */
1293  txn(MDB_txn* const handle) noexcept
1294  : _handle{handle} {}
1295 
1296  /**
1297  * Move constructor.
1298  */
1299  txn(txn&& other) noexcept {
1300  std::swap(_handle, other._handle);
1301  }
1302 
1303  /**
1304  * Move assignment operator.
1305  */
1306  txn& operator=(txn&& other) noexcept {
1307  if (this != &other) {
1308  std::swap(_handle, other._handle);
1309  }
1310  return *this;
1311  }
1312 
1313  /**
1314  * Destructor.
1315  */
1316  ~txn() noexcept {
1317  if (_handle) {
1318  try { abort(); } catch (...) {}
1319  _handle = nullptr;
1320  }
1321  }
1322 
1323  /**
1324  * Returns the underlying `MDB_txn*` handle.
1325  */
1326  operator MDB_txn*() const noexcept {
1327  return _handle;
1328  }
1329 
1330  /**
1331  * Returns the underlying `MDB_txn*` handle.
1332  */
1333  MDB_txn* handle() const noexcept {
1334  return _handle;
1335  }
1336 
1337  /**
1338  * Returns the transaction's `MDB_env*` handle.
1339  */
1340  MDB_env* env() const noexcept {
1341  return lmdb::txn_env(handle());
1342  }
1343 
1344  /**
1345  * Commits this transaction.
1346  *
1347  * @throws lmdb::error on failure
1348  * @post `handle() == nullptr`
1349  */
1350  void commit() {
1352  _handle = nullptr;
1353  }
1354 
1355  /**
1356  * Aborts this transaction.
1357  *
1358  * @post `handle() == nullptr`
1359  */
1360  void abort() noexcept {
1362  _handle = nullptr;
1363  }
1364 
1365  /**
1366  * Resets this read-only transaction.
1367  */
1368  void reset() noexcept {
1370  }
1371 
1372  /**
1373  * Renews this read-only transaction.
1374  *
1375  * @throws lmdb::error on failure
1376  */
1377  void renew() {
1379  }
1380 };
1381 
1382 ////////////////////////////////////////////////////////////////////////////////
1383 /* Resource Interface: Databases */
1384 
1385 namespace lmdb {
1386  class dbi;
1387 }
1388 
1389 /**
1390  * Resource class for `MDB_dbi` handles.
1391  *
1392  * @note Instances of this class are movable, but not copyable.
1393  * @see http://symas.com/mdb/doc/group__mdb.html#gadbe68a06c448dfb62da16443d251a78b
1394  */
1395 class lmdb::dbi {
1396 protected:
1398 
1399 public:
1400  static constexpr unsigned int default_flags = 0;
1401  static constexpr unsigned int default_put_flags = 0;
1402 
1403  /**
1404  * Opens a database handle.
1405  *
1406  * @param txn the transaction handle
1407  * @param name
1408  * @param flags
1409  * @throws lmdb::error on failure
1410  */
1411  static dbi
1412  open(MDB_txn* const txn,
1413  const char* const name = nullptr,
1414  const unsigned int flags = default_flags) {
1415  MDB_dbi handle{};
1416  lmdb::dbi_open(txn, name, flags, &handle);
1417  return dbi{handle};
1418  }
1419 
1420  /**
1421  * Constructor.
1422  *
1423  * @param handle a valid `MDB_dbi` handle
1424  */
1425  dbi(const MDB_dbi handle) noexcept
1426  : _handle{handle} {}
1427 
1428  /**
1429  * Move constructor.
1430  */
1431  dbi(dbi&& other) noexcept {
1432  std::swap(_handle, other._handle);
1433  }
1434 
1435  /**
1436  * Move assignment operator.
1437  */
1438  dbi& operator=(dbi&& other) noexcept {
1439  if (this != &other) {
1440  std::swap(_handle, other._handle);
1441  }
1442  return *this;
1443  }
1444 
1445  /**
1446  * Destructor.
1447  */
1448  ~dbi() noexcept {
1449  if (_handle) {
1450  /* No need to call close() here. */
1451  }
1452  }
1453 
1454  /**
1455  * Returns the underlying `MDB_dbi` handle.
1456  */
1457  operator MDB_dbi() const noexcept {
1458  return _handle;
1459  }
1460 
1461  /**
1462  * Returns the underlying `MDB_dbi` handle.
1463  */
1464  MDB_dbi handle() const noexcept {
1465  return _handle;
1466  }
1467 
1468  /**
1469  * Returns statistics for this database.
1470  *
1471  * @param txn a transaction handle
1472  * @throws lmdb::error on failure
1473  */
1474  MDB_stat stat(MDB_txn* const txn) const {
1475  MDB_stat result;
1477  return result;
1478  }
1479 
1480  /**
1481  * Retrieves the flags for this database handle.
1482  *
1483  * @param txn a transaction handle
1484  * @throws lmdb::error on failure
1485  */
1486  unsigned int flags(MDB_txn* const txn) const {
1487  unsigned int result{};
1489  return result;
1490  }
1491 
1492  /**
1493  * Returns the number of records in this database.
1494  *
1495  * @param txn a transaction handle
1496  * @throws lmdb::error on failure
1497  */
1498  std::size_t size(MDB_txn* const txn) const {
1499  return stat(txn).ms_entries;
1500  }
1501 
1502  /**
1503  * @param txn a transaction handle
1504  * @param del
1505  * @throws lmdb::error on failure
1506  */
1507  void drop(MDB_txn* const txn,
1508  const bool del = false) {
1510  }
1511 
1512  /**
1513  * Sets a custom key comparison function for this database.
1514  *
1515  * @param txn a transaction handle
1516  * @param cmp the comparison function
1517  * @throws lmdb::error on failure
1518  */
1520  MDB_cmp_func* const cmp = nullptr) {
1522  return *this;
1523  }
1524 
1525  /**
1526  * Retrieves a key/value pair from this database.
1527  *
1528  * @param txn a transaction handle
1529  * @param key
1530  * @param data
1531  * @throws lmdb::error on failure
1532  */
1533  bool get(MDB_txn* const txn,
1534  const val& key,
1535  val& data) {
1536  return lmdb::dbi_get(txn, handle(), key, data);
1537  }
1538 
1539  /**
1540  * Retrieves a key from this database.
1541  *
1542  * @param txn a transaction handle
1543  * @param key
1544  * @throws lmdb::error on failure
1545  */
1546  template<typename K>
1547  bool get(MDB_txn* const txn,
1548  const K& key) const {
1549  const lmdb::val k{&key, sizeof(K)};
1550  lmdb::val v{};
1551  return lmdb::dbi_get(txn, handle(), k, v);
1552  }
1553 
1554  /**
1555  * Retrieves a key/value pair from this database.
1556  *
1557  * @param txn a transaction handle
1558  * @param key
1559  * @param val
1560  * @throws lmdb::error on failure
1561  */
1562  template<typename K, typename V>
1563  bool get(MDB_txn* const txn,
1564  const K& key,
1565  V& val) const {
1566  const lmdb::val k{&key, sizeof(K)};
1567  lmdb::val v{};
1568  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1569  if (result) {
1570  val = *v.data<const V>();
1571  }
1572  return result;
1573  }
1574 
1575  /**
1576  * Retrieves a key/value pair from this database.
1577  *
1578  * @param txn a transaction handle
1579  * @param key a NUL-terminated string key
1580  * @param val
1581  * @throws lmdb::error on failure
1582  */
1583  template<typename V>
1584  bool get(MDB_txn* const txn,
1585  const char* const key,
1586  V& val) const {
1587  const lmdb::val k{key, std::strlen(key)};
1588  lmdb::val v{};
1589  const bool result = lmdb::dbi_get(txn, handle(), k, v);
1590  if (result) {
1591  val = *v.data<const V>();
1592  }
1593  return result;
1594  }
1595 
1596  /**
1597  * Stores a key/value pair into this database.
1598  *
1599  * @param txn a transaction handle
1600  * @param key
1601  * @param data
1602  * @param flags
1603  * @throws lmdb::error on failure
1604  */
1605  bool put(MDB_txn* const txn,
1606  const val& key,
1607  val& data,
1608  const unsigned int flags = default_put_flags) {
1609  return lmdb::dbi_put(txn, handle(), key, data, flags);
1610  }
1611 
1612  /**
1613  * Stores a key into this database.
1614  *
1615  * @param txn a transaction handle
1616  * @param key
1617  * @param flags
1618  * @throws lmdb::error on failure
1619  */
1620  template<typename K>
1621  bool put(MDB_txn* const txn,
1622  const K& key,
1623  const unsigned int flags = default_put_flags) {
1624  const lmdb::val k{&key, sizeof(K)};
1625  lmdb::val v{};
1626  return lmdb::dbi_put(txn, handle(), k, v, flags);
1627  }
1628 
1629  /**
1630  * Stores a key/value pair into this database.
1631  *
1632  * @param txn a transaction handle
1633  * @param key
1634  * @param val
1635  * @param flags
1636  * @throws lmdb::error on failure
1637  */
1638  template<typename K, typename V>
1639  bool put(MDB_txn* const txn,
1640  const K& key,
1641  const V& val,
1642  const unsigned int flags = default_put_flags) {
1643  const lmdb::val k{&key, sizeof(K)};
1644  lmdb::val v{&val, sizeof(V)};
1645  return lmdb::dbi_put(txn, handle(), k, v, flags);
1646  }
1647 
1648  /**
1649  * Stores a key/value pair into this database.
1650  *
1651  * @param txn a transaction handle
1652  * @param key a NUL-terminated string key
1653  * @param val
1654  * @param flags
1655  * @throws lmdb::error on failure
1656  */
1657  template<typename V>
1658  bool put(MDB_txn* const txn,
1659  const char* const key,
1660  const V& val,
1661  const unsigned int flags = default_put_flags) {
1662  const lmdb::val k{key, std::strlen(key)};
1663  lmdb::val v{&val, sizeof(V)};
1664  return lmdb::dbi_put(txn, handle(), k, v, flags);
1665  }
1666 
1667  /**
1668  * Stores a key/value pair into this database.
1669  *
1670  * @param txn a transaction handle
1671  * @param key a NUL-terminated string key
1672  * @param val a NUL-terminated string key
1673  * @param flags
1674  * @throws lmdb::error on failure
1675  */
1676  bool put(MDB_txn* const txn,
1677  const char* const key,
1678  const char* const val,
1679  const unsigned int flags = default_put_flags) {
1680  const lmdb::val k{key, std::strlen(key)};
1681  lmdb::val v{val, std::strlen(val)};
1682  return lmdb::dbi_put(txn, handle(), k, v, flags);
1683  }
1684 
1685  /**
1686  * Removes a key/value pair from this database.
1687  *
1688  * @param txn a transaction handle
1689  * @param key
1690  * @throws lmdb::error on failure
1691  */
1692  bool del(MDB_txn* const txn,
1693  const val& key) {
1694  return lmdb::dbi_del(txn, handle(), key);
1695  }
1696 
1697  /**
1698  * Removes a key/value pair from this database.
1699  *
1700  * @param txn a transaction handle
1701  * @param key
1702  * @throws lmdb::error on failure
1703  */
1704  template<typename K>
1705  bool del(MDB_txn* const txn,
1706  const K& key) {
1707  const lmdb::val k{&key, sizeof(K)};
1708  return lmdb::dbi_del(txn, handle(), k);
1709  }
1710 };
1711 
1712 ////////////////////////////////////////////////////////////////////////////////
1713 /* Resource Interface: Cursors */
1714 
1715 namespace lmdb {
1716  class cursor;
1717 }
1718 
1719 /**
1720  * Resource class for `MDB_cursor*` handles.
1721  *
1722  * @note Instances of this class are movable, but not copyable.
1723  * @see http://symas.com/mdb/doc/group__internal.html#structMDB__cursor
1724  */
1726 protected:
1727  MDB_cursor* _handle{nullptr};
1728 
1729 public:
1730  static constexpr unsigned int default_flags = 0;
1731 
1732  /**
1733  * Creates an LMDB cursor.
1734  *
1735  * @param txn the transaction handle
1736  * @param dbi the database handle
1737  * @throws lmdb::error on failure
1738  */
1739  static cursor
1740  open(MDB_txn* const txn,
1741  const MDB_dbi dbi) {
1742  MDB_cursor* handle{};
1744 #ifdef LMDBXX_DEBUG
1745  assert(handle != nullptr);
1746 #endif
1747  return cursor{handle};
1748  }
1749 
1750  /**
1751  * Constructor.
1752  *
1753  * @param handle a valid `MDB_cursor*` handle
1754  */
1755  cursor(MDB_cursor* const handle) noexcept
1756  : _handle{handle} {}
1757 
1758  /**
1759  * Move constructor.
1760  */
1761  cursor(cursor&& other) noexcept {
1762  std::swap(_handle, other._handle);
1763  }
1764 
1765  /**
1766  * Move assignment operator.
1767  */
1768  cursor& operator=(cursor&& other) noexcept {
1769  if (this != &other) {
1770  std::swap(_handle, other._handle);
1771  }
1772  return *this;
1773  }
1774 
1775  /**
1776  * Destructor.
1777  */
1778  ~cursor() noexcept {
1779  try { close(); } catch (...) {}
1780  }
1781 
1782  /**
1783  * Returns the underlying `MDB_cursor*` handle.
1784  */
1785  operator MDB_cursor*() const noexcept {
1786  return _handle;
1787  }
1788 
1789  /**
1790  * Returns the underlying `MDB_cursor*` handle.
1791  */
1792  MDB_cursor* handle() const noexcept {
1793  return _handle;
1794  }
1795 
1796  /**
1797  * Closes this cursor.
1798  *
1799  * @note this method is idempotent
1800  * @post `handle() == nullptr`
1801  */
1802  void close() noexcept {
1803  if (_handle) {
1805  _handle = nullptr;
1806  }
1807  }
1808 
1809  /**
1810  * Renews this cursor.
1811  *
1812  * @param txn the transaction scope
1813  * @throws lmdb::error on failure
1814  */
1815  void renew(MDB_txn* const txn) {
1817  }
1818 
1819  /**
1820  * Returns the cursor's transaction handle.
1821  */
1822  MDB_txn* txn() const noexcept {
1823  return lmdb::cursor_txn(handle());
1824  }
1825 
1826  /**
1827  * Returns the cursor's database handle.
1828  */
1829  MDB_dbi dbi() const noexcept {
1830  return lmdb::cursor_dbi(handle());
1831  }
1832 
1833  /**
1834  * Retrieves a key from the database.
1835  *
1836  * @param key
1837  * @param op
1838  * @throws lmdb::error on failure
1839  */
1840  bool get(MDB_val* const key,
1841  const MDB_cursor_op op) {
1842  return get(key, nullptr, op);
1843  }
1844 
1845  /**
1846  * Retrieves a key from the database.
1847  *
1848  * @param key
1849  * @param op
1850  * @throws lmdb::error on failure
1851  */
1853  const MDB_cursor_op op) {
1854  return get(key, nullptr, op);
1855  }
1856 
1857  /**
1858  * Retrieves a key/value pair from the database.
1859  *
1860  * @param key
1861  * @param val (may be `nullptr`)
1862  * @param op
1863  * @throws lmdb::error on failure
1864  */
1865  bool get(MDB_val* const key,
1866  MDB_val* const val,
1867  const MDB_cursor_op op) {
1868  return lmdb::cursor_get(handle(), key, val, op);
1869  }
1870 
1871  /**
1872  * Retrieves a key/value pair from the database.
1873  *
1874  * @param key
1875  * @param val
1876  * @param op
1877  * @throws lmdb::error on failure
1878  */
1880  lmdb::val& val,
1881  const MDB_cursor_op op) {
1882  return lmdb::cursor_get(handle(), key, val, op);
1883  }
1884 
1885  /**
1886  * Retrieves a key/value pair from the database.
1887  *
1888  * @param key
1889  * @param val
1890  * @param op
1891  * @throws lmdb::error on failure
1892  */
1894  std::string& val,
1895  const MDB_cursor_op op) {
1896  lmdb::val k{}, v{};
1897  const bool found = get(k, v, op);
1898  if (found) {
1899  key.assign(k.data(), k.size());
1900  val.assign(v.data(), v.size());
1901  }
1902  return found;
1903  }
1904 
1905  /**
1906  * Positions this cursor at the given key.
1907  *
1908  * @param key
1909  * @param op
1910  * @throws lmdb::error on failure
1911  */
1912  template<typename K>
1913  bool find(const K& key,
1914  const MDB_cursor_op op = MDB_SET) {
1915  lmdb::val k{&key, sizeof(K)};
1916  return get(k, nullptr, op);
1917  }
1918 };
1919 
1920 ////////////////////////////////////////////////////////////////////////////////
1921 
1922 #endif /* LMDBXX_H */
Exception class for `MDB_BAD_DBI` errors.
Definition: lmdb++.h:205
Exception class for `MDB_CORRUPTED` errors.
Definition: lmdb++.h:164
Resource class for `MDB_cursor*` handles.
Definition: lmdb++.h:1725
bool get(lmdb::val &key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1852
MDB_cursor * handle() const noexcept
Returns the underlying `MDB_cursor*` handle.
Definition: lmdb++.h:1792
MDB_txn * txn() const noexcept
Returns the cursor's transaction handle.
Definition: lmdb++.h:1822
bool get(lmdb::val &key, lmdb::val &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1879
void close() noexcept
Closes this cursor.
Definition: lmdb++.h:1802
~cursor() noexcept
Destructor.
Definition: lmdb++.h:1778
bool get(MDB_val *const key, const MDB_cursor_op op)
Retrieves a key from the database.
Definition: lmdb++.h:1840
bool find(const K &key, const MDB_cursor_op op=MDB_SET)
Positions this cursor at the given key.
Definition: lmdb++.h:1913
bool get(std::string &key, std::string &val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1893
cursor(cursor &&other) noexcept
Move constructor.
Definition: lmdb++.h:1761
MDB_dbi dbi() const noexcept
Returns the cursor's database handle.
Definition: lmdb++.h:1829
static cursor open(MDB_txn *const txn, const MDB_dbi dbi)
Creates an LMDB cursor.
Definition: lmdb++.h:1740
MDB_cursor * _handle
Definition: lmdb++.h:1727
cursor(MDB_cursor *const handle) noexcept
Constructor.
Definition: lmdb++.h:1755
bool get(MDB_val *const key, MDB_val *const val, const MDB_cursor_op op)
Retrieves a key/value pair from the database.
Definition: lmdb++.h:1865
cursor & operator=(cursor &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1768
static constexpr unsigned int default_flags
Definition: lmdb++.h:1730
void renew(MDB_txn *const txn)
Renews this cursor.
Definition: lmdb++.h:1815
Resource class for `MDB_dbi` handles.
Definition: lmdb++.h:1395
std::size_t size(MDB_txn *const txn) const
Returns the number of records in this database.
Definition: lmdb++.h:1498
bool put(MDB_txn *const txn, const K &key, const V &val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1639
bool put(MDB_txn *const txn, const val &key, val &data, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1605
dbi(const MDB_dbi handle) noexcept
Constructor.
Definition: lmdb++.h:1425
bool del(MDB_txn *const txn, const val &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1692
dbi & operator=(dbi &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1438
~dbi() noexcept
Destructor.
Definition: lmdb++.h:1448
bool get(MDB_txn *const txn, const val &key, val &data)
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1533
MDB_stat stat(MDB_txn *const txn) const
Returns statistics for this database.
Definition: lmdb++.h:1474
bool put(MDB_txn *const txn, const char *const key, const V &val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1658
unsigned int flags(MDB_txn *const txn) const
Retrieves the flags for this database handle.
Definition: lmdb++.h:1486
bool del(MDB_txn *const txn, const K &key)
Removes a key/value pair from this database.
Definition: lmdb++.h:1705
static dbi open(MDB_txn *const txn, const char *const name=nullptr, const unsigned int flags=default_flags)
Opens a database handle.
Definition: lmdb++.h:1412
dbi & set_compare(MDB_txn *const txn, MDB_cmp_func *const cmp=nullptr)
Sets a custom key comparison function for this database.
Definition: lmdb++.h:1519
static constexpr unsigned int default_flags
Definition: lmdb++.h:1400
static constexpr unsigned int default_put_flags
Definition: lmdb++.h:1401
bool get(MDB_txn *const txn, const K &key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1563
void drop(MDB_txn *const txn, const bool del=false)
Definition: lmdb++.h:1507
bool put(MDB_txn *const txn, const char *const key, const char *const val, const unsigned int flags=default_put_flags)
Stores a key/value pair into this database.
Definition: lmdb++.h:1676
bool get(MDB_txn *const txn, const char *const key, V &val) const
Retrieves a key/value pair from this database.
Definition: lmdb++.h:1584
dbi(dbi &&other) noexcept
Move constructor.
Definition: lmdb++.h:1431
MDB_dbi _handle
Definition: lmdb++.h:1397
bool get(MDB_txn *const txn, const K &key) const
Retrieves a key from this database.
Definition: lmdb++.h:1547
MDB_dbi handle() const noexcept
Returns the underlying `MDB_dbi` handle.
Definition: lmdb++.h:1464
bool put(MDB_txn *const txn, const K &key, const unsigned int flags=default_put_flags)
Stores a key into this database.
Definition: lmdb++.h:1621
Resource class for `MDB_env*` handles.
Definition: lmdb++.h:1094
MDB_env * _handle
Definition: lmdb++.h:1096
void close() noexcept
Closes this environment, releasing the memory map.
Definition: lmdb++.h:1188
env & set_flags(const unsigned int flags, const bool onoff=true)
Definition: lmdb++.h:1215
~env() noexcept
Destructor.
Definition: lmdb++.h:1154
MDB_env * handle() const noexcept
Returns the underlying `MDB_env*` handle.
Definition: lmdb++.h:1168
env(MDB_env *const handle) noexcept
Constructor.
Definition: lmdb++.h:1131
static constexpr mode default_mode
Definition: lmdb++.h:1100
env(env &&other) noexcept
Move constructor.
Definition: lmdb++.h:1137
env & operator=(env &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1144
env & open(const char *const path, const unsigned int flags=default_flags, const mode mode=default_mode)
Opens this environment.
Definition: lmdb++.h:1203
void sync(const bool force=true)
Flushes data buffers to disk.
Definition: lmdb++.h:1178
static env create(const unsigned int flags=default_flags)
Creates a new LMDB environment.
Definition: lmdb++.h:1108
static constexpr unsigned int default_flags
Definition: lmdb++.h:1099
env & set_max_readers(const unsigned int count)
Definition: lmdb++.h:1234
env & set_max_dbs(const MDB_dbi count)
Definition: lmdb++.h:1243
env & set_mapsize(const std::size_t size)
Definition: lmdb++.h:1225
Base class for LMDB exception conditions.
Definition: lmdb++.h:63
const int _code
Definition: lmdb++.h:65
error(const char *const origin, const int rc) noexcept
Constructor.
Definition: lmdb++.h:76
virtual const char * what() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:98
int code() const noexcept
Returns the underlying LMDB error code.
Definition: lmdb++.h:84
static void raise(const char *origin, int rc)
Throws an error based on the given LMDB return code.
Definition: lmdb++.h:211
const char * origin() const noexcept
Returns the origin of the LMDB error.
Definition: lmdb++.h:91
Base class for fatal error conditions.
Definition: lmdb++.h:126
Exception class for `MDB_KEYEXIST` errors.
Definition: lmdb++.h:144
Base class for logic error conditions.
Definition: lmdb++.h:118
Exception class for `MDB_MAP_FULL` errors.
Definition: lmdb++.h:194
Exception class for `MDB_NOTFOUND` errors.
Definition: lmdb++.h:154
Exception class for `MDB_PANIC` errors.
Definition: lmdb++.h:174
Base class for runtime error conditions.
Definition: lmdb++.h:134
Resource class for `MDB_txn*` handles.
Definition: lmdb++.h:1262
void commit()
Commits this transaction.
Definition: lmdb++.h:1350
MDB_env * env() const noexcept
Returns the transaction's `MDB_env*` handle.
Definition: lmdb++.h:1340
txn & operator=(txn &&other) noexcept
Move assignment operator.
Definition: lmdb++.h:1306
void abort() noexcept
Aborts this transaction.
Definition: lmdb++.h:1360
void reset() noexcept
Resets this read-only transaction.
Definition: lmdb++.h:1368
MDB_txn * _handle
Definition: lmdb++.h:1264
~txn() noexcept
Destructor.
Definition: lmdb++.h:1316
void renew()
Renews this read-only transaction.
Definition: lmdb++.h:1377
static constexpr unsigned int default_flags
Definition: lmdb++.h:1267
txn(txn &&other) noexcept
Move constructor.
Definition: lmdb++.h:1299
txn(MDB_txn *const handle) noexcept
Constructor.
Definition: lmdb++.h:1293
static txn begin(MDB_env *const env, MDB_txn *const parent=nullptr, const unsigned int flags=default_flags)
Creates a new LMDB transaction.
Definition: lmdb++.h:1277
MDB_txn * handle() const noexcept
Returns the underlying `MDB_txn*` handle.
Definition: lmdb++.h:1333
Wrapper class for `MDB_val` structures.
Definition: lmdb++.h:948
val(const char *const data) noexcept
Constructor.
Definition: lmdb++.h:967
val & assign(const T *const data, const std::size_t size) noexcept
Assigns the value.
Definition: lmdb++.h:1054
MDB_val _val
Definition: lmdb++.h:950
val(const void *const data, const std::size_t size) noexcept
Constructor.
Definition: lmdb++.h:973
const T * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1032
bool empty() const noexcept
Determines whether this value is empty.
Definition: lmdb++.h:1009
const char * data() const noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1046
val(val &&other) noexcept=default
Move constructor.
T * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1024
val() noexcept=default
Default constructor.
char * data() noexcept
Returns a pointer to the data.
Definition: lmdb++.h:1039
val & assign(const char *const data) noexcept
Assigns the value.
Definition: lmdb++.h:1064
~val() noexcept=default
Destructor.
std::size_t size() const noexcept
Returns the size of the data.
Definition: lmdb++.h:1016
val & operator=(val &&other) noexcept=default
Move assignment operator.
val & assign(const std::string &data) noexcept
Assigns the value.
Definition: lmdb++.h:1071
Exception class for `MDB_VERSION_MISMATCH` errors.
Definition: lmdb++.h:184
static uch flags
#define T(s)
Definition: common.h:230
CS_CONTEXT * ctx
Definition: t0006.c:12
static HENV env
Definition: transaction2.c:38
static void fatal_error(const char *msg)
Definition: dynamic1.c:26
char data[12]
Definition: iconv.c:80
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
string
Definition: cgiapp.hpp:690
#define MDB_VERINT(a, b, c)
Combine args a,b,c into a single integer for easy version comparisons.
Definition: lmdb.h:206
#define MDB_VERSION_FULL
The full library version as a single integer.
Definition: lmdb.h:209
#define MDB_KEYEXIST
key/data pair already exists
Definition: lmdb.h:405
#define MDB_MAP_FULL
Environment mapsize reached.
Definition: lmdb.h:419
#define MDB_VERSION_MISMATCH
Environment version mismatch.
Definition: lmdb.h:415
#define MDB_BAD_DBI
The specified DBI was changed unexpectedly.
Definition: lmdb.h:450
#define MDB_NOTFOUND
key/data pair not found (EOF)
Definition: lmdb.h:407
#define MDB_SUCCESS
Successful result.
Definition: lmdb.h:403
#define MDB_PANIC
Update of meta page failed or environment had fatal error.
Definition: lmdb.h:413
#define MDB_CORRUPTED
Located page was wrong type.
Definition: lmdb.h:411
void mdb_txn_reset(MDB_txn *txn)
Reset a read-only transaction.
Definition: mdb.c:3048
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
Definition: mdb.c:9689
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
Definition: mdb.c:6540
int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags)
Delete current key/data pair.
Definition: mdb.c:7069
int mdb_env_get_flags(MDB_env *env, unsigned int *flags)
Get environment flags.
Definition: mdb.c:9601
MDB_dbi mdb_cursor_dbi(MDB_cursor *cursor)
Return the cursor's database handle.
Definition: mdb.c:7745
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
Definition: mdb.c:4959
int mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
Copy an LMDB environment to the specified path, with options.
Definition: mdb.c:9563
int mdb_cursor_count(MDB_cursor *cursor, size_t *countp)
Return count of duplicates for current key.
Definition: mdb.c:7685
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
Definition: mdb.c:5156
int mdb_env_copyfd(MDB_env *env, mdb_filehandle_t fd)
Copy an LMDB environment to the specified file descriptor.
Definition: mdb.c:9557
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
Definition: mdb.c:6319
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Store items into a database.
Definition: mdb.c:9009
int mdb_env_copyfd2(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Copy an LMDB environment to the specified file descriptor, with options.
Definition: mdb.c:9548
void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
Close a database handle.
Definition: mdb.c:9867
int mdb_env_copy(MDB_env *env, const char *path)
Copy an LMDB environment to the specified path.
Definition: mdb.c:9583
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom key comparison function for a database.
Definition: mdb.c:10042
int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Set a relocation function for a MDB_FIXEDMAP database.
Definition: mdb.c:10060
int mdb_txn_renew(MDB_txn *txn)
Renew a read-only transaction.
Definition: mdb.c:2812
void * mdb_env_get_userctx(MDB_env *env)
Get the application information associated with the MDB_env.
Definition: mdb.c:9620
int mdb_env_get_maxreaders(MDB_env *env, unsigned int *readers)
Get the maximum number of threads/reader slots for the environment.
Definition: mdb.c:4112
void mdb_txn_abort(MDB_txn *txn)
Abandon all the operations of the transaction instead of saving them.
Definition: mdb.c:3061
int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Set a context pointer for a MDB_FIXEDMAP database's relocation function.
Definition: mdb.c:10069
int mdb_env_set_flags(MDB_env *env, unsigned int flags, int onoff)
Set environment flags.
Definition: mdb.c:9589
int mdb_txn_commit(MDB_txn *txn)
Commit all the operations of a transaction into the database.
Definition: mdb.c:3448
int mdb_env_sync(MDB_env *env, int force)
Flush the data buffers to disk.
Definition: mdb.c:2513
int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Get items from a database.
Definition: mdb.c:5782
int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Retrieve the DB flags for a database handle.
Definition: mdb.c:9883
char * mdb_strerror(int err)
Return a string describing a given error code.
Definition: mdb.c:1479
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Create a cursor handle.
Definition: mdb.c:7634
int mdb_env_set_mapsize(MDB_env *env, size_t size)
Set the size of the memory map to use for this environment.
Definition: mdb.c:4060
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
Definition: mdb.c:4094
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
Definition: mdb.c:3951
int mdb_env_get_maxkeysize(MDB_env *env)
Get the maximum size of keys and MDB_DUPSORT data we can write.
Definition: mdb.c:10079
int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Delete items from a database.
Definition: mdb.c:8523
int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
Empty or delete+close a database.
Definition: mdb.c:9991
int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Open a database in the environment.
Definition: mdb.c:9730
int mdb_env_get_path(MDB_env *env, const char **path)
Return the path that was used in mdb_env_open().
Definition: mdb.c:9637
int mdb_cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Renew a cursor handle.
Definition: mdb.c:7668
int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom data comparison function for a MDB_DUPSORT database.
Definition: mdb.c:10051
void mdb_cursor_close(MDB_cursor *cursor)
Close a cursor handle.
Definition: mdb.c:7723
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
Definition: mdb.c:2829
size_t mdb_txn_id(MDB_txn *txn)
Return the transaction's ID.
Definition: mdb.c:2937
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:366
int mdb_env_set_maxreaders(MDB_env *env, unsigned int readers)
Set the maximum number of threads/reader slots for the environment.
Definition: mdb.c:4103
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Retrieve statistics for a database.
Definition: mdb.c:9850
MDB_txn * mdb_cursor_txn(MDB_cursor *cursor)
Return the cursor's transaction handle.
Definition: mdb.c:7738
int mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Return the filedescriptor for the given environment.
Definition: mdb.c:9647
int mdb_env_set_userctx(MDB_env *env, void *ctx)
Set application information associated with the MDB_env.
Definition: mdb.c:9611
int mdb_env_stat(MDB_env *env, MDB_stat *stat)
Return statistics about the LMDB environment.
Definition: mdb.c:9676
MDB_env * mdb_txn_env(MDB_txn *txn)
Returns the transaction's MDB_env.
Definition: mdb.c:2930
@ MDB_SET
Position at specified key.
Definition: lmdb.h:390
size_t ms_entries
Number of data items.
Definition: lmdb.h:463
size_t mv_size
size of the data item
Definition: lmdb.h:258
void * mv_data
address of the data item
Definition: lmdb.h:259
void() MDB_rel_func(MDB_val *item, void *oldptr, void *newptr, void *relctx)
A callback function used to relocate a position-dependent data item in a fixed-address database.
Definition: lmdb.h:279
int() MDB_cmp_func(const MDB_val *a, const MDB_val *b)
A callback function used to compare two keys in a database.
Definition: lmdb.h:263
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition: lmdb.h:241
<lmdb++.h> - C++11 wrapper for LMDB.
Definition: lmdb++.h:37
static void env_info(MDB_env *env, MDB_envinfo *stat)
Definition: lmdb++.h:356
static void * env_get_userctx(MDB_env *env)
Definition: lmdb++.h:524
static void dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
Definition: lmdb++.h:673
static void cursor_renew(MDB_txn *txn, MDB_cursor *cursor)
Definition: lmdb++.h:854
static void env_copy_fd(MDB_env *env, mdb_filehandle_t fd, unsigned int flags)
Definition: lmdb++.h:324
static void txn_commit(MDB_txn *txn)
Definition: lmdb++.h:583
static void env_open(MDB_env *env, const char *path, unsigned int flags, mode mode)
Definition: lmdb++.h:288
static MDB_txn * cursor_txn(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:866
static void dbi_drop(MDB_txn *txn, MDB_dbi dbi, bool del)
Definition: lmdb++.h:695
static bool dbi_put(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:783
static void env_create(MDB_env **env)
Definition: lmdb++.h:276
static unsigned int env_get_max_keysize(MDB_env *env)
Definition: lmdb++.h:494
static void cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Definition: lmdb++.h:832
static void cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Definition: lmdb++.h:899
static void env_get_fd(MDB_env *env, mdb_filehandle_t *fd)
Definition: lmdb++.h:430
static void cursor_del(MDB_cursor *cursor, unsigned int flags)
Definition: lmdb++.h:914
static void dbi_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
Definition: lmdb++.h:737
static void dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Definition: lmdb++.h:644
static void dbi_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:709
static void env_set_max_readers(MDB_env *env, unsigned int count)
Definition: lmdb++.h:456
static MDB_env * txn_env(MDB_txn *txn) noexcept
Definition: lmdb++.h:564
static void env_set_mapsize(MDB_env *env, std::size_t size)
Definition: lmdb++.h:443
static void env_set_max_dbs(MDB_env *env, MDB_dbi count)
Definition: lmdb++.h:482
static void env_close(MDB_env *env) noexcept
Definition: lmdb++.h:381
static void env_set_flags(MDB_env *env, unsigned int flags, bool onoff)
Definition: lmdb++.h:390
static void txn_renew(MDB_txn *txn)
Definition: lmdb++.h:611
static void cursor_close(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:845
static bool cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Definition: lmdb++.h:883
static void cursor_count(MDB_cursor *cursor, std::size_t &count)
Definition: lmdb++.h:927
static void env_get_max_readers(MDB_env *env, unsigned int *count)
Definition: lmdb++.h:469
static MDB_dbi cursor_dbi(MDB_cursor *cursor) noexcept
Definition: lmdb++.h:874
static void txn_abort(MDB_txn *txn) noexcept
Definition: lmdb++.h:594
static void env_get_path(MDB_env *env, const char **path)
Definition: lmdb++.h:417
static void dbi_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat)
Definition: lmdb++.h:659
static bool dbi_del(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, const MDB_val *data)
Definition: lmdb++.h:801
static bool dbi_get(MDB_txn *txn, MDB_dbi dbi, const MDB_val *key, MDB_val *data)
Definition: lmdb++.h:766
static void env_copy(MDB_env *env, const char *path, unsigned int flags)
Definition: lmdb++.h:304
static void txn_reset(MDB_txn *txn) noexcept
Definition: lmdb++.h:602
static void env_set_userctx(MDB_env *env, void *ctx)
Definition: lmdb++.h:509
static void dbi_close(MDB_env *env, MDB_dbi dbi) noexcept
Definition: lmdb++.h:686
static void env_stat(MDB_env *env, MDB_stat *stat)
Definition: lmdb++.h:343
static void env_sync(MDB_env *env, bool force)
Definition: lmdb++.h:369
static void dbi_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Definition: lmdb++.h:723
mdb_mode_t mode
Definition: lmdb++.h:38
static void env_get_flags(MDB_env *env, unsigned int *flags)
Definition: lmdb++.h:404
static void txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Definition: lmdb++.h:550
static void dbi_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
Definition: lmdb++.h:751
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
static const GLdouble origin[]
#define count
static uint8_t * buffer
Definition: pcre2test.c:1016
int mdb_filehandle_t
An abstraction for a file handle.
Definition: lmdb.h:188
mode_t mdb_mode_t
Unix permissions for creating files, or dummy definition for Windows.
Definition: lmdb.h:178
#define assert(x)
Definition: srv_diag.hpp:58
Cursors are used for all DB operations.
Definition: mdb.c:1184
The database environment.
Definition: mdb.c:1259
Information about the environment.
Definition: lmdb.h:467
Statistics for a database in the environment.
Definition: lmdb.h:456
A database transaction.
Definition: mdb.c:1084
Generic structure used for passing keys and data in and out of the database.
Definition: lmdb.h:257
else result
Definition: token2.c:20
#define const
Definition: zconf.h:232
Modified on Fri Sep 20 14:57:49 2024 by modify_doxy.py rev. 669887