libmdbx  0.11.6.39 (2022-04-13T11:05:50+03:00)
One of the fastest compact embeddable key-value ACID database without WAL.
mdbx.h++
Go to the documentation of this file.
1 
16 #pragma once
17 
18 /* Workaround for modern libstdc++ with CLANG < 4.x */
19 #if defined(__SIZEOF_INT128__) && !defined(__GLIBCXX_TYPE_INT_N_0) && \
20  defined(__clang__) && __clang_major__ < 4
21 #define __GLIBCXX_BITSIZE_INT_N_0 128
22 #define __GLIBCXX_TYPE_INT_N_0 __int128
23 #endif /* Workaround for modern libstdc++ with CLANG < 4.x */
24 
25 #if !defined(__cplusplus) || __cplusplus < 201103L
26 #if !defined(_MSC_VER) || _MSC_VER < 1900
27 #error "C++11 compiler or better is required"
28 #elif _MSC_VER >= 1910
29 #error \
30  "Please add `/Zc:__cplusplus` to MSVC compiler options to enforce it conform ISO C++"
31 #endif /* MSVC is mad and don't define __cplusplus properly */
32 #endif /* __cplusplus < 201103L */
33 
34 #if (defined(_WIN32) || defined(_WIN64)) && MDBX_WITHOUT_MSVC_CRT
35 #error \
36  "CRT is required for C++ API, the MDBX_WITHOUT_MSVC_CRT option must be disabled"
37 #endif /* Windows */
38 
39 #ifndef __has_include
40 #define __has_include(header) (0)
41 #endif /* __has_include */
42 
43 #if __has_include(<version>)
44 #include <version>
45 #endif /* <version> */
46 
47 /* Disable min/max macros from C' headers */
48 #ifndef NOMINMAX
49 #define NOMINMAX
50 #endif
51 
52 #include <algorithm> // for std::min/max
53 #include <cassert> // for assert()
54 #include <climits> // for CHAR_BIT
55 #include <cstring> // for std::strlen, str:memcmp
56 #include <exception> // for std::exception_ptr
57 #include <ostream> // for std::ostream
58 #include <sstream> // for std::ostringstream
59 #include <stdexcept> // for std::invalid_argument
60 #include <string> // for std::string
61 #include <type_traits> // for std::is_pod<>, etc.
62 #include <utility> // for std::make_pair
63 #include <vector> // for std::vector<> as template args
64 
65 #if defined(__cpp_lib_memory_resource) && __cpp_lib_memory_resource >= 201603L
66 #include <memory_resource>
67 #endif
68 
69 #if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
70 #include <string_view>
71 #endif
72 
73 #if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L
74 #include <filesystem>
75 #elif __has_include(<experimental/filesystem>)
76 #include <experimental/filesystem>
77 #endif
78 
79 #include "mdbx.h"
80 
81 #if (defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L) || \
82  (defined(__cpp_lib_endian) && __cpp_lib_endian >= 201907L) || \
83  (defined(__cpp_lib_bitops) && __cpp_lib_bitops >= 201907L) || \
84  (defined(__cpp_lib_int_pow2) && __cpp_lib_int_pow2 >= 202002L)
85 #include <bit>
86 #elif !(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
87  defined(__ORDER_BIG_ENDIAN__))
88 #if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && defined(__BIG_ENDIAN)
89 #define __ORDER_LITTLE_ENDIAN__ __LITTLE_ENDIAN
90 #define __ORDER_BIG_ENDIAN__ __BIG_ENDIAN
91 #define __BYTE_ORDER__ __BYTE_ORDER
92 #elif defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
93 #define __ORDER_LITTLE_ENDIAN__ _LITTLE_ENDIAN
94 #define __ORDER_BIG_ENDIAN__ _BIG_ENDIAN
95 #define __BYTE_ORDER__ _BYTE_ORDER
96 #else
97 #define __ORDER_LITTLE_ENDIAN__ 1234
98 #define __ORDER_BIG_ENDIAN__ 4321
99 #if defined(__LITTLE_ENDIAN__) || \
100  (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
101  defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || \
102  defined(__MIPSEL__) || defined(_MIPSEL) || defined(__MIPSEL) || \
103  defined(_M_ARM) || defined(_M_ARM64) || defined(__e2k__) || \
104  defined(__elbrus_4c__) || defined(__elbrus_8c__) || defined(__bfin__) || \
105  defined(__BFIN__) || defined(__ia64__) || defined(_IA64) || \
106  defined(__IA64__) || defined(__ia64) || defined(_M_IA64) || \
107  defined(__itanium__) || defined(__ia32__) || defined(__CYGWIN__) || \
108  defined(_WIN64) || defined(_WIN32) || defined(__TOS_WIN__) || \
109  defined(__WINDOWS__)
110 #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
111 #elif defined(__BIG_ENDIAN__) || \
112  (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \
113  defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || \
114  defined(__MIPSEB__) || defined(_MIPSEB) || defined(__MIPSEB) || \
115  defined(__m68k__) || defined(M68000) || defined(__hppa__) || \
116  defined(__hppa) || defined(__HPPA__) || defined(__sparc__) || \
117  defined(__sparc) || defined(__370__) || defined(__THW_370__) || \
118  defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
119 #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
120 #endif
121 #endif
122 #endif /* Byte Order */
123 
124 #if defined(DOXYGEN) || \
125  defined(__cpp_constexpr) && __cpp_constexpr >= 201603L && \
126  ((defined(_MSC_VER) && _MSC_VER >= 1915) || \
127  (defined(__clang__) && __clang_major__ > 5) || \
128  (defined(__GNUC__) && __GNUC__ > 7) || \
129  (!defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER)))
130 #define MDBX_CXX17_CONSTEXPR constexpr
131 #else
132 #define MDBX_CXX17_CONSTEXPR inline
133 #endif /* MDBX_CXX17_CONSTEXPR */
134 
135 #if defined(DOXYGEN) || defined(__cpp_lib_is_constant_evaluated) && \
136  __cpp_lib_is_constant_evaluated >= 201811L && \
137  defined(__cpp_lib_constexpr_string) && \
138  __cpp_lib_constexpr_string >= 201907L
139 #define MDBX_CXX20_CONSTEXPR constexpr
140 #else
141 #define MDBX_CXX20_CONSTEXPR inline
142 #endif /* MDBX_CXX20_CONSTEXPR */
143 
144 #if defined(CONSTEXPR_ASSERT)
145 #define MDBX_CONSTEXPR_ASSERT(expr) CONSTEXPR_ASSERT(expr)
146 #elif defined NDEBUG
147 #define MDBX_CONSTEXPR_ASSERT(expr) void(0)
148 #else
149 #define MDBX_CONSTEXPR_ASSERT(expr) \
150  ((expr) ? void(0) : [] { assert(!#expr); }())
151 #endif /* MDBX_CONSTEXPR_ASSERT */
152 
153 #ifndef MDBX_LIKELY
154 #if defined(DOXYGEN) || \
155  (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \
156  !defined(__COVERITY__)
157 #define MDBX_LIKELY(cond) __builtin_expect(!!(cond), 1)
158 #else
159 #define MDBX_LIKELY(x) (x)
160 #endif
161 #endif /* MDBX_LIKELY */
162 
163 #ifndef MDBX_UNLIKELY
164 #if defined(DOXYGEN) || \
165  (defined(__GNUC__) || __has_builtin(__builtin_expect)) && \
166  !defined(__COVERITY__)
167 #define MDBX_UNLIKELY(cond) __builtin_expect(!!(cond), 0)
168 #else
169 #define MDBX_UNLIKELY(x) (x)
170 #endif
171 #endif /* MDBX_UNLIKELY */
172 
173 #if defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
174 #define MDBX_IF_CONSTEXPR constexpr
175 #else
176 #define MDBX_IF_CONSTEXPR
177 #endif /* MDBX_IF_CONSTEXPR */
178 
179 #if defined(DOXYGEN) || \
180  (__has_cpp_attribute(fallthrough) && \
181  (!defined(__clang__) || __clang__ > 4)) || \
182  __cplusplus >= 201703L
183 #define MDBX_CXX17_FALLTHROUGH [[fallthrough]]
184 #else
185 #define MDBX_CXX17_FALLTHROUGH
186 #endif /* MDBX_CXX17_FALLTHROUGH */
187 
188 #if defined(DOXYGEN) || (__has_cpp_attribute(likely) >= 201803L && \
189  (!defined(__GNUC__) || __GNUC__ > 9))
190 #define MDBX_CXX20_LIKELY [[likely]]
191 #else
192 #define MDBX_CXX20_LIKELY
193 #endif /* MDBX_CXX20_LIKELY */
194 
195 #ifndef MDBX_CXX20_UNLIKELY
196 #if defined(DOXYGEN) || (__has_cpp_attribute(unlikely) >= 201803L && \
197  (!defined(__GNUC__) || __GNUC__ > 9))
198 #define MDBX_CXX20_UNLIKELY [[unlikely]]
199 #else
200 #define MDBX_CXX20_UNLIKELY
201 #endif
202 #endif /* MDBX_CXX20_UNLIKELY */
203 
204 #ifndef MDBX_CXX20_CONCEPT
205 #if defined(DOXYGEN) || \
206  (defined(__cpp_concepts) && __cpp_concepts >= 201907L && \
207  (!defined(__clang__) || \
208  (__clang_major__ >= 12 && !defined(__APPLE__) && \
209  !defined(__ANDROID_API__)) || \
210  __clang_major__ >= \
211  /* Hope Apple will fix concepts in AppleClang 14 */ 14))
212 #define MDBX_CXX20_CONCEPT(CONCEPT, NAME) CONCEPT NAME
213 #else
214 #define MDBX_CXX20_CONCEPT(CONCEPT, NAME) typename NAME
215 #endif
216 #endif /* MDBX_CXX20_CONCEPT */
217 
218 #ifndef MDBX_ASSERT_CXX20_CONCEPT_SATISFIED
219 #if defined(DOXYGEN) || \
220  (defined(__cpp_concepts) && __cpp_concepts >= 201907L && \
221  (!defined(__clang__) || \
222  (__clang_major__ >= 12 && !defined(__APPLE__) && \
223  !defined(__ANDROID_API__)) || \
224  __clang_major__ >= \
225  /* Hope Apple will fix concepts in AppleClang 14 */ 14))
226 #define MDBX_ASSERT_CXX20_CONCEPT_SATISFIED(CONCEPT, TYPE) \
227  static_assert(CONCEPT<TYPE>)
228 #else
229 #define MDBX_ASSERT_CXX20_CONCEPT_SATISFIED(CONCEPT, NAME) \
230  static_assert(true, MDBX_STRINGIFY(CONCEPT) "<" MDBX_STRINGIFY(TYPE) ">")
231 #endif
232 #endif /* MDBX_ASSERT_CXX20_CONCEPT_SATISFIED */
233 
234 #ifdef _MSC_VER
235 #pragma warning(push, 4)
236 #pragma warning(disable : 4127) /* conditional expression is constant */
237 #pragma warning(disable : 4251) /* 'std::FOO' needs to have dll-interface to \
238  be used by clients of 'mdbx::BAR' */
239 #pragma warning(disable : 4275) /* non dll-interface 'std::FOO' used as \
240  base for dll-interface 'mdbx::BAR' */
241 /* MSVC is mad and can generate this warning for its own intermediate
242  * automatically generated code, which becomes unreachable after some kinds of
243  * optimization (copy elision, etc). */
244 #pragma warning(disable : 4702) /* unreachable code */
245 #endif /* _MSC_VER (warnings) */
246 
247 //------------------------------------------------------------------------------
250 
251 namespace mdbx {
252 
253 // Functions whose signature depends on the `mdbx::byte` type
254 // must be strictly defined as inline!
255 #if defined(DOXYGEN) || (defined(__cpp_char8_t) && __cpp_char8_t >= 201811)
256 // To enable all kinds of an compiler optimizations we use a byte-like type
257 // that don't presumes aliases for pointers as does the `char` type and its
258 // derivatives/typedefs.
259 // Please see https://github.com/erthink/libmdbx/issues/263
260 // for reasoning of the use of `char8_t` type and switching to `__restrict__`.
261 using byte = char8_t;
262 #else
263 // Avoid `std::byte` since it doesn't add features but inconvenient
264 // restrictions.
265 using byte = unsigned char;
266 #endif /* __cpp_char8_t >= 201811*/
267 
268 #if defined(__cpp_lib_endian) && __cpp_lib_endian >= 201907L
269 using endian = ::std::endian;
270 #elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
271  defined(__ORDER_BIG_ENDIAN__)
272 enum class endian {
273  little = __ORDER_LITTLE_ENDIAN__,
274  big = __ORDER_BIG_ENDIAN__,
275  native = __BYTE_ORDER__
276 };
277 #else
278 #error \
279  "Please use a C++ compiler provides byte order information or C++20 support"
280 #endif /* Byte Order enum */
281 
289 MDBX_CXX11_CONSTEXPR const build_info &get_build() noexcept;
290 
292 static MDBX_CXX17_CONSTEXPR size_t strlen(const char *c_str) noexcept;
293 
296 using legacy_allocator = ::std::string::allocator_type;
297 
298 struct slice;
300 template <class ALLOCATOR = legacy_allocator,
301  class CAPACITY_POLICY = default_capacity_policy>
302 class buffer;
303 class env;
304 class env_managed;
305 class txn;
306 class txn_managed;
307 class cursor;
308 class cursor_managed;
309 
310 #if defined(DOXYGEN) || \
311  (defined(__cpp_lib_memory_resource) && \
312  __cpp_lib_memory_resource >= 201603L && _GLIBCXX_USE_CXX11_ABI)
313 using polymorphic_allocator = ::std::pmr::string::allocator_type;
315 #endif /* __cpp_lib_memory_resource >= 201603L */
316 
318 template <class ALLOCATOR = legacy_allocator>
319 using string = ::std::basic_string<char, ::std::char_traits<char>, ALLOCATOR>;
320 
322 #if defined(DOXYGEN) || \
323  (defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
324  (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || \
325  __MAC_OS_X_VERSION_MIN_REQUIRED >= 101500) && \
326  (!defined(__IPHONE_OS_VERSION_MIN_REQUIRED) || \
327  __IPHONE_OS_VERSION_MIN_REQUIRED >= 130100))
328 namespace filesystem = ::std::filesystem;
329 #define MDBX_STD_FILESYSTEM_PATH ::mdbx::filesystem::path
330 #elif defined(__cpp_lib_experimental_filesystem) && \
331  __cpp_lib_experimental_filesystem >= 201406L
332 namespace filesystem = ::std::experimental::filesystem;
333 #define MDBX_STD_FILESYSTEM_PATH ::mdbx::filesystem::path
334 #endif /* MDBX_STD_FILESYSTEM_PATH */
335 
336 #ifdef MDBX_STD_FILESYSTEM_PATH
338 #elif defined(_WIN32) || defined(_WIN64)
339 using path = ::std::wstring;
340 #else
341 using path = ::std::string;
342 #endif /* mdbx::path */
343 
349  ::std::exception_ptr captured_;
350 
351 public:
352  exception_thunk() noexcept = default;
353  exception_thunk(const exception_thunk &) = delete;
354  exception_thunk(exception_thunk &&) = delete;
355  exception_thunk &operator=(const exception_thunk &) = delete;
356  exception_thunk &operator=(exception_thunk &&) = delete;
357  inline bool is_clean() const noexcept;
358  inline void capture() noexcept;
359  inline void rethrow_captured() const;
360 };
361 
364  MDBX_error_t code_;
365  inline error &operator=(MDBX_error_t error_code) noexcept;
366 
367 public:
368  MDBX_CXX11_CONSTEXPR error(MDBX_error_t error_code) noexcept;
369  error(const error &) = default;
370  error(error &&) = default;
371  error &operator=(const error &) = default;
372  error &operator=(error &&) = default;
373 
374  MDBX_CXX11_CONSTEXPR friend bool operator==(const error &a,
375  const error &b) noexcept;
376  MDBX_CXX11_CONSTEXPR friend bool operator!=(const error &a,
377  const error &b) noexcept;
378 
379  MDBX_CXX11_CONSTEXPR bool is_success() const noexcept;
380  MDBX_CXX11_CONSTEXPR bool is_result_true() const noexcept;
381  MDBX_CXX11_CONSTEXPR bool is_result_false() const noexcept;
382  MDBX_CXX11_CONSTEXPR bool is_failure() const noexcept;
383 
385  MDBX_CXX11_CONSTEXPR MDBX_error_t code() const noexcept;
386 
388  const char *what() const noexcept;
389 
391  ::std::string message() const;
392 
394  MDBX_CXX11_CONSTEXPR bool is_mdbx_error() const noexcept;
396  [[noreturn]] void panic(const char *context_where_when,
397  const char *func_who_what) const noexcept;
398  [[noreturn]] void throw_exception() const;
399  [[noreturn]] static inline void throw_exception(int error_code);
400  inline void throw_on_failure() const;
401  inline void success_or_throw() const;
402  inline void success_or_throw(const exception_thunk &) const;
403  inline void panic_on_failure(const char *context_where,
404  const char *func_who) const noexcept;
405  inline void success_or_panic(const char *context_where,
406  const char *func_who) const noexcept;
407  static inline void throw_on_nullptr(const void *ptr, MDBX_error_t error_code);
408  static inline void success_or_throw(MDBX_error_t error_code);
409  static void success_or_throw(int error_code) {
410  success_or_throw(static_cast<MDBX_error_t>(error_code));
411  }
412  static inline void throw_on_failure(int error_code);
413  static inline bool boolean_or_throw(int error_code);
414  static inline void success_or_throw(int error_code, const exception_thunk &);
415  static inline void panic_on_failure(int error_code, const char *context_where,
416  const char *func_who) noexcept;
417  static inline void success_or_panic(int error_code, const char *context_where,
418  const char *func_who) noexcept;
419 };
420 
425 class LIBMDBX_API_TYPE exception : public ::std::runtime_error {
426  using base = ::std::runtime_error;
427  ::mdbx::error error_;
428 
429 public:
430  exception(const ::mdbx::error &) noexcept;
431  exception(const exception &) = default;
432  exception(exception &&) = default;
433  exception &operator=(const exception &) = default;
434  exception &operator=(exception &&) = default;
435  virtual ~exception() noexcept;
436  const ::mdbx::error error() const noexcept { return error_; }
437 };
438 
442  using base = exception;
443 
444 public:
445  fatal(const ::mdbx::error &) noexcept;
446  fatal(const exception &src) noexcept : fatal(src.error()) {}
447  fatal(exception &&src) noexcept : fatal(src.error()) {}
448  fatal(const fatal &src) noexcept : fatal(src.error()) {}
449  fatal(fatal &&src) noexcept : fatal(src.error()) {}
450  fatal &operator=(fatal &&) = default;
451  fatal &operator=(const fatal &) = default;
452  virtual ~fatal() noexcept;
453 };
454 
455 #define MDBX_DECLARE_EXCEPTION(NAME) \
456  struct LIBMDBX_API_TYPE NAME : public exception { \
457  NAME(const ::mdbx::error &); \
458  virtual ~NAME() noexcept; \
459  }
460 MDBX_DECLARE_EXCEPTION(bad_map_id);
461 MDBX_DECLARE_EXCEPTION(bad_transaction);
462 MDBX_DECLARE_EXCEPTION(bad_value_size);
463 MDBX_DECLARE_EXCEPTION(db_corrupted);
464 MDBX_DECLARE_EXCEPTION(db_full);
465 MDBX_DECLARE_EXCEPTION(db_invalid);
466 MDBX_DECLARE_EXCEPTION(db_too_large);
467 MDBX_DECLARE_EXCEPTION(db_unable_extend);
468 MDBX_DECLARE_EXCEPTION(db_version_mismatch);
469 MDBX_DECLARE_EXCEPTION(db_wanna_write_for_recovery);
470 MDBX_DECLARE_EXCEPTION(incompatible_operation);
471 MDBX_DECLARE_EXCEPTION(internal_page_full);
472 MDBX_DECLARE_EXCEPTION(internal_problem);
473 MDBX_DECLARE_EXCEPTION(key_exists);
474 MDBX_DECLARE_EXCEPTION(key_mismatch);
475 MDBX_DECLARE_EXCEPTION(max_maps_reached);
476 MDBX_DECLARE_EXCEPTION(max_readers_reached);
477 MDBX_DECLARE_EXCEPTION(multivalue);
478 MDBX_DECLARE_EXCEPTION(no_data);
479 MDBX_DECLARE_EXCEPTION(not_found);
480 MDBX_DECLARE_EXCEPTION(operation_not_permitted);
481 MDBX_DECLARE_EXCEPTION(permission_denied_or_not_writeable);
482 MDBX_DECLARE_EXCEPTION(reader_slot_busy);
483 MDBX_DECLARE_EXCEPTION(remote_media);
484 MDBX_DECLARE_EXCEPTION(something_busy);
485 MDBX_DECLARE_EXCEPTION(thread_mismatch);
486 MDBX_DECLARE_EXCEPTION(transaction_full);
487 MDBX_DECLARE_EXCEPTION(transaction_overlapping);
488 #undef MDBX_DECLARE_EXCEPTION
489 
490 [[noreturn]] LIBMDBX_API void throw_too_small_target_buffer();
491 [[noreturn]] LIBMDBX_API void throw_max_length_exceeded();
492 [[noreturn]] LIBMDBX_API void throw_out_range();
493 [[noreturn]] LIBMDBX_API void throw_allocators_mismatch();
494 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes);
495 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom,
496  size_t payload);
497 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom, size_t payload,
498  size_t tailroom);
499 static MDBX_CXX17_CONSTEXPR size_t strlen(const char *c_str) noexcept;
500 static MDBX_CXX20_CONSTEXPR void *memcpy(void *dest, const void *src,
501  size_t bytes) noexcept;
502 //------------------------------------------------------------------------------
503 
504 #if defined(DOXYGEN) || \
505  (defined(__cpp_concepts) && __cpp_concepts >= 201907L && \
506  (!defined(__clang__) || \
507  (__clang_major__ >= 12 && !defined(__APPLE__) && \
508  !defined(__ANDROID_API__)) || \
509  __clang_major__ >= \
510  /* Hope Apple will fix concepts in AppleClang 14 */ 14))
511 
512 template <typename T>
513 concept MutableByteProducer = requires(T a, char array[42]) {
514  { a.is_empty() } -> std::same_as<bool>;
515  { a.envisage_result_length() } -> std::same_as<size_t>;
516  { a.write_bytes(&array[0], size_t(42)) } -> std::same_as<char *>;
517 };
518 
519 template <typename T>
520 concept ImmutableByteProducer = requires(const T &a, char array[42]) {
521  { a.is_empty() } -> std::same_as<bool>;
522  { a.envisage_result_length() } -> std::same_as<size_t>;
523  { a.write_bytes(&array[0], size_t(42)) } -> std::same_as<char *>;
524 };
525 
526 template <typename T>
527 concept SliceTranscoder = ImmutableByteProducer<T> &&
528  requires(const slice &source, const T &a) {
529  T(source);
530  { a.is_erroneous() } -> std::same_as<bool>;
531 };
532 
533 #endif /* __cpp_concepts >= 201907L*/
534 
535 template <class ALLOCATOR = legacy_allocator,
536  typename CAPACITY_POLICY = default_capacity_policy,
538 inline buffer<ALLOCATOR, CAPACITY_POLICY>
539 make_buffer(PRODUCER &producer, const ALLOCATOR &allocator = ALLOCATOR());
540 
541 template <class ALLOCATOR = legacy_allocator,
542  typename CAPACITY_POLICY = default_capacity_policy,
544 inline buffer<ALLOCATOR, CAPACITY_POLICY>
545 make_buffer(const PRODUCER &producer, const ALLOCATOR &allocator = ALLOCATOR());
546 
547 template <class ALLOCATOR = legacy_allocator,
549 inline string<ALLOCATOR> make_string(PRODUCER &producer,
550  const ALLOCATOR &allocator = ALLOCATOR());
551 
552 template <class ALLOCATOR = legacy_allocator,
554 inline string<ALLOCATOR> make_string(const PRODUCER &producer,
555  const ALLOCATOR &allocator = ALLOCATOR());
556 
568 
569  enum { max_length = MDBX_MAXDATASIZE };
570 
572  MDBX_CXX11_CONSTEXPR slice() noexcept;
573 
576  MDBX_CXX14_CONSTEXPR slice(const void *ptr, size_t bytes);
577 
579  MDBX_CXX14_CONSTEXPR slice(const void *begin, const void *end);
580 
582  template <size_t SIZE>
583  MDBX_CXX14_CONSTEXPR slice(const char (&text)[SIZE]) : slice(text, SIZE - 1) {
584  MDBX_CONSTEXPR_ASSERT(SIZE > 0 && text[SIZE - 1] == '\0');
585  }
587  explicit MDBX_CXX17_CONSTEXPR slice(const char *c_str);
588 
591  template <class CHAR, class T, class A>
592  explicit MDBX_CXX20_CONSTEXPR
593  slice(const ::std::basic_string<CHAR, T, A> &str)
594  : slice(str.data(), str.length() * sizeof(CHAR)) {}
595 
596  MDBX_CXX14_CONSTEXPR slice(const MDBX_val &src);
597  MDBX_CXX11_CONSTEXPR slice(const slice &) noexcept = default;
599  MDBX_CXX14_CONSTEXPR slice(slice &&src) noexcept;
600 
601 #if defined(DOXYGEN) || \
602  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
603  template <class CHAR, class T>
605  MDBX_CXX14_CONSTEXPR slice(const ::std::basic_string_view<CHAR, T> &sv)
606  : slice(sv.data(), sv.data() + sv.length()) {}
607 
608  template <class CHAR, class T>
609  slice(::std::basic_string_view<CHAR, T> &&sv) : slice(sv) {
610  sv = {};
611  }
612 #endif /* __cpp_lib_string_view >= 201606L */
613 
614  template <size_t SIZE>
615  static MDBX_CXX14_CONSTEXPR slice wrap(const char (&text)[SIZE]) {
616  return slice(text);
617  }
618 
619  template <typename POD>
620  MDBX_CXX14_CONSTEXPR static slice wrap(const POD &pod) {
621  static_assert(::std::is_standard_layout<POD>::value &&
622  !::std::is_pointer<POD>::value,
623  "Must be a standard layout type!");
624  return slice(&pod, sizeof(pod));
625  }
626 
627  inline slice &assign(const void *ptr, size_t bytes);
628  inline slice &assign(const slice &src) noexcept;
629  inline slice &assign(const ::MDBX_val &src);
630  inline slice &assign(slice &&src) noexcept;
631  inline slice &assign(::MDBX_val &&src);
632  inline slice &assign(const void *begin, const void *end);
633  template <class CHAR, class T, class ALLOCATOR>
634  slice &assign(const ::std::basic_string<CHAR, T, ALLOCATOR> &str) {
635  return assign(str.data(), str.length() * sizeof(CHAR));
636  }
637  inline slice &assign(const char *c_str);
638 #if defined(DOXYGEN) || \
639  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
640  template <class CHAR, class T>
641  slice &assign(const ::std::basic_string_view<CHAR, T> &view) {
642  return assign(view.begin(), view.end());
643  }
644  template <class CHAR, class T>
645  slice &assign(::std::basic_string_view<CHAR, T> &&view) {
646  assign(view);
647  view = {};
648  return *this;
649  }
650 #endif /* __cpp_lib_string_view >= 201606L */
651 
652  slice &operator=(const slice &) noexcept = default;
653  inline slice &operator=(slice &&src) noexcept;
654  inline slice &operator=(::MDBX_val &&src);
655 
656 #if defined(DOXYGEN) || \
657  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
658  template <class CHAR, class T>
659  slice &operator=(const ::std::basic_string_view<CHAR, T> &view) {
660  return assign(view);
661  }
662 
663  template <class CHAR, class T>
664  slice &operator=(::std::basic_string_view<CHAR, T> &&view) {
665  return assign(view);
666  }
667 
669  template <class CHAR = char, class T = ::std::char_traits<CHAR>>
670  MDBX_CXX11_CONSTEXPR ::std::basic_string_view<CHAR, T>
671  string_view() const noexcept {
672  static_assert(sizeof(CHAR) == 1, "Must be single byte characters");
673  return ::std::basic_string_view<CHAR, T>(char_ptr(), length());
674  }
675 
677  template <class CHAR, class T>
678  MDBX_CXX11_CONSTEXPR explicit
679  operator ::std::basic_string_view<CHAR, T>() const noexcept {
680  return this->string_view<CHAR, T>();
681  }
682 #endif /* __cpp_lib_string_view >= 201606L */
683 
684  template <class CHAR = char, class T = ::std::char_traits<CHAR>,
685  class ALLOCATOR = legacy_allocator>
686  MDBX_CXX20_CONSTEXPR ::std::basic_string<CHAR, T, ALLOCATOR>
687  as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
688  static_assert(sizeof(CHAR) == 1, "Must be single byte characters");
689  return ::std::basic_string<CHAR, T, ALLOCATOR>(char_ptr(), length(),
690  allocator);
691  }
692 
693  template <class CHAR, class T, class ALLOCATOR>
694  MDBX_CXX20_CONSTEXPR explicit
695  operator ::std::basic_string<CHAR, T, ALLOCATOR>() const {
696  return as_string<CHAR, T, ALLOCATOR>();
697  }
698 
700  template <class ALLOCATOR = legacy_allocator>
701  inline string<ALLOCATOR>
702  as_hex_string(bool uppercase = false, unsigned wrap_width = 0,
703  const ALLOCATOR &allocator = ALLOCATOR()) const;
704 
707  template <class ALLOCATOR = legacy_allocator>
708  inline string<ALLOCATOR>
709  as_base58_string(unsigned wrap_width = 0,
710  const ALLOCATOR &allocator = ALLOCATOR()) const;
711 
714  template <class ALLOCATOR = legacy_allocator>
715  inline string<ALLOCATOR>
716  as_base64_string(unsigned wrap_width = 0,
717  const ALLOCATOR &allocator = ALLOCATOR()) const;
718 
720  template <class ALLOCATOR = legacy_allocator,
721  class CAPACITY_POLICY = default_capacity_policy>
723  encode_hex(bool uppercase = false, unsigned wrap_width = 0,
724  const ALLOCATOR &allocator = ALLOCATOR()) const;
725 
728  template <class ALLOCATOR = legacy_allocator,
729  class CAPACITY_POLICY = default_capacity_policy>
731  encode_base58(unsigned wrap_width = 0,
732  const ALLOCATOR &allocator = ALLOCATOR()) const;
733 
736  template <class ALLOCATOR = legacy_allocator,
737  class CAPACITY_POLICY = default_capacity_policy>
739  encode_base64(unsigned wrap_width = 0,
740  const ALLOCATOR &allocator = ALLOCATOR()) const;
741 
743  template <class ALLOCATOR = legacy_allocator,
744  class CAPACITY_POLICY = default_capacity_policy>
746  hex_decode(bool ignore_spaces = false,
747  const ALLOCATOR &allocator = ALLOCATOR()) const;
748 
751  template <class ALLOCATOR = legacy_allocator,
752  class CAPACITY_POLICY = default_capacity_policy>
754  base58_decode(bool ignore_spaces = false,
755  const ALLOCATOR &allocator = ALLOCATOR()) const;
756 
759  template <class ALLOCATOR = legacy_allocator,
760  class CAPACITY_POLICY = default_capacity_policy>
762  base64_decode(bool ignore_spaces = false,
763  const ALLOCATOR &allocator = ALLOCATOR()) const;
764 
771  is_printable(bool disable_utf8 = false) const noexcept;
772 
777  inline MDBX_NOTHROW_PURE_FUNCTION bool
778  is_hex(bool ignore_spaces = false) const noexcept;
779 
785  inline MDBX_NOTHROW_PURE_FUNCTION bool
786  is_base58(bool ignore_spaces = false) const noexcept;
787 
793  inline MDBX_NOTHROW_PURE_FUNCTION bool
794  is_base64(bool ignore_spaces = false) const noexcept;
795 
796  inline void swap(slice &other) noexcept;
797 
798 #if defined(DOXYGEN) || \
799  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
800  template <class CHAR, class T>
801  void swap(::std::basic_string_view<CHAR, T> &view) noexcept {
802  static_assert(sizeof(CHAR) == 1, "Must be single byte characters");
803  const auto temp = ::std::basic_string_view<CHAR, T>(*this);
804  *this = view;
805  view = temp;
806  }
807 #endif /* __cpp_lib_string_view >= 201606L */
808 
810  MDBX_CXX11_CONSTEXPR const byte *byte_ptr() const noexcept;
811  MDBX_CXX11_CONSTEXPR byte *byte_ptr() noexcept;
812 
814  MDBX_CXX11_CONSTEXPR const byte *end_byte_ptr() const noexcept;
815  MDBX_CXX11_CONSTEXPR byte *end_byte_ptr() noexcept;
816 
818  MDBX_CXX11_CONSTEXPR const char *char_ptr() const noexcept;
819  MDBX_CXX11_CONSTEXPR char *char_ptr() noexcept;
820 
822  MDBX_CXX11_CONSTEXPR const char *end_char_ptr() const noexcept;
823  MDBX_CXX11_CONSTEXPR char *end_char_ptr() noexcept;
824 
826  MDBX_CXX11_CONSTEXPR const void *data() const noexcept;
827  MDBX_CXX11_CONSTEXPR void *data() noexcept;
828 
830  MDBX_CXX11_CONSTEXPR const void *end() const noexcept;
831  MDBX_CXX11_CONSTEXPR void *end() noexcept;
832 
834  MDBX_CXX11_CONSTEXPR size_t length() const noexcept;
835 
837  MDBX_CXX14_CONSTEXPR slice &set_length(size_t bytes);
838 
840  MDBX_CXX14_CONSTEXPR slice &set_end(const void *ptr);
841 
843  MDBX_CXX11_CONSTEXPR bool empty() const noexcept;
844 
846  MDBX_CXX11_CONSTEXPR bool is_null() const noexcept;
847 
849  MDBX_CXX11_CONSTEXPR size_t size() const noexcept;
850 
852  MDBX_CXX11_CONSTEXPR operator bool() const noexcept;
853 
855  MDBX_CXX14_CONSTEXPR void invalidate() noexcept;
856 
858  MDBX_CXX14_CONSTEXPR void clear() noexcept;
859 
862  inline void remove_prefix(size_t n) noexcept;
863 
866  inline void remove_suffix(size_t n) noexcept;
867 
870  inline void safe_remove_prefix(size_t n);
871 
874  inline void safe_remove_suffix(size_t n);
875 
878  starts_with(const slice &prefix) const noexcept;
879 
882  ends_with(const slice &suffix) const noexcept;
883 
886  MDBX_CXX11_CONSTEXPR byte operator[](size_t n) const noexcept;
887 
890  MDBX_CXX11_CONSTEXPR byte at(size_t n) const;
891 
894  MDBX_CXX14_CONSTEXPR slice head(size_t n) const noexcept;
895 
898  MDBX_CXX14_CONSTEXPR slice tail(size_t n) const noexcept;
899 
902  MDBX_CXX14_CONSTEXPR slice middle(size_t from, size_t n) const noexcept;
903 
906  MDBX_CXX14_CONSTEXPR slice safe_head(size_t n) const;
907 
910  MDBX_CXX14_CONSTEXPR slice safe_tail(size_t n) const;
911 
914  MDBX_CXX14_CONSTEXPR slice safe_middle(size_t from, size_t n) const;
915 
921  hash_value() const noexcept;
922 
931  compare_fast(const slice &a, const slice &b) noexcept;
932 
939  compare_lexicographically(const slice &a, const slice &b) noexcept;
940  friend MDBX_CXX14_CONSTEXPR bool operator==(const slice &a,
941  const slice &b) noexcept;
942  friend MDBX_CXX14_CONSTEXPR bool operator<(const slice &a,
943  const slice &b) noexcept;
944  friend MDBX_CXX14_CONSTEXPR bool operator>(const slice &a,
945  const slice &b) noexcept;
946  friend MDBX_CXX14_CONSTEXPR bool operator<=(const slice &a,
947  const slice &b) noexcept;
948  friend MDBX_CXX14_CONSTEXPR bool operator>=(const slice &a,
949  const slice &b) noexcept;
950  friend MDBX_CXX14_CONSTEXPR bool operator!=(const slice &a,
951  const slice &b) noexcept;
952 
954  MDBX_CXX11_CONSTEXPR bool is_valid() const noexcept {
955  return !(iov_base == nullptr && iov_len != 0);
956  }
957 
960  MDBX_CXX14_CONSTEXPR static slice invalid() noexcept {
961  return slice(size_t(-1));
962  }
963 
964 protected:
965  MDBX_CXX11_CONSTEXPR slice(size_t invalid_length) noexcept
966  : ::MDBX_val({nullptr, invalid_length}) {}
967 };
968 
969 //------------------------------------------------------------------------------
970 
971 namespace allocation_aware_details {
972 
973 template <typename A> constexpr bool allocator_is_always_equal() noexcept {
974 #if defined(__cpp_lib_allocator_traits_is_always_equal) && \
975  __cpp_lib_allocator_traits_is_always_equal >= 201411L
976  return ::std::allocator_traits<A>::is_always_equal::value;
977 #else
978  return ::std::is_empty<A>::value;
979 #endif /* __cpp_lib_allocator_traits_is_always_equal */
980 }
981 
982 template <typename T, typename A = typename T::allocator_type,
983  bool PoCMA = ::std::allocator_traits<
984  A>::propagate_on_container_move_assignment::value>
986 
987 template <typename T, typename A> struct move_assign_alloc<T, A, false> {
988  static constexpr bool is_nothrow() noexcept {
989  return allocator_is_always_equal<A>();
990  }
991  static MDBX_CXX20_CONSTEXPR bool is_moveable(T *target, T &source) noexcept {
992  return allocator_is_always_equal<A>() ||
993  target->get_allocator() == source.get_allocator();
994  }
995  static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source) noexcept {
996  assert(target->get_allocator() != source.get_allocator());
997  (void)target;
998  (void)source;
999  }
1000 };
1001 
1002 template <typename T, typename A> struct move_assign_alloc<T, A, true> {
1003  static constexpr bool is_nothrow() noexcept {
1004  return allocator_is_always_equal<A>() ||
1005  ::std::is_nothrow_move_assignable<A>::value;
1006  }
1007  static constexpr bool is_moveable(T *, T &) noexcept { return true; }
1008  static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source) {
1009  assert(target->get_allocator() != source.get_allocator());
1010  target->get_allocator() = ::std::move(source.get_allocator());
1011  }
1012 };
1013 
1014 template <typename T, typename A = typename T::allocator_type,
1015  bool PoCCA = ::std::allocator_traits<
1016  A>::propagate_on_container_copy_assignment::value>
1018 
1019 template <typename T, typename A> struct copy_assign_alloc<T, A, false> {
1020  static constexpr bool is_nothrow() noexcept { return false; }
1021  static MDBX_CXX20_CONSTEXPR void propagate(T *target,
1022  const T &source) noexcept {
1023  assert(target->get_allocator() != source.get_allocator());
1024  (void)target;
1025  (void)source;
1026  }
1027 };
1028 
1029 template <typename T, typename A> struct copy_assign_alloc<T, A, true> {
1030  static constexpr bool is_nothrow() noexcept {
1031  return allocator_is_always_equal<A>() ||
1032  ::std::is_nothrow_copy_assignable<A>::value;
1033  }
1034  static MDBX_CXX20_CONSTEXPR void
1035  propagate(T *target, const T &source) noexcept(is_nothrow()) {
1036  if MDBX_IF_CONSTEXPR (!allocator_is_always_equal<A>()) {
1037  if (MDBX_UNLIKELY(target->get_allocator() != source.get_allocator()))
1038  MDBX_CXX20_UNLIKELY target->get_allocator() =
1039  ::std::allocator_traits<A>::select_on_container_copy_construction(
1040  source.get_allocator());
1041  } else {
1042  /* gag for buggy compilers */
1043  (void)target;
1044  (void)source;
1045  }
1046  }
1047 };
1048 
1049 template <typename T, typename A = typename T::allocator_type,
1050  bool PoCS =
1051  ::std::allocator_traits<A>::propagate_on_container_swap::value>
1052 struct swap_alloc;
1053 
1054 template <typename T, typename A> struct swap_alloc<T, A, false> {
1055  static constexpr bool is_nothrow() noexcept {
1056  return allocator_is_always_equal<A>();
1057  }
1058  static MDBX_CXX20_CONSTEXPR void propagate(T *target,
1059  T &source) noexcept(is_nothrow()) {
1060  if MDBX_IF_CONSTEXPR (!allocator_is_always_equal<A>()) {
1061  if (MDBX_UNLIKELY(target->get_allocator() != source.get_allocator()))
1063  } else {
1064  /* gag for buggy compilers */
1065  (void)target;
1066  (void)source;
1067  }
1068  }
1069 };
1070 
1071 template <typename T, typename A> struct swap_alloc<T, A, true> {
1072  static constexpr bool is_nothrow() noexcept {
1073  return allocator_is_always_equal<A>() ||
1074 #if defined(__cpp_lib_is_swappable) && __cpp_lib_is_swappable >= 201603L
1075  ::std::is_nothrow_swappable<A>() ||
1076 #endif /* __cpp_lib_is_swappable >= 201603L */
1077  (::std::is_nothrow_move_constructible<A>::value &&
1078  ::std::is_nothrow_move_assignable<A>::value);
1079  }
1080  static MDBX_CXX20_CONSTEXPR void propagate(T *target,
1081  T &source) noexcept(is_nothrow()) {
1082  if MDBX_IF_CONSTEXPR (!allocator_is_always_equal<A>()) {
1083  if (MDBX_UNLIKELY(target->get_allocator() != source.get_allocator()))
1084  MDBX_CXX20_UNLIKELY ::std::swap(*target, source);
1085  } else {
1086  /* gag for buggy compilers */
1087  (void)target;
1088  (void)source;
1089  }
1090  }
1091 };
1092 
1093 } // namespace allocation_aware_details
1094 
1096  enum : size_t {
1097  extra_inplace_storage = 0,
1098  pettiness_threshold = 64,
1099  max_reserve = 65536
1100  };
1101 
1102  static MDBX_CXX11_CONSTEXPR size_t round(const size_t value) {
1103  static_assert((pettiness_threshold & (pettiness_threshold - 1)) == 0,
1104  "pettiness_threshold must be a power of 2");
1105  static_assert(pettiness_threshold % 2 == 0,
1106  "pettiness_threshold must be even");
1107  static_assert(pettiness_threshold >= sizeof(uint64_t),
1108  "pettiness_threshold must be > 7");
1109  constexpr const auto pettiness_mask = ~size_t(pettiness_threshold - 1);
1110  return (value + pettiness_threshold - 1) & pettiness_mask;
1111  }
1112 
1113  static MDBX_CXX11_CONSTEXPR size_t advise(const size_t current,
1114  const size_t wanna) {
1115  static_assert(max_reserve % pettiness_threshold == 0,
1116  "max_reserve must be a multiple of pettiness_threshold");
1117  static_assert(max_reserve / 3 > pettiness_threshold,
1118  "max_reserve must be > pettiness_threshold * 3");
1119  if (wanna > current)
1120  /* doubling capacity, but don't made reserve more than max_reserve */
1121  return round(wanna + ::std::min(size_t(max_reserve), current));
1122 
1123  if (current - wanna >
1124  /* shrink if reserve will more than half of current or max_reserve,
1125  * but not less than pettiness_threshold */
1126  ::std::min(wanna + pettiness_threshold, size_t(max_reserve)))
1127  return round(wanna);
1128 
1129  /* keep unchanged */
1130  return current;
1131  }
1132 };
1133 
1136  const slice source;
1137  const bool uppercase = false;
1138  const unsigned wrap_width = 0;
1139  MDBX_CXX11_CONSTEXPR to_hex(const slice &source, bool uppercase = false,
1140  unsigned wrap_width = 0) noexcept
1141  : source(source), uppercase(uppercase), wrap_width(wrap_width) {
1143  }
1144 
1146  template <class ALLOCATOR = legacy_allocator>
1147  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1148  return make_string<ALLOCATOR>(*this, allocator);
1149  }
1150 
1152  template <class ALLOCATOR = legacy_allocator,
1153  typename CAPACITY_POLICY = default_capacity_policy>
1155  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1156  return make_buffer<ALLOCATOR>(*this, allocator);
1157  }
1158 
1162  const size_t bytes = source.length() << 1;
1163  return wrap_width ? bytes + bytes / wrap_width : bytes;
1164  }
1165 
1168  char *write_bytes(char *dest, size_t dest_size) const;
1169 
1173  ::std::ostream &output(::std::ostream &out) const;
1174 
1177  bool is_empty() const noexcept { return source.empty(); }
1178 
1181  bool is_erroneous() const noexcept { return false; }
1182 };
1183 
1187  const slice source;
1188  const unsigned wrap_width = 0;
1190  to_base58(const slice &source, unsigned wrap_width = 0) noexcept
1191  : source(source), wrap_width(wrap_width) {
1193  }
1194 
1197  template <class ALLOCATOR = legacy_allocator>
1198  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1199  return make_string<ALLOCATOR>(*this, allocator);
1200  }
1201 
1204  template <class ALLOCATOR = legacy_allocator,
1205  typename CAPACITY_POLICY = default_capacity_policy>
1207  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1208  return make_buffer<ALLOCATOR>(*this, allocator);
1209  }
1210 
1214  const size_t bytes =
1215  source.length() / 8 * 11 + (source.length() % 8 * 43 + 31) / 32;
1216  return wrap_width ? bytes + bytes / wrap_width : bytes;
1217  }
1218 
1222  char *write_bytes(char *dest, size_t dest_size) const;
1223 
1228  ::std::ostream &output(::std::ostream &out) const;
1229 
1232  bool is_empty() const noexcept { return source.empty(); }
1233 
1236  bool is_erroneous() const noexcept { return false; }
1237 };
1238 
1242  const slice source;
1243  const unsigned wrap_width = 0;
1245  to_base64(const slice &source, unsigned wrap_width = 0) noexcept
1246  : source(source), wrap_width(wrap_width) {
1248  }
1249 
1252  template <class ALLOCATOR = legacy_allocator>
1253  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1254  return make_string<ALLOCATOR>(*this, allocator);
1255  }
1256 
1259  template <class ALLOCATOR = legacy_allocator,
1260  typename CAPACITY_POLICY = default_capacity_policy>
1262  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1263  return make_buffer<ALLOCATOR>(*this, allocator);
1264  }
1265 
1269  const size_t bytes = (source.length() + 2) / 3 * 4;
1270  return wrap_width ? bytes + bytes / wrap_width : bytes;
1271  }
1272 
1276  char *write_bytes(char *dest, size_t dest_size) const;
1277 
1282  ::std::ostream &output(::std::ostream &out) const;
1283 
1286  bool is_empty() const noexcept { return source.empty(); }
1287 
1290  bool is_erroneous() const noexcept { return false; }
1291 };
1292 
1293 inline ::std::ostream &operator<<(::std::ostream &out, const to_hex &wrapper) {
1294  return wrapper.output(out);
1295 }
1296 inline ::std::ostream &operator<<(::std::ostream &out,
1297  const to_base58 &wrapper) {
1298  return wrapper.output(out);
1299 }
1300 inline ::std::ostream &operator<<(::std::ostream &out,
1301  const to_base64 &wrapper) {
1302  return wrapper.output(out);
1303 }
1304 
1307  const slice source;
1308  const bool ignore_spaces = false;
1310  bool ignore_spaces = false) noexcept
1311  : source(source), ignore_spaces(ignore_spaces) {
1313  }
1314 
1316  template <class ALLOCATOR = legacy_allocator>
1317  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1318  return make_string<ALLOCATOR>(*this, allocator);
1319  }
1320 
1322  template <class ALLOCATOR = legacy_allocator,
1323  typename CAPACITY_POLICY = default_capacity_policy>
1325  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1326  return make_buffer<ALLOCATOR>(*this, allocator);
1327  }
1328 
1332  return source.length() >> 1;
1333  }
1334 
1338  char *write_bytes(char *dest, size_t dest_size) const;
1339 
1342  bool is_empty() const noexcept { return source.empty(); }
1343 
1346  bool is_erroneous() const noexcept;
1347 };
1348 
1352  const slice source;
1353  const bool ignore_spaces = false;
1355  bool ignore_spaces = false) noexcept
1356  : source(source), ignore_spaces(ignore_spaces) {
1358  }
1359 
1362  template <class ALLOCATOR = legacy_allocator>
1363  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1364  return make_string<ALLOCATOR>(*this, allocator);
1365  }
1366 
1369  template <class ALLOCATOR = legacy_allocator,
1370  typename CAPACITY_POLICY = default_capacity_policy>
1372  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1373  return make_buffer<ALLOCATOR>(*this, allocator);
1374  }
1375 
1380  return source.length() / 11 * 8 + source.length() % 11 * 32 / 43;
1381  }
1382 
1386  char *write_bytes(char *dest, size_t dest_size) const;
1387 
1390  bool is_empty() const noexcept { return source.empty(); }
1391 
1395  bool is_erroneous() const noexcept;
1396 };
1397 
1401  const slice source;
1402  const bool ignore_spaces = false;
1404  bool ignore_spaces = false) noexcept
1405  : source(source), ignore_spaces(ignore_spaces) {
1407  }
1408 
1411  template <class ALLOCATOR = legacy_allocator>
1412  string<ALLOCATOR> as_string(const ALLOCATOR &allocator = ALLOCATOR()) const {
1413  return make_string<ALLOCATOR>(*this, allocator);
1414  }
1415 
1418  template <class ALLOCATOR = legacy_allocator,
1419  typename CAPACITY_POLICY = default_capacity_policy>
1421  as_buffer(const ALLOCATOR &allocator = ALLOCATOR()) const {
1422  return make_buffer<ALLOCATOR>(*this, allocator);
1423  }
1424 
1429  return (source.length() + 3) / 4 * 3;
1430  }
1431 
1435  char *write_bytes(char *dest, size_t dest_size) const;
1436 
1439  bool is_empty() const noexcept { return source.empty(); }
1440 
1444  bool is_erroneous() const noexcept;
1445 };
1446 
1448 template <class ALLOCATOR, typename CAPACITY_POLICY> class buffer {
1449 public:
1450 #if !defined(_MSC_VER) || _MSC_VER > 1900
1451  using allocator_type = typename ::std::allocator_traits<
1452  ALLOCATOR>::template rebind_alloc<uint64_t>;
1453 #else
1454  using allocator_type = typename ALLOCATOR::template rebind<uint64_t>::other;
1455 #endif /* MSVC is mad */
1456  using allocator_traits = ::std::allocator_traits<allocator_type>;
1457  using reservation_policy = CAPACITY_POLICY;
1458  enum : size_t {
1459  max_length = MDBX_MAXDATASIZE,
1460  max_capacity = (max_length / 3u * 4u + 1023u) & ~size_t(1023),
1461  extra_inplace_storage = reservation_policy::extra_inplace_storage,
1462  pettiness_threshold = reservation_policy::pettiness_threshold
1463  };
1464 
1465 private:
1466  friend class txn;
1467  struct silo;
1468  using move_assign_alloc =
1470  using copy_assign_alloc =
1473  struct silo /* Empty Base Class Optimization */ : public allocator_type {
1474  MDBX_CXX20_CONSTEXPR const allocator_type &get_allocator() const noexcept {
1475  return *this;
1476  }
1477  MDBX_CXX20_CONSTEXPR allocator_type &get_allocator() noexcept {
1478  return *this;
1479  }
1480 
1481  using allocator_pointer = typename allocator_traits::pointer;
1482  using allocator_const_pointer = typename allocator_traits::const_pointer;
1483 
1484  MDBX_CXX20_CONSTEXPR ::std::pair<allocator_pointer, size_t>
1485  allocate_storage(size_t bytes) {
1486  assert(bytes >= sizeof(bin));
1487  constexpr size_t unit = sizeof(typename allocator_type::value_type);
1488  static_assert((unit & (unit - 1)) == 0,
1489  "size of ALLOCATOR::value_type should be a power of 2");
1490  static_assert(unit > 0, "size of ALLOCATOR::value_type must be > 0");
1491  const size_t n = (bytes + unit - 1) / unit;
1492  return ::std::make_pair(allocator_traits::allocate(get_allocator(), n),
1493  n * unit);
1494  }
1495  MDBX_CXX20_CONSTEXPR void deallocate_storage(allocator_pointer ptr,
1496  size_t bytes) {
1497  constexpr size_t unit = sizeof(typename allocator_type::value_type);
1498  assert(ptr && bytes >= sizeof(bin) && bytes >= unit && bytes % unit == 0);
1499  allocator_traits::deallocate(get_allocator(), ptr, bytes / unit);
1500  }
1501 
1502  static MDBX_CXX17_CONSTEXPR void *
1503  to_address(allocator_pointer ptr) noexcept {
1504 #if defined(__cpp_lib_to_address) && __cpp_lib_to_address >= 201711L
1505  return static_cast<void *>(::std::to_address(ptr));
1506 #else
1507  return static_cast<void *>(::std::addressof(*ptr));
1508 #endif /* __cpp_lib_to_address */
1509  }
1510  static MDBX_CXX17_CONSTEXPR const void *
1511  to_address(allocator_const_pointer ptr) noexcept {
1512 #if defined(__cpp_lib_to_address) && __cpp_lib_to_address >= 201711L
1513  return static_cast<const void *>(::std::to_address(ptr));
1514 #else
1515  return static_cast<const void *>(::std::addressof(*ptr));
1516 #endif /* __cpp_lib_to_address */
1517  }
1518 
1519  union bin {
1520  struct allocated {
1521  allocator_pointer ptr_;
1523  constexpr allocated(allocator_pointer ptr, size_t bytes) noexcept
1524  : ptr_(ptr), capacity_bytes_(bytes) {}
1525  constexpr allocated(const allocated &) noexcept = default;
1526  constexpr allocated(allocated &&) noexcept = default;
1528  operator=(const allocated &) noexcept = default;
1530  operator=(allocated &&) noexcept = default;
1531  };
1532 
1533  allocated allocated_;
1534  uint64_t align_hint_;
1535  byte inplace_[(sizeof(allocated) + extra_inplace_storage + 7u) &
1536  ~size_t(7)];
1537 
1538  static constexpr bool
1539  is_suitable_for_inplace(size_t capacity_bytes) noexcept {
1540  static_assert(sizeof(bin) == sizeof(inplace_), "WTF?");
1541  return capacity_bytes < sizeof(bin);
1542  }
1543 
1544  enum : byte {
1545  /* Little Endian:
1546  * last byte is the most significant byte of u_.allocated.cap,
1547  * so use higher bit of capacity as the inplace-flag */
1548  le_lastbyte_mask = 0x80,
1549  /* Big Endian:
1550  * last byte is the least significant byte of u_.allocated.cap,
1551  * so use lower bit of capacity as the inplace-flag. */
1552  be_lastbyte_mask = 0x01
1553  };
1554 
1555  static constexpr byte inplace_lastbyte_mask() noexcept {
1556  static_assert(
1557  endian::native == endian::little || endian::native == endian::big,
1558  "Only the little-endian or big-endian bytes order are supported");
1559  return (endian::native == endian::little) ? le_lastbyte_mask
1560  : be_lastbyte_mask;
1561  }
1562  constexpr byte lastbyte() const noexcept {
1563  return inplace_[sizeof(bin) - 1];
1564  }
1565  MDBX_CXX17_CONSTEXPR byte &lastbyte() noexcept {
1566  return inplace_[sizeof(bin) - 1];
1567  }
1568 
1569  constexpr bool is_inplace() const noexcept {
1570  return (lastbyte() & inplace_lastbyte_mask()) != 0;
1571  }
1572  constexpr bool is_allocated() const noexcept { return !is_inplace(); }
1573 
1574  template <bool destroy_ptr>
1576  if (destroy_ptr) {
1577  MDBX_CONSTEXPR_ASSERT(is_allocated());
1578  /* properly destroy allocator::pointer */
1579  allocated_.~allocated();
1580  }
1581  if (::std::is_trivial<allocator_pointer>::value)
1582  /* workaround for "uninitialized" warning from some compilers */
1583  ::std::memset(&allocated_.ptr_, 0, sizeof(allocated_.ptr_));
1584  lastbyte() = inplace_lastbyte_mask();
1585  MDBX_CONSTEXPR_ASSERT(is_inplace() && address() == inplace_ &&
1586  is_suitable_for_inplace(capacity()));
1587  return address();
1588  }
1589 
1590  template <bool construct_ptr>
1591  MDBX_CXX17_CONSTEXPR byte *
1592  make_allocated(allocator_pointer ptr, size_t capacity_bytes) noexcept {
1594  (capacity_bytes & be_lastbyte_mask) == 0 &&
1595  ((capacity_bytes >>
1596  (sizeof(allocated_.capacity_bytes_) - 1) * CHAR_BIT) &
1597  le_lastbyte_mask) == 0);
1598  if (construct_ptr)
1599  /* properly construct allocator::pointer */
1600  new (&allocated_) allocated(ptr, capacity_bytes);
1601  else {
1602  MDBX_CONSTEXPR_ASSERT(is_allocated());
1603  allocated_.ptr_ = ptr;
1604  allocated_.capacity_bytes_ = capacity_bytes;
1605  }
1606  MDBX_CONSTEXPR_ASSERT(is_allocated() && address() == to_address(ptr) &&
1607  capacity() == capacity_bytes);
1608  return address();
1609  }
1610 
1611  MDBX_CXX20_CONSTEXPR bin(size_t capacity_bytes = 0) noexcept {
1612  MDBX_CONSTEXPR_ASSERT(is_suitable_for_inplace(capacity_bytes));
1613  make_inplace<false>();
1614  (void)capacity_bytes;
1615  }
1616  MDBX_CXX20_CONSTEXPR bin(allocator_pointer ptr,
1617  size_t capacity_bytes) noexcept {
1618  MDBX_CONSTEXPR_ASSERT(!is_suitable_for_inplace(capacity_bytes));
1619  make_allocated<true>(ptr, capacity_bytes);
1620  }
1622  if (is_allocated())
1623  /* properly destroy allocator::pointer */
1624  allocated_.~allocated();
1625  }
1626  MDBX_CXX20_CONSTEXPR bin(bin &&ditto) noexcept {
1627  if (ditto.is_inplace()) {
1628  // micro-optimization: don't use make_inplace<> here
1629  // since memcpy() will copy the flag.
1630  memcpy(inplace_, ditto.inplace_, sizeof(inplace_));
1631  MDBX_CONSTEXPR_ASSERT(is_inplace());
1632  } else {
1633  new (&allocated_) allocated(::std::move(ditto.allocated_));
1634  ditto.make_inplace<true>();
1635  MDBX_CONSTEXPR_ASSERT(is_allocated());
1636  }
1637  }
1638 
1639  MDBX_CXX17_CONSTEXPR bin &operator=(const bin &ditto) noexcept {
1640  if (ditto.is_inplace()) {
1641  // micro-optimization: don't use make_inplace<> here
1642  // since memcpy() will copy the flag.
1643  if (is_allocated())
1644  /* properly destroy allocator::pointer */
1645  allocated_.~allocated();
1646  memcpy(inplace_, ditto.inplace_, sizeof(inplace_));
1647  MDBX_CONSTEXPR_ASSERT(is_inplace());
1648  } else if (is_inplace())
1649  make_allocated<true>(ditto.allocated_.ptr_,
1650  ditto.allocated_.capacity_bytes_);
1651  else
1652  make_allocated<false>(ditto.allocated_.ptr_,
1653  ditto.allocated_.capacity_bytes_);
1654  return *this;
1655  }
1656 
1657  MDBX_CXX17_CONSTEXPR bin &operator=(bin &&ditto) noexcept {
1658  operator=(const_cast<const bin &>(ditto));
1659  if (ditto.is_allocated())
1660  ditto.make_inplace<true>();
1661  return *this;
1662  }
1663 
1664  static MDBX_CXX20_CONSTEXPR size_t advise_capacity(const size_t current,
1665  const size_t wanna) {
1666  if (MDBX_UNLIKELY(wanna > max_capacity))
1668 
1669  const size_t advised = reservation_policy::advise(current, wanna);
1670  assert(advised >= wanna);
1671  return ::std::min(size_t(max_capacity),
1672  ::std::max(sizeof(bin) - 1, advised));
1673  }
1674 
1675  constexpr const byte *address() const noexcept {
1676  return is_inplace()
1677  ? inplace_
1678  : static_cast<const byte *>(to_address(allocated_.ptr_));
1679  }
1680  MDBX_CXX17_CONSTEXPR byte *address() noexcept {
1681  return is_inplace() ? inplace_
1682  : static_cast<byte *>(to_address(allocated_.ptr_));
1683  }
1684  constexpr size_t capacity() const noexcept {
1685  return is_inplace() ? sizeof(bin) - 1 : allocated_.capacity_bytes_;
1686  }
1687  } bin_;
1688 
1689  MDBX_CXX20_CONSTEXPR void *init(size_t capacity) {
1690  capacity = bin::advise_capacity(0, capacity);
1691  if (bin_.is_suitable_for_inplace(capacity))
1692  new (&bin_) bin();
1693  else {
1694  const auto pair = allocate_storage(capacity);
1695  assert(pair.second >= capacity);
1696  new (&bin_) bin(pair.first, pair.second);
1697  }
1698  return bin_.address();
1699  }
1700 
1701  MDBX_CXX20_CONSTEXPR void release() noexcept {
1702  if (bin_.is_allocated()) {
1703  deallocate_storage(bin_.allocated_.ptr_,
1704  bin_.allocated_.capacity_bytes_);
1705  bin_.template make_inplace<true>();
1706  }
1707  }
1708 
1709  template <bool external_content>
1710  MDBX_CXX20_CONSTEXPR void *
1711  reshape(const size_t wanna_capacity, const size_t wanna_headroom,
1712  const void *const content, const size_t length) {
1713  assert(wanna_capacity >= wanna_headroom + length);
1714  const size_t old_capacity = bin_.capacity();
1715  const size_t new_capacity =
1716  bin::advise_capacity(old_capacity, wanna_capacity);
1717  assert(new_capacity >= wanna_capacity);
1718  if (MDBX_LIKELY(new_capacity == old_capacity))
1720  assert(bin_.is_inplace() ==
1721  bin::is_suitable_for_inplace(new_capacity));
1722  byte *const new_place = bin_.address() + wanna_headroom;
1723  if (MDBX_LIKELY(length))
1725  if (external_content)
1726  memcpy(new_place, content, length);
1727  else {
1728  const size_t old_headroom =
1729  bin_.address() - static_cast<const byte *>(content);
1730  assert(old_capacity >= old_headroom + length);
1731  if (MDBX_UNLIKELY(old_headroom != wanna_headroom))
1732  MDBX_CXX20_UNLIKELY ::std::memmove(new_place, content,
1733  length);
1734  }
1735  }
1736  return new_place;
1737  }
1738 
1739  if (bin::is_suitable_for_inplace(new_capacity)) {
1740  assert(bin_.is_allocated());
1741  const auto old_allocated = ::std::move(bin_.allocated_.ptr_);
1742  byte *const new_place =
1743  bin_.template make_inplace<true>() + wanna_headroom;
1744  if (MDBX_LIKELY(length))
1745  MDBX_CXX20_LIKELY memcpy(new_place, content, length);
1746  deallocate_storage(old_allocated, old_capacity);
1747  return new_place;
1748  }
1749 
1750  if (!bin_.is_allocated()) {
1751  const auto pair = allocate_storage(new_capacity);
1752  assert(pair.second >= new_capacity);
1753  byte *const new_place =
1754  static_cast<byte *>(to_address(pair.first)) + wanna_headroom;
1755  if (MDBX_LIKELY(length))
1756  MDBX_CXX20_LIKELY memcpy(new_place, content, length);
1757  bin_.template make_allocated<true>(pair.first, pair.second);
1758  return new_place;
1759  }
1760 
1761  const auto old_allocated = ::std::move(bin_.allocated_.ptr_);
1762  if (external_content)
1763  deallocate_storage(old_allocated, old_capacity);
1764  const auto pair = allocate_storage(new_capacity);
1765  assert(pair.second >= new_capacity);
1766  byte *const new_place =
1767  bin_.template make_allocated<false>(pair.first, pair.second) +
1768  wanna_headroom;
1769  if (MDBX_LIKELY(length))
1770  MDBX_CXX20_LIKELY memcpy(new_place, content, length);
1771  if (!external_content)
1772  deallocate_storage(old_allocated, old_capacity);
1773  return new_place;
1774  }
1775 
1776  MDBX_CXX20_CONSTEXPR const byte *get(size_t offset = 0) const noexcept {
1777  assert(capacity() >= offset);
1778  return bin_.address() + offset;
1779  }
1780  MDBX_CXX20_CONSTEXPR byte *get(size_t offset = 0) noexcept {
1781  assert(capacity() >= offset);
1782  return bin_.address() + offset;
1783  }
1784  MDBX_CXX20_CONSTEXPR byte *put(size_t offset, const void *ptr,
1785  size_t length) {
1786  assert(capacity() >= offset + length);
1787  return static_cast<byte *>(memcpy(get(offset), ptr, length));
1788  }
1789 
1790  //--------------------------------------------------------------------------
1791 
1793  silo() noexcept : allocator_type() { init(0); }
1795  silo(const allocator_type &alloc) noexcept : allocator_type(alloc) {
1796  init(0);
1797  }
1798  MDBX_CXX20_CONSTEXPR silo(size_t capacity) { init(capacity); }
1799  MDBX_CXX20_CONSTEXPR silo(size_t capacity, const allocator_type &alloc)
1800  : silo(alloc) {
1801  init(capacity);
1802  }
1803 
1804  MDBX_CXX20_CONSTEXPR silo(silo &&ditto) noexcept(
1805  ::std::is_nothrow_move_constructible<allocator_type>::value)
1806  : allocator_type(::std::move(ditto.get_allocator())),
1807  bin_(::std::move(ditto.bin_)) {}
1808 
1809  MDBX_CXX20_CONSTEXPR silo(size_t capacity, size_t headroom, const void *ptr,
1810  size_t length)
1811  : silo(capacity) {
1812  assert(capacity >= headroom + length);
1813  if (length)
1814  put(headroom, ptr, length);
1815  }
1816 
1817  // select_on_container_copy_construction()
1818  MDBX_CXX20_CONSTEXPR silo(size_t capacity, size_t headroom, const void *ptr,
1819  size_t length, const allocator_type &alloc)
1820  : silo(capacity, alloc) {
1821  assert(capacity >= headroom + length);
1822  if (length)
1823  put(headroom, ptr, length);
1824  }
1825 
1826  MDBX_CXX20_CONSTEXPR silo(const void *ptr, size_t length)
1827  : silo(length, 0, ptr, length) {}
1828  MDBX_CXX20_CONSTEXPR silo(const void *ptr, size_t length,
1829  const allocator_type &alloc)
1830  : silo(length, 0, ptr, length, alloc) {}
1831 
1832  ~silo() { release(); }
1833 
1834  //--------------------------------------------------------------------------
1835 
1836  MDBX_CXX20_CONSTEXPR void *assign(size_t headroom, const void *ptr,
1837  size_t length, size_t tailroom) {
1838  return reshape<true>(headroom + length + tailroom, headroom, ptr, length);
1839  }
1840  MDBX_CXX20_CONSTEXPR void *assign(const void *ptr, size_t length) {
1841  return assign(0, ptr, length, 0);
1842  }
1843 
1844  MDBX_CXX20_CONSTEXPR silo &assign(const silo &ditto, size_t headroom,
1845  slice &content) {
1846  assert(ditto.get() + headroom == content.byte_ptr());
1847  if MDBX_IF_CONSTEXPR (!allocation_aware_details::
1848  allocator_is_always_equal<allocator_type>()) {
1849  if (MDBX_UNLIKELY(get_allocator() != ditto.get_allocator()))
1851  release();
1852  allocation_aware_details::copy_assign_alloc<
1853  silo, allocator_type>::propagate(this, ditto);
1854  }
1855  }
1856  content.iov_base = reshape<true>(ditto.capacity(), headroom,
1857  content.data(), content.length());
1858  return *this;
1859  }
1860 
1861  MDBX_CXX20_CONSTEXPR silo &
1862  assign(silo &&ditto, size_t headroom, slice &content) noexcept(
1863  allocation_aware_details::move_assign_alloc<
1864  silo, allocator_type>::is_nothrow()) {
1865  assert(ditto.get() + headroom == content.byte_ptr());
1866  if (allocation_aware_details::move_assign_alloc<
1867  silo, allocator_type>::is_moveable(this, ditto)) {
1868  release();
1869  allocation_aware_details::move_assign_alloc<
1870  silo, allocator_type>::propagate(this, ditto);
1871  /* no reallocation nor copying required */
1872  bin_ = ::std::move(ditto.bin_);
1873  assert(get() + headroom == content.byte_ptr());
1874  } else {
1875  /* copy content since allocators are different */
1876  content.iov_base = reshape<true>(ditto.capacity(), headroom,
1877  content.data(), content.length());
1878  ditto.release();
1879  }
1880  return *this;
1881  }
1882 
1883  MDBX_CXX20_CONSTEXPR void clear() { reshape<true>(0, 0, nullptr, 0); }
1884  MDBX_CXX20_CONSTEXPR void resize(size_t capacity, size_t headroom,
1885  slice &content) {
1886  content.iov_base =
1887  reshape<false>(capacity, headroom, content.iov_base, content.iov_len);
1888  }
1889  MDBX_CXX20_CONSTEXPR void swap(silo &ditto) noexcept(
1890  allocation_aware_details::swap_alloc<silo,
1891  allocator_type>::is_nothrow()) {
1892  allocation_aware_details::swap_alloc<silo, allocator_type>::propagate(
1893  this, ditto);
1894  ::std::swap(bin_, ditto.bin_);
1895  }
1896 
1897  /* MDBX_CXX20_CONSTEXPR void shrink_to_fit() { TODO } */
1898 
1900  capacity() const noexcept {
1901  return bin_.capacity();
1902  }
1904  data(size_t offset = 0) const noexcept {
1905  return get(offset);
1906  }
1908  data(size_t offset = 0) noexcept {
1909  return get(offset);
1910  }
1911  };
1912 
1913  silo silo_;
1914  ::mdbx::slice slice_;
1915 
1916  void insulate() {
1917  assert(is_reference());
1918  silo_.assign(slice_.char_ptr(), slice_.length());
1919  slice_.iov_base = silo_.data();
1920  }
1921 
1923  silo_begin() const noexcept {
1924  return static_cast<const byte *>(silo_.data());
1925  }
1926 
1928  silo_end() const noexcept {
1929  return silo_begin() + silo_.capacity();
1930  }
1931 
1932  struct data_preserver : public exception_thunk {
1933  buffer data;
1934  data_preserver(allocator_type &allocator) : data(allocator) {}
1935  static int callback(void *context, MDBX_val *target, const void *src,
1936  size_t bytes) noexcept {
1937  auto self = static_cast<data_preserver *>(context);
1938  assert(self->is_clean());
1939  assert(&self->data.slice_ == target);
1940  (void)target;
1941  try {
1942  self->data.assign(src, bytes, false);
1943  return MDBX_RESULT_FALSE;
1944  } catch (... /* capture any exception to rethrow it over C code */) {
1945  self->capture();
1946  return MDBX_RESULT_TRUE;
1947  }
1948  }
1949  MDBX_CXX11_CONSTEXPR operator MDBX_preserve_func() const noexcept {
1950  return callback;
1951  }
1952  MDBX_CXX11_CONSTEXPR operator const buffer &() const noexcept {
1953  return data;
1954  }
1955  MDBX_CXX11_CONSTEXPR operator buffer &() noexcept { return data; }
1956  };
1957 
1958 public:
1962 
1965  return silo_.get_allocator();
1966  }
1967 
1971  is_freestanding() const noexcept {
1972  static_assert(size_t(-long(max_length)) > max_length, "WTF?");
1973  return size_t(byte_ptr() - silo_begin()) < silo_.capacity();
1974  }
1975 
1979  is_reference() const noexcept {
1980  return !is_freestanding();
1981  }
1982 
1986  capacity() const noexcept {
1987  return is_freestanding() ? silo_.capacity() : 0;
1988  }
1989 
1993  headroom() const noexcept {
1994  return is_freestanding() ? slice_.byte_ptr() - silo_begin() : 0;
1995  }
1996 
2000  tailroom() const noexcept {
2001  return is_freestanding() ? capacity() - headroom() - slice_.length() : 0;
2002  }
2003 
2005  MDBX_CXX11_CONSTEXPR const byte *byte_ptr() const noexcept {
2006  return slice_.byte_ptr();
2007  }
2008 
2010  MDBX_CXX11_CONSTEXPR const byte *end_byte_ptr() const noexcept {
2011  return slice_.end_byte_ptr();
2012  }
2013 
2017  MDBX_CXX11_CONSTEXPR byte *byte_ptr() noexcept {
2018  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2019  return const_cast<byte *>(slice_.byte_ptr());
2020  }
2021 
2026  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2027  return const_cast<byte *>(slice_.end_byte_ptr());
2028  }
2029 
2031  MDBX_CXX11_CONSTEXPR const char *char_ptr() const noexcept {
2032  return slice_.char_ptr();
2033  }
2034 
2036  MDBX_CXX11_CONSTEXPR const char *end_char_ptr() const noexcept {
2037  return slice_.end_char_ptr();
2038  }
2039 
2043  MDBX_CXX11_CONSTEXPR char *char_ptr() noexcept {
2044  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2045  return const_cast<char *>(slice_.char_ptr());
2046  }
2047 
2052  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2053  return const_cast<char *>(slice_.end_char_ptr());
2054  }
2055 
2057  MDBX_CXX11_CONSTEXPR const void *data() const noexcept {
2058  return slice_.data();
2059  }
2060 
2062  MDBX_CXX11_CONSTEXPR const void *end() const noexcept { return slice_.end(); }
2063 
2067  MDBX_CXX11_CONSTEXPR void *data() noexcept {
2068  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2069  return const_cast<void *>(slice_.data());
2070  }
2071 
2075  MDBX_CXX11_CONSTEXPR void *end() noexcept {
2076  MDBX_CONSTEXPR_ASSERT(is_freestanding());
2077  return const_cast<void *>(slice_.end());
2078  }
2079 
2082  length() const noexcept {
2083  return MDBX_CONSTEXPR_ASSERT(is_reference() ||
2084  slice_.length() + headroom() <=
2085  silo_.capacity()),
2086  slice_.length();
2087  }
2088 
2091  MDBX_CONSTEXPR_ASSERT(is_reference() ||
2092  bytes + headroom() <= silo_.capacity());
2093  slice_.set_length(bytes);
2094  return *this;
2095  }
2096 
2099  MDBX_CONSTEXPR_ASSERT(static_cast<const char *>(ptr) >= char_ptr());
2100  return set_length(static_cast<const char *>(ptr) - char_ptr());
2101  }
2102 
2107  if (is_reference())
2108  insulate();
2109  }
2110 
2111  MDBX_CXX20_CONSTEXPR buffer() noexcept = default;
2112  MDBX_CXX20_CONSTEXPR buffer(const allocator_type &allocator) noexcept
2113  : silo_(allocator) {}
2114 
2115  buffer(const struct slice &src, bool make_reference,
2116  const allocator_type &allocator = allocator_type())
2117  : silo_(allocator), slice_(src) {
2118  if (!make_reference)
2119  insulate();
2120  }
2121 
2122  buffer(const buffer &src, bool make_reference,
2123  const allocator_type &allocator = allocator_type())
2124  : buffer(src.slice_, make_reference, allocator) {}
2125 
2126  buffer(const void *ptr, size_t bytes, bool make_reference,
2127  const allocator_type &allocator = allocator_type())
2128  : buffer(::mdbx::slice(ptr, bytes), make_reference, allocator) {}
2129 
2130  template <class CHAR, class T, class A>
2131  buffer(const ::std::basic_string<CHAR, T, A> &) = delete;
2132  template <class CHAR, class T, class A>
2133  buffer(const ::std::basic_string<CHAR, T, A> &&) = delete;
2134 
2135  buffer(const char *c_str, bool make_reference,
2136  const allocator_type &allocator = allocator_type())
2137  : buffer(::mdbx::slice(c_str), make_reference, allocator) {}
2138 
2139 #if defined(DOXYGEN) || \
2140  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
2141  template <class CHAR, class T>
2142  buffer(const ::std::basic_string_view<CHAR, T> &view, bool make_reference,
2143  const allocator_type &allocator = allocator_type())
2144  : buffer(::mdbx::slice(view), make_reference, allocator) {}
2145 #endif /* __cpp_lib_string_view >= 201606L */
2146 
2148  buffer(const struct slice &src,
2149  const allocator_type &allocator = allocator_type())
2150  : silo_(src.data(), src.length(), allocator),
2151  slice_(silo_.data(), src.length()) {}
2152 
2154  buffer(const buffer &src, const allocator_type &allocator = allocator_type())
2155  : buffer(src.slice_, allocator) {}
2156 
2158  buffer(const void *ptr, size_t bytes,
2159  const allocator_type &allocator = allocator_type())
2160  : buffer(::mdbx::slice(ptr, bytes), allocator) {}
2161 
2162  template <class CHAR, class T, class A>
2164  buffer(const ::std::basic_string<CHAR, T, A> &str,
2165  const allocator_type &allocator = allocator_type())
2166  : buffer(::mdbx::slice(str), allocator) {}
2167 
2169  buffer(const char *c_str, const allocator_type &allocator = allocator_type())
2170  : buffer(::mdbx::slice(c_str), allocator) {}
2171 
2172 #if defined(DOXYGEN) || \
2173  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
2174  template <class CHAR, class T>
2176  buffer(const ::std::basic_string_view<CHAR, T> &view,
2177  const allocator_type &allocator = allocator_type())
2178  : buffer(::mdbx::slice(view), allocator) {}
2179 #endif /* __cpp_lib_string_view >= 201606L */
2180 
2181  buffer(size_t head_room, size_t tail_room,
2182  const allocator_type &allocator = allocator_type())
2183  : silo_(allocator) {
2184  slice_.iov_base = silo_.init(check_length(head_room, tail_room));
2185  assert(slice_.iov_len == 0);
2186  }
2187 
2188  buffer(size_t capacity, const allocator_type &allocator = allocator_type())
2189  : silo_(allocator) {
2190  slice_.iov_base = silo_.init(check_length(capacity));
2191  assert(slice_.iov_len == 0);
2192  }
2193 
2194  buffer(size_t head_room, const struct slice &src, size_t tail_room,
2195  const allocator_type &allocator = allocator_type())
2196  : silo_(allocator) {
2197  slice_.iov_base =
2198  silo_.init(check_length(head_room, src.length(), tail_room));
2199  slice_.iov_len = src.length();
2200  memcpy(slice_.iov_base, src.data(), src.length());
2201  }
2202 
2203  buffer(size_t head_room, const buffer &src, size_t tail_room,
2204  const allocator_type &allocator = allocator_type())
2205  : buffer(head_room, src.slice_, tail_room, allocator) {}
2206 
2207  inline buffer(const ::mdbx::txn &txn, const struct slice &src,
2208  const allocator_type &allocator = allocator_type());
2209 
2210  buffer(buffer &&src) noexcept(move_assign_alloc::is_nothrow())
2211  : silo_(::std::move(src.silo_)), slice_(::std::move(src.slice_)) {}
2212 
2213  MDBX_CXX11_CONSTEXPR const struct slice &slice() const noexcept {
2214  return slice_;
2215  }
2216 
2217  MDBX_CXX11_CONSTEXPR operator const struct slice &() const noexcept {
2218  return slice_;
2219  }
2220 
2221  template <typename POD>
2222  static buffer wrap(const POD &pod, bool make_reference = false,
2223  const allocator_type &allocator = allocator_type()) {
2224  return buffer(::mdbx::slice::wrap(pod), make_reference, allocator);
2225  }
2226 
2228  void reserve(size_t wanna_headroom, size_t wanna_tailroom) {
2229  wanna_headroom = ::std::min(::std::max(headroom(), wanna_headroom),
2230  wanna_headroom + pettiness_threshold);
2231  wanna_tailroom = ::std::min(::std::max(tailroom(), wanna_tailroom),
2232  wanna_tailroom + pettiness_threshold);
2233  const size_t wanna_capacity =
2234  check_length(wanna_headroom, slice_.length(), wanna_tailroom);
2235  silo_.resize(wanna_capacity, wanna_headroom, slice_);
2236  assert(headroom() >= wanna_headroom &&
2237  headroom() <= wanna_headroom + pettiness_threshold);
2238  assert(tailroom() >= wanna_tailroom &&
2239  tailroom() <= wanna_tailroom + pettiness_threshold);
2240  }
2241 
2243  void reserve_headroom(size_t wanna_headroom) { reserve(wanna_headroom, 0); }
2244 
2246  void reserve_tailroom(size_t wanna_tailroom) { reserve(0, wanna_tailroom); }
2247 
2248  buffer &assign_reference(const void *ptr, size_t bytes) {
2249  silo_.clear();
2250  slice_.assign(ptr, bytes);
2251  return *this;
2252  }
2253 
2254  buffer &assign_freestanding(const void *ptr, size_t bytes) {
2255  silo_.assign(static_cast<const typename silo::value_type *>(ptr),
2256  check_length(bytes));
2257  slice_.assign(silo_.data(), bytes);
2258  return *this;
2259  }
2260 
2262  swap(buffer &other) noexcept(swap_alloc::is_nothrow()) {
2263  silo_.swap(other.silo_);
2264  slice_.swap(other.slice_);
2265  }
2266 
2267  static buffer clone(const buffer &src,
2268  const allocator_type &allocator = allocator_type()) {
2269  return buffer(src.headroom(), src.slice_, src.tailroom(), allocator);
2270  }
2271 
2272  buffer &assign(const buffer &src, bool make_reference = false) {
2273  return assign(src.slice_, make_reference);
2274  }
2275 
2276  buffer &assign(const void *ptr, size_t bytes, bool make_reference = false) {
2277  return make_reference ? assign_reference(ptr, bytes)
2278  : assign_freestanding(ptr, bytes);
2279  }
2280 
2281  buffer &assign(const struct slice &src, bool make_reference = false) {
2282  return assign(src.data(), src.length(), make_reference);
2283  }
2284 
2285  buffer &assign(const ::MDBX_val &src, bool make_reference = false) {
2286  return assign(src.iov_base, src.iov_len, make_reference);
2287  }
2288 
2289  buffer &assign(struct slice &&src, bool make_reference = false) {
2290  assign(src.data(), src.length(), make_reference);
2291  src.invalidate();
2292  return *this;
2293  }
2294 
2295  buffer &assign(::MDBX_val &&src, bool make_reference = false) {
2296  assign(src.iov_base, src.iov_len, make_reference);
2297  src.iov_base = nullptr;
2298  return *this;
2299  }
2300 
2301  buffer &assign(const void *begin, const void *end,
2302  bool make_reference = false) {
2303  return assign(begin,
2304  static_cast<const byte *>(end) -
2305  static_cast<const byte *>(begin),
2306  make_reference);
2307  }
2308 
2309  template <class CHAR, class T, class A>
2310  buffer &assign(const ::std::basic_string<CHAR, T, A> &str,
2311  bool make_reference = false) {
2312  return assign(str.data(), str.length(), make_reference);
2313  }
2314 
2315  buffer &assign(const char *c_str, bool make_reference = false) {
2316  return assign(c_str, ::mdbx::strlen(c_str), make_reference);
2317  }
2318 
2319 #if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
2320  template <class CHAR, class T>
2321  buffer &assign(const ::std::basic_string_view<CHAR, T> &view,
2322  bool make_reference = false) {
2323  return assign(view.data(), view.length(), make_reference);
2324  }
2325 
2326  template <class CHAR, class T>
2327  buffer &assign(::std::basic_string_view<CHAR, T> &&view,
2328  bool make_reference = false) {
2329  assign(view.data(), view.length(), make_reference);
2330  view = {};
2331  return *this;
2332  }
2333 #endif /* __cpp_lib_string_view >= 201606L */
2334 
2335  buffer &operator=(const buffer &src) { return assign(src); }
2336 
2337  buffer &operator=(buffer &&src) noexcept(move_assign_alloc::is_nothrow()) {
2338  return assign(::std::move(src));
2339  }
2340 
2341  buffer &operator=(const struct slice &src) { return assign(src); }
2342 
2343  buffer &operator=(struct slice &&src) { return assign(::std::move(src)); }
2344 
2345 #if defined(DOXYGEN) || \
2346  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
2347  template <class CHAR, class T>
2348  buffer &operator=(const ::std::basic_string_view<CHAR, T> &view) noexcept {
2349  return assign(view);
2350  }
2351 
2353  template <class CHAR = char, class T = ::std::char_traits<CHAR>>
2354  ::std::basic_string_view<CHAR, T> string_view() const noexcept {
2355  return slice_.string_view<CHAR, T>();
2356  }
2357 
2359  template <class CHAR, class T>
2360  operator ::std::basic_string_view<CHAR, T>() const noexcept {
2361  return string_view<CHAR, T>();
2362  }
2363 #endif /* __cpp_lib_string_view >= 201606L */
2364 
2367  return length() == 0;
2368  }
2369 
2371  MDBX_CXX11_CONSTEXPR bool is_null() const noexcept {
2372  return data() == nullptr;
2373  }
2374 
2377  return length();
2378  }
2379 
2385  hash_value() const noexcept {
2386  return slice_.hash_value();
2387  }
2388 
2389  template <class CHAR = char, class T = ::std::char_traits<CHAR>,
2390  class A = legacy_allocator>
2391  MDBX_CXX20_CONSTEXPR ::std::basic_string<CHAR, T, A>
2392  as_string(const A &allocator = A()) const {
2393  return slice_.as_string<CHAR, T, A>(allocator);
2394  }
2395 
2396  template <class CHAR, class T, class A>
2397  MDBX_CXX20_CONSTEXPR explicit
2398  operator ::std::basic_string<CHAR, T, A>() const {
2399  return as_string<CHAR, T, A>();
2400  }
2401 
2404  starts_with(const struct slice &prefix) const noexcept {
2405  return slice_.starts_with(prefix);
2406  }
2407 
2410  ends_with(const struct slice &suffix) const noexcept {
2411  return slice_.ends_with(suffix);
2412  }
2413 
2415  void clear() noexcept {
2416  slice_.clear();
2417  silo_.clear();
2418  }
2419 
2421  void shrink_to_fit() { reserve(0, 0); }
2422 
2425  void remove_prefix(size_t n) noexcept { slice_.remove_prefix(n); }
2426 
2429  void remove_suffix(size_t n) noexcept { slice_.remove_suffix(n); }
2430 
2433  void safe_remove_prefix(size_t n) { slice_.safe_remove_prefix(n); }
2434 
2437  void safe_remove_suffix(size_t n) { slice_.safe_remove_suffix(n); }
2438 
2441  MDBX_CXX11_CONSTEXPR byte operator[](size_t n) const noexcept {
2442  MDBX_CONSTEXPR_ASSERT(n < size());
2443  return slice_[n];
2444  }
2445 
2448  MDBX_CXX11_CONSTEXPR byte &operator[](size_t n) noexcept {
2449  MDBX_CONSTEXPR_ASSERT(n < size());
2450  return byte_ptr()[n];
2451  }
2452 
2455  MDBX_CXX14_CONSTEXPR byte at(size_t n) const { return slice_.at(n); }
2456 
2459  MDBX_CXX14_CONSTEXPR byte &at(size_t n) {
2460  if (MDBX_UNLIKELY(n >= size()))
2462  return byte_ptr()[n];
2463  }
2464 
2467  MDBX_CXX14_CONSTEXPR struct slice head(size_t n) const noexcept {
2468  return slice_.head(n);
2469  }
2470 
2473  MDBX_CXX14_CONSTEXPR struct slice tail(size_t n) const noexcept {
2474  return slice_.tail(n);
2475  }
2476 
2479  MDBX_CXX14_CONSTEXPR struct slice middle(size_t from,
2480  size_t n) const noexcept {
2481  return slice_.middle(from, n);
2482  }
2483 
2486  MDBX_CXX14_CONSTEXPR struct slice safe_head(size_t n) const {
2487  return slice_.safe_head(n);
2488  }
2489 
2492  MDBX_CXX14_CONSTEXPR struct slice safe_tail(size_t n) const {
2493  return slice_.safe_tail(n);
2494  }
2495 
2498  MDBX_CXX14_CONSTEXPR struct slice safe_middle(size_t from, size_t n) const {
2499  return slice_.safe_middle(from, n);
2500  }
2501 
2502  buffer &append(const void *src, size_t bytes) {
2503  if (MDBX_UNLIKELY(tailroom() < check_length(bytes)))
2504  MDBX_CXX20_UNLIKELY reserve_tailroom(bytes);
2505  memcpy(slice_.byte_ptr() + size(), src, bytes);
2506  slice_.iov_len += bytes;
2507  return *this;
2508  }
2509 
2510  buffer &append(const struct slice &chunk) {
2511  return append(chunk.data(), chunk.size());
2512  }
2513 
2514  buffer &add_header(const void *src, size_t bytes) {
2515  if (MDBX_UNLIKELY(headroom() < check_length(bytes)))
2516  MDBX_CXX20_UNLIKELY reserve_headroom(bytes);
2517  slice_.iov_base =
2518  memcpy(static_cast<char *>(slice_.iov_base) - bytes, src, bytes);
2519  slice_.iov_len += bytes;
2520  return *this;
2521  }
2522 
2523  buffer &add_header(const struct slice &chunk) {
2524  return add_header(chunk.data(), chunk.size());
2525  }
2526 
2527  template <MDBX_CXX20_CONCEPT(MutableByteProducer, PRODUCER)>
2528  buffer &append_producer(PRODUCER &producer) {
2529  const size_t wanna_bytes = producer.envisage_result_length();
2530  if (MDBX_UNLIKELY(tailroom() < check_length(wanna_bytes)))
2531  MDBX_CXX20_UNLIKELY reserve_tailroom(wanna_bytes);
2532  return set_end(producer.write_bytes(end_char_ptr(), tailroom()));
2533  }
2534 
2535  template <MDBX_CXX20_CONCEPT(ImmutableByteProducer, PRODUCER)>
2536  buffer &append_producer(const PRODUCER &producer) {
2537  const size_t wanna_bytes = producer.envisage_result_length();
2538  if (MDBX_UNLIKELY(tailroom() < check_length(wanna_bytes)))
2539  MDBX_CXX20_UNLIKELY reserve_tailroom(wanna_bytes);
2540  return set_end(producer.write_bytes(end_char_ptr(), tailroom()));
2541  }
2542 
2543  buffer &append_hex(const struct slice &data, bool uppercase = false,
2544  unsigned wrap_width = 0) {
2545  return append_producer(to_hex(data, uppercase, wrap_width));
2546  }
2547 
2548  buffer &append_base58(const struct slice &data, unsigned wrap_width = 0) {
2549  return append_producer(to_base58(data, wrap_width));
2550  }
2551 
2552  buffer &append_base64(const struct slice &data, unsigned wrap_width = 0) {
2553  return append_producer(to_base64(data, wrap_width));
2554  }
2555 
2556  buffer &append_decoded_hex(const struct slice &data,
2557  bool ignore_spaces = false) {
2558  return append_producer(from_hex(data, ignore_spaces));
2559  }
2560 
2561  buffer &append_decoded_base58(const struct slice &data,
2562  bool ignore_spaces = false) {
2563  return append_producer(from_base58(data, ignore_spaces));
2564  }
2565 
2566  buffer &append_decoded_base64(const struct slice &data,
2567  bool ignore_spaces = false) {
2568  return append_producer(from_base64(data, ignore_spaces));
2569  }
2570 
2571  //----------------------------------------------------------------------------
2572 
2573  template <size_t SIZE>
2574  static buffer key_from(const char (&text)[SIZE], bool make_reference = true) {
2575  return buffer(::mdbx::slice(text), make_reference);
2576  }
2577 
2578 #if defined(DOXYGEN) || \
2579  (defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L)
2580  template <class CHAR, class T>
2581  static buffer key_from(const ::std::basic_string_view<CHAR, T> &src,
2582  bool make_reference = false) {
2583  return buffer(src, make_reference);
2584  }
2585 #endif /* __cpp_lib_string_view >= 201606L */
2586 
2587  static buffer key_from(const char *src, bool make_reference = false) {
2588  return buffer(src, make_reference);
2589  }
2590 
2591  template <class CHAR, class T, class A>
2592  static buffer key_from(const ::std::basic_string<CHAR, T, A> &src,
2593  bool make_reference = false) {
2594  return buffer(src, make_reference);
2595  }
2596 
2597  static buffer key_from(const silo &&src) noexcept {
2598  return buffer(::std::move(src));
2599  }
2600 
2601  static buffer key_from(const double ieee754_64bit) {
2602  return wrap(::mdbx_key_from_double(ieee754_64bit));
2603  }
2604 
2605  static buffer key_from(const double *ieee754_64bit) {
2606  return wrap(::mdbx_key_from_ptrdouble(ieee754_64bit));
2607  }
2608 
2609  static buffer key_from(const uint64_t unsigned_int64) {
2610  return wrap(unsigned_int64);
2611  }
2612 
2613  static buffer key_from(const int64_t signed_int64) {
2614  return wrap(::mdbx_key_from_int64(signed_int64));
2615  }
2616 
2617  static buffer key_from_jsonInteger(const int64_t json_integer) {
2618  return wrap(::mdbx_key_from_jsonInteger(json_integer));
2619  }
2620 
2621  static buffer key_from(const float ieee754_32bit) {
2622  return wrap(::mdbx_key_from_float(ieee754_32bit));
2623  }
2624 
2625  static buffer key_from(const float *ieee754_32bit) {
2626  return wrap(::mdbx_key_from_ptrfloat(ieee754_32bit));
2627  }
2628 
2629  static buffer key_from(const uint32_t unsigned_int32) {
2630  return wrap(unsigned_int32);
2631  }
2632 
2633  static buffer key_from(const int32_t signed_int32) {
2634  return wrap(::mdbx_key_from_int32(signed_int32));
2635  }
2636 };
2637 
2638 template <class ALLOCATOR, class CAPACITY_POLICY,
2640 inline buffer<ALLOCATOR, CAPACITY_POLICY>
2641 make_buffer(PRODUCER &producer, const ALLOCATOR &allocator) {
2642  if (MDBX_LIKELY(!producer.is_empty()))
2645  producer.envisage_result_length(), allocator);
2646  result.set_end(
2647  producer.write_bytes(result.end_char_ptr(), result.tailroom()));
2648  return result;
2649  }
2650  return buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
2651 }
2652 
2653 template <class ALLOCATOR, class CAPACITY_POLICY,
2655 inline buffer<ALLOCATOR, CAPACITY_POLICY>
2656 make_buffer(const PRODUCER &producer, const ALLOCATOR &allocator) {
2657  if (MDBX_LIKELY(!producer.is_empty()))
2660  producer.envisage_result_length(), allocator);
2661  result.set_end(
2662  producer.write_bytes(result.end_char_ptr(), result.tailroom()));
2663  return result;
2664  }
2665  return buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
2666 }
2667 
2668 template <class ALLOCATOR, MDBX_CXX20_CONCEPT(MutableByteProducer, PRODUCER)>
2669 inline string<ALLOCATOR> make_string(PRODUCER &producer,
2670  const ALLOCATOR &allocator) {
2671  string<ALLOCATOR> result(allocator);
2672  if (MDBX_LIKELY(!producer.is_empty()))
2674  result.resize(producer.envisage_result_length());
2675  result.resize(producer.write_bytes(const_cast<char *>(result.data()),
2676  result.capacity()) -
2677  result.data());
2678  }
2679  return result;
2680 }
2681 
2682 template <class ALLOCATOR, MDBX_CXX20_CONCEPT(ImmutableByteProducer, PRODUCER)>
2683 inline string<ALLOCATOR> make_string(const PRODUCER &producer,
2684  const ALLOCATOR &allocator) {
2685  string<ALLOCATOR> result(allocator);
2686  if (MDBX_LIKELY(!producer.is_empty()))
2688  result.resize(producer.envisage_result_length());
2689  result.resize(producer.write_bytes(const_cast<char *>(result.data()),
2690  result.capacity()) -
2691  result.data());
2692  }
2693  return result;
2694 }
2695 
2700  bool done;
2701  value_result(const slice &value, bool done) noexcept
2702  : value(value), done(done) {}
2703  value_result(const value_result &) noexcept = default;
2704  value_result &operator=(const value_result &) noexcept = default;
2705  MDBX_CXX14_CONSTEXPR operator bool() const noexcept {
2706  assert(!done || bool(value));
2707  return done;
2708  }
2709 };
2710 
2713 struct pair {
2714  slice key, value;
2715  pair(const slice &key, const slice &value) noexcept
2716  : key(key), value(value) {}
2717  pair(const pair &) noexcept = default;
2718  pair &operator=(const pair &) noexcept = default;
2719  MDBX_CXX14_CONSTEXPR operator bool() const noexcept {
2720  assert(bool(key) == bool(value));
2721  return key;
2722  }
2723 };
2724 
2727 struct pair_result : public pair {
2728  bool done;
2729  pair_result(const slice &key, const slice &value, bool done) noexcept
2730  : pair(key, value), done(done) {}
2731  pair_result(const pair_result &) noexcept = default;
2732  pair_result &operator=(const pair_result &) noexcept = default;
2733  MDBX_CXX14_CONSTEXPR operator bool() const noexcept {
2734  assert(!done || (bool(key) && bool(value)));
2735  return done;
2736  }
2737 };
2738 
2739 //------------------------------------------------------------------------------
2740 
2743 enum loop_control { continue_loop = 0, exit_loop = INT32_MIN };
2744 
2746 enum class key_mode {
2753  msgpack = -1
2758 };
2761 
2764 enum class value_mode {
2766  multi =
2768  MDBX_DUPSORT,
2769 #if CONSTEXPR_ENUM_FLAGS_OPERATIONS || defined(DOXYGEN)
2775  multi_reverse =
2776  MDBX_DUPSORT |
2777  MDBX_REVERSEDUP,
2786  MDBX_DUPSORT |
2787  MDBX_DUPFIXED,
2788  multi_ordinal =
2796  MDBX_INTEGERDUP,
2806  MDBX_DUPFIXED,
2807  msgpack = -1
2815 #else
2822  multi_reverse = uint32_t(MDBX_DUPSORT) | uint32_t(MDBX_REVERSEDUP),
2823  multi_samelength = uint32_t(MDBX_DUPSORT) | uint32_t(MDBX_DUPFIXED),
2824  multi_ordinal = uint32_t(MDBX_DUPSORT) | uint32_t(MDBX_DUPFIXED) |
2825  uint32_t(MDBX_INTEGERDUP),
2827  uint32_t(MDBX_REVERSEDUP) | uint32_t(MDBX_DUPFIXED)
2828 #endif
2829 };
2830 
2839  MDBX_dbi dbi{0};
2841  MDBX_CXX11_CONSTEXPR map_handle(MDBX_dbi dbi) noexcept : dbi(dbi) {}
2842  map_handle(const map_handle &) noexcept = default;
2843  map_handle &operator=(const map_handle &) noexcept = default;
2844  operator bool() const noexcept { return dbi != 0; }
2845 
2852  map_handle::state state) noexcept;
2853  info(const info &) noexcept = default;
2854  info &operator=(const info &) noexcept = default;
2855 #if CONSTEXPR_ENUM_FLAGS_OPERATIONS
2857 #else
2858  inline
2859 #endif
2860  ::mdbx::key_mode key_mode() const noexcept;
2861 #if CONSTEXPR_ENUM_FLAGS_OPERATIONS
2863 #else
2864  inline
2865 #endif
2866  ::mdbx::value_mode value_mode() const noexcept;
2867  };
2868 };
2869 
2871 enum put_mode {
2875 };
2876 
2886  friend class txn;
2887 
2888 protected:
2889  MDBX_env *handle_{nullptr};
2890  MDBX_CXX11_CONSTEXPR env(MDBX_env *ptr) noexcept;
2891 
2892 public:
2893  MDBX_CXX11_CONSTEXPR env() noexcept = default;
2894  env(const env &) noexcept = default;
2895  inline env &operator=(env &&other) noexcept;
2896  inline env(env &&other) noexcept;
2897  inline ~env() noexcept;
2898 
2899  MDBX_CXX14_CONSTEXPR operator bool() const noexcept;
2900  MDBX_CXX14_CONSTEXPR operator const MDBX_env *() const;
2901  MDBX_CXX14_CONSTEXPR operator MDBX_env *();
2902  friend MDBX_CXX11_CONSTEXPR bool operator==(const env &a,
2903  const env &b) noexcept;
2904  friend MDBX_CXX11_CONSTEXPR bool operator!=(const env &a,
2905  const env &b) noexcept;
2906 
2907  //----------------------------------------------------------------------------
2908 
2911  enum : int64_t {
2912  default_value = -1,
2913  minimal_value = 0,
2914  maximal_value = INTPTR_MAX,
2915  kB = 1000,
2916  MB = kB * 1000,
2917  GB = MB * 1000,
2918  TB = GB * 1000,
2919  PB = TB * 1000,
2920  EB = PB * 1000,
2921  KiB = 1024,
2922  MiB = KiB << 10,
2923  GiB = MiB << 10,
2924  TiB = GiB << 10,
2925  PiB = TiB << 10,
2926  EiB = PiB << 10,
2927  };
2928 
2930  struct size {
2931  intptr_t bytes;
2932  MDBX_CXX11_CONSTEXPR size(intptr_t bytes) noexcept : bytes(bytes) {}
2933  MDBX_CXX11_CONSTEXPR operator intptr_t() const noexcept { return bytes; }
2934  };
2935 
2937  intptr_t size_lower{minimal_value};
2938 
2942  intptr_t size_now{default_value};
2943 
2954  intptr_t size_upper{maximal_value};
2955 
2958  intptr_t growth_step{default_value};
2959 
2962  intptr_t shrink_threshold{default_value};
2963 
2968  intptr_t pagesize{default_value};
2969 
2970  inline geometry &make_fixed(intptr_t size) noexcept;
2971  inline geometry &make_dynamic(intptr_t lower = minimal_value,
2972  intptr_t upper = maximal_value) noexcept;
2975  geometry(const geometry &) noexcept = default;
2976  MDBX_CXX11_CONSTEXPR geometry(intptr_t size_lower,
2977  intptr_t size_now = default_value,
2978  intptr_t size_upper = maximal_value,
2979  intptr_t growth_step = default_value,
2980  intptr_t shrink_threshold = default_value,
2981  intptr_t pagesize = default_value) noexcept
2982  : size_lower(size_lower), size_now(size_now), size_upper(size_upper),
2983  growth_step(growth_step), shrink_threshold(shrink_threshold),
2984  pagesize(pagesize) {}
2985  };
2986 
2988  enum mode {
2990  write_file_io, // don't available on OpenBSD
2991  write_mapped_io
2992  };
2993 
2995  enum durability {
2999  whole_fragile
3000  };
3001 
3005  bool lifo{false};
3007  bool coalesce{false};
3010  reclaiming_options(const reclaiming_options &) noexcept = default;
3012  operator=(const reclaiming_options &) noexcept = default;
3014  };
3015 
3019  bool orphan_read_transactions{false};
3020  bool nested_write_transactions{false};
3022  bool exclusive{false};
3024  bool disable_readahead{false};
3026  bool disable_clear_memory{false};
3029  operate_options(const operate_options &) noexcept = default;
3031  operator=(const operate_options &) noexcept = default;
3033  };
3034 
3039  unsigned max_maps{0};
3042  unsigned max_readers{0};
3043  env::mode mode{write_mapped_io};
3044  env::durability durability{robust_synchronous};
3047 
3051  const unsigned max_maps, const unsigned max_readers = 0,
3052  const env::mode mode = env::mode::write_mapped_io,
3053  env::durability durability = env::durability::robust_synchronous,
3054  const env::reclaiming_options &reclaiming = env::reclaiming_options(),
3055  const env::operate_options &options = env::operate_options()) noexcept
3056  : max_maps(max_maps), max_readers(max_readers), mode(mode),
3057  durability(durability), reclaiming(reclaiming), options(options) {}
3059  operate_parameters(const operate_parameters &) noexcept = default;
3061  operator=(const operate_parameters &) noexcept = default;
3063  make_flags(bool accede = true,
3064  bool use_subdirectory =
3065  false
3066  ) const;
3067  static env::mode mode_from_flags(MDBX_env_flags_t) noexcept;
3068  static env::durability durability_from_flags(MDBX_env_flags_t) noexcept;
3069  inline static env::reclaiming_options
3070  reclaiming_from_flags(MDBX_env_flags_t flags) noexcept;
3071  inline static env::operate_options
3072  options_from_flags(MDBX_env_flags_t flags) noexcept;
3073  };
3074 
3076  inline env::operate_parameters get_operation_parameters() const;
3078  inline env::mode get_mode() const;
3080  inline env::durability get_durability() const;
3082  inline env::reclaiming_options get_reclaiming() const;
3084  inline env::operate_options get_options() const;
3085 
3088  bool is_pristine() const;
3089 
3091  bool is_empty() const;
3092 
3094  static size_t default_pagesize() noexcept {
3096  }
3097 
3098  struct limits {
3099  limits() = delete;
3101  static inline size_t pagesize_min() noexcept;
3103  static inline size_t pagesize_max() noexcept;
3106  static inline size_t dbsize_min(intptr_t pagesize);
3109  static inline size_t dbsize_max(intptr_t pagesize);
3112  static inline size_t key_min(MDBX_db_flags_t flags) noexcept;
3114  static inline size_t key_min(key_mode mode) noexcept;
3117  static inline size_t key_max(intptr_t pagesize, MDBX_db_flags_t flags);
3120  static inline size_t key_max(intptr_t pagesize, key_mode mode);
3123  static inline size_t key_max(const env &, MDBX_db_flags_t flags);
3126  static inline size_t key_max(const env &, key_mode mode);
3129  static inline size_t value_min(MDBX_db_flags_t flags) noexcept;
3132  static inline size_t value_min(value_mode) noexcept;
3135  static inline size_t value_max(intptr_t pagesize, MDBX_db_flags_t flags);
3138  static inline size_t value_max(intptr_t pagesize, value_mode);
3141  static inline size_t value_max(const env &, MDBX_db_flags_t flags);
3144  static inline size_t value_max(const env &, value_mode);
3147  static inline size_t transaction_size_max(intptr_t pagesize);
3148  };
3149 
3151  size_t dbsize_min() const { return limits::dbsize_min(this->get_pagesize()); }
3153  size_t dbsize_max() const { return limits::dbsize_max(this->get_pagesize()); }
3155  size_t key_min(key_mode mode) const noexcept { return limits::key_min(mode); }
3157  size_t key_max(key_mode mode) const { return limits::key_max(*this, mode); }
3159  size_t value_min(value_mode mode) const noexcept {
3160  return limits::value_min(mode);
3161  }
3163  size_t value_max(value_mode mode) const {
3164  return limits::value_max(*this, mode);
3165  }
3168  size_t transaction_size_max() const {
3169  return limits::transaction_size_max(this->get_pagesize());
3170  }
3171 
3174 #ifdef MDBX_STD_FILESYSTEM_PATH
3175  env &copy(const MDBX_STD_FILESYSTEM_PATH &destination, bool compactify,
3176  bool force_dynamic_size = false);
3177 #endif /* MDBX_STD_FILESYSTEM_PATH */
3178 #if defined(_WIN32) || defined(_WIN64)
3179  env &copy(const ::std::wstring &destination, bool compactify,
3180  bool force_dynamic_size = false);
3181 #endif /* Windows */
3182  env &copy(const ::std::string &destination, bool compactify,
3183  bool force_dynamic_size = false);
3184 
3186  env &copy(filehandle fd, bool compactify, bool force_dynamic_size = false);
3187 
3196  just_remove = MDBX_ENV_JUST_DELETE,
3199  ensure_unused = MDBX_ENV_ENSURE_UNUSED,
3202  wait_for_unused = MDBX_ENV_WAIT_FOR_UNUSED
3203  };
3204 
3207 #ifdef MDBX_STD_FILESYSTEM_PATH
3208  static bool remove(const MDBX_STD_FILESYSTEM_PATH &,
3209  const remove_mode mode = just_remove);
3210 #endif /* MDBX_STD_FILESYSTEM_PATH */
3211 #if defined(_WIN32) || defined(_WIN64)
3212  static bool remove(const ::std::wstring &,
3213  const remove_mode mode = just_remove);
3214 #endif /* Windows */
3215  static bool remove(const ::std::string &,
3216  const remove_mode mode = just_remove);
3217 
3220 
3223 
3225  inline stat get_stat() const;
3226 
3228  size_t get_pagesize() const { return get_stat().ms_psize; }
3229 
3231  inline info get_info() const;
3232 
3235  inline stat get_stat(const txn &) const;
3236 
3239  inline info get_info(const txn &) const;
3240 
3242  inline filehandle get_filehandle() const;
3243 
3245  path get_path() const;
3246 
3248  inline MDBX_env_flags_t get_flags() const;
3249 
3252  inline unsigned max_readers() const;
3253 
3255  inline unsigned max_maps() const;
3256 
3258  inline void *get_context() const noexcept;
3259 
3261  inline env &set_context(void *);
3262 
3276  inline env &set_sync_threshold(size_t bytes);
3277 
3297  inline env &set_sync_period(unsigned seconds_16dot16);
3298 
3318  inline env &set_sync_period(double seconds);
3319 
3321  inline env &alter_flags(MDBX_env_flags_t flags, bool on_off);
3322 
3324  inline env &set_geometry(const geometry &size);
3325 
3329  inline bool sync_to_disk(bool force = true, bool nonblock = false);
3330 
3334  bool poll_sync_to_disk() { return sync_to_disk(false, true); }
3335 
3354  inline void close_map(const map_handle &);
3355 
3357  struct reader_info {
3358  int slot;
3361  uint64_t transaction_id;
3362  uint64_t transaction_lag;
3364  size_t bytes_used;
3368  size_t bytes_retained;
3371 
3378  mdbx_tid_t thread, uint64_t txnid,
3379  uint64_t lag, size_t used,
3380  size_t retained) noexcept;
3381  };
3382 
3390  template <typename VISITOR> inline int enumerate_readers(VISITOR &visitor);
3391 
3394  inline unsigned check_readers();
3395 
3413  inline env &set_HandleSlowReaders(MDBX_hsr_func *);
3414 
3419  inline MDBX_hsr_func *get_HandleSlowReaders() const noexcept;
3420 
3422  inline txn_managed start_read() const;
3423 
3425  inline txn_managed prepare_read() const;
3426 
3428  inline txn_managed start_write(bool dont_wait = false);
3429 
3431  inline txn_managed try_start_write();
3432 };
3433 
3443  using inherited = env;
3445  MDBX_CXX11_CONSTEXPR env_managed(MDBX_env *ptr) noexcept : inherited(ptr) {}
3446  void setup(unsigned max_maps, unsigned max_readers = 0);
3447 
3448 public:
3449  MDBX_CXX11_CONSTEXPR env_managed() noexcept = default;
3450 
3452 #ifdef MDBX_STD_FILESYSTEM_PATH
3454  bool accede = true);
3455 #endif /* MDBX_STD_FILESYSTEM_PATH */
3456 #if defined(_WIN32) || defined(_WIN64)
3457  env_managed(const ::std::wstring &, const operate_parameters &,
3458  bool accede = true);
3459 #endif /* Windows */
3461  bool accede = true);
3462 
3466  mdbx_mode_t file_mode_bits{0640};
3467  bool use_subdirectory{false};
3468  MDBX_CXX11_CONSTEXPR create_parameters() noexcept = default;
3469  create_parameters(const create_parameters &) noexcept = default;
3470  };
3471 
3473 #ifdef MDBX_STD_FILESYSTEM_PATH
3475  const operate_parameters &, bool accede = true);
3476 #endif /* MDBX_STD_FILESYSTEM_PATH */
3477 #if defined(_WIN32) || defined(_WIN64)
3478  env_managed(const ::std::wstring &, const create_parameters &,
3479  const operate_parameters &, bool accede = true);
3480 #endif /* Windows */
3482  const operate_parameters &, bool accede = true);
3483 
3497  void close(bool dont_sync = false);
3498 
3499  env_managed(env_managed &&) = default;
3501  if (MDBX_UNLIKELY(handle_))
3503  assert(handle_ != other.handle_);
3504  close();
3505  }
3506  inherited::operator=(std::move(other));
3507  return *this;
3508  }
3509  env_managed(const env_managed &) = delete;
3510  env_managed &operator=(const env_managed &) = delete;
3511  virtual ~env_managed() noexcept;
3512 };
3513 
3523 protected:
3524  friend class cursor;
3525  MDBX_txn *handle_{nullptr};
3526  MDBX_CXX11_CONSTEXPR txn(MDBX_txn *ptr) noexcept;
3527 
3528 public:
3529  MDBX_CXX11_CONSTEXPR txn() noexcept = default;
3530  txn(const txn &) noexcept = default;
3531  inline txn &operator=(txn &&other) noexcept;
3532  inline txn(txn &&other) noexcept;
3533  inline ~txn() noexcept;
3534 
3535  MDBX_CXX14_CONSTEXPR operator bool() const noexcept;
3536  MDBX_CXX14_CONSTEXPR operator const MDBX_txn *() const;
3537  MDBX_CXX14_CONSTEXPR operator MDBX_txn *();
3538  friend MDBX_CXX11_CONSTEXPR bool operator==(const txn &a,
3539  const txn &b) noexcept;
3540  friend MDBX_CXX11_CONSTEXPR bool operator!=(const txn &a,
3541  const txn &b) noexcept;
3542 
3544  inline ::mdbx::env env() const noexcept;
3546  inline MDBX_txn_flags_t flags() const;
3548  inline uint64_t id() const;
3549 
3551  inline bool is_dirty(const void *ptr) const;
3552 
3554  bool is_readonly() const { return (flags() & MDBX_TXN_RDONLY) != 0; }
3555 
3557  bool is_readwrite() const { return (flags() & MDBX_TXN_RDONLY) == 0; }
3558 
3561  inline info get_info(bool scan_reader_lock_table = false) const;
3562 
3565  size_t size_max() const { return env().transaction_size_max(); }
3566 
3569  size_t size_current() const {
3570  assert(is_readwrite());
3571  return size_t(get_info().txn_space_dirty);
3572  }
3573 
3574  //----------------------------------------------------------------------------
3575 
3577  inline void reset_reading();
3578 
3580  inline void renew_reading();
3581 
3583  txn_managed start_nested();
3584 
3586  inline cursor_managed open_cursor(map_handle map);
3587 
3589  inline map_handle open_map(
3590  const char *name,
3594  inline map_handle open_map(
3595  const ::std::string &name,
3598 
3600  inline map_handle
3601  create_map(const char *name,
3605  inline map_handle
3606  create_map(const ::std::string &name,
3609 
3611  inline void drop_map(map_handle map);
3615  bool drop_map(const char *name, bool throw_if_absent = false);
3619  inline bool drop_map(const ::std::string &name, bool throw_if_absent = false);
3620 
3622  inline void clear_map(map_handle map);
3625  bool clear_map(const char *name, bool throw_if_absent = false);
3628  inline bool clear_map(const ::std::string &name,
3629  bool throw_if_absent = false);
3630 
3633  inline map_stat get_map_stat(map_handle map) const;
3636  inline uint32_t get_tree_deepmask(map_handle map) const;
3638  inline map_handle::info get_handle_info(map_handle map) const;
3639 
3643  inline txn &put_canary(const canary &);
3646  inline canary get_canary() const;
3647 
3650  inline uint64_t sequence(map_handle map) const;
3653  inline uint64_t sequence(map_handle map, uint64_t increment);
3654 
3657  inline int compare_keys(map_handle map, const slice &a,
3658  const slice &b) const noexcept;
3661  inline int compare_values(map_handle map, const slice &a,
3662  const slice &b) const noexcept;
3665  inline int compare_keys(map_handle map, const pair &a,
3666  const pair &b) const noexcept;
3669  inline int compare_values(map_handle map, const pair &a,
3670  const pair &b) const noexcept;
3671 
3673  inline slice get(map_handle map, const slice &key) const;
3676  inline slice get(map_handle map, slice key, size_t &values_count) const;
3678  inline slice get(map_handle map, const slice &key,
3679  const slice &value_at_absence) const;
3682  inline slice get(map_handle map, slice key, size_t &values_count,
3683  const slice &value_at_absence) const;
3687  inline pair_result get_equal_or_great(map_handle map, const slice &key) const;
3691  inline pair_result get_equal_or_great(map_handle map, const slice &key,
3692  const slice &value_at_absence) const;
3693 
3694  inline MDBX_error_t put(map_handle map, const slice &key, slice *value,
3695  MDBX_put_flags_t flags) noexcept;
3696  inline void put(map_handle map, const slice &key, slice value, put_mode mode);
3697  inline void insert(map_handle map, const slice &key, slice value);
3698  inline value_result try_insert(map_handle map, const slice &key, slice value);
3699  inline slice insert_reserve(map_handle map, const slice &key,
3700  size_t value_length);
3701  inline value_result try_insert_reserve(map_handle map, const slice &key,
3702  size_t value_length);
3703 
3704  inline void upsert(map_handle map, const slice &key, const slice &value);
3705  inline slice upsert_reserve(map_handle map, const slice &key,
3706  size_t value_length);
3707 
3708  inline void update(map_handle map, const slice &key, const slice &value);
3709  inline bool try_update(map_handle map, const slice &key, const slice &value);
3710  inline slice update_reserve(map_handle map, const slice &key,
3711  size_t value_length);
3712  inline value_result try_update_reserve(map_handle map, const slice &key,
3713  size_t value_length);
3714 
3716  inline bool erase(map_handle map, const slice &key);
3717 
3719  inline bool erase(map_handle map, const slice &key, const slice &value);
3720 
3722  inline void replace(map_handle map, const slice &key, slice old_value,
3723  const slice &new_value);
3724 
3726  template <class ALLOCATOR, typename CAPACITY_POLICY>
3728  extract(map_handle map, const slice &key,
3731 
3733  template <class ALLOCATOR, typename CAPACITY_POLICY>
3735  replace(map_handle map, const slice &key, const slice &new_value,
3738 
3739  template <class ALLOCATOR, typename CAPACITY_POLICY>
3740  inline buffer<ALLOCATOR, CAPACITY_POLICY> replace_reserve(
3741  map_handle map, const slice &key, slice &new_value,
3744 
3761  inline void append(map_handle map, const slice &key, const slice &value,
3762  bool multivalue_order_preserved = true);
3763 
3764  size_t put_multiple(map_handle map, const slice &key,
3765  const size_t value_length, const void *values_array,
3766  size_t values_count, put_mode mode,
3767  bool allow_partial = false);
3768  template <typename VALUE>
3769  void put_multiple(map_handle map, const slice &key,
3770  const ::std::vector<VALUE> &vector, put_mode mode) {
3771  put_multiple(map, key, sizeof(VALUE), vector.data(), vector.size(), mode,
3772  false);
3773  }
3774 
3775  inline ptrdiff_t estimate(map_handle map, pair from, pair to) const;
3776  inline ptrdiff_t estimate(map_handle map, slice from, slice to) const;
3777  inline ptrdiff_t estimate_from_first(map_handle map, slice to) const;
3778  inline ptrdiff_t estimate_to_last(map_handle map, slice from) const;
3779 };
3780 
3790  using inherited = txn;
3791  friend class env;
3792  friend class txn;
3794  MDBX_CXX11_CONSTEXPR txn_managed(MDBX_txn *ptr) noexcept : inherited(ptr) {}
3795 
3796 public:
3797  MDBX_CXX11_CONSTEXPR txn_managed() noexcept = default;
3798  txn_managed(txn_managed &&) = default;
3799  txn_managed &operator=(txn_managed &&other) {
3800  if (MDBX_UNLIKELY(handle_))
3802  assert(handle_ != other.handle_);
3803  abort();
3804  }
3805  inherited::operator=(std::move(other));
3806  return *this;
3807  }
3808  txn_managed(const txn_managed &) = delete;
3809  txn_managed &operator=(const txn_managed &) = delete;
3810  ~txn_managed() noexcept;
3811 
3812  //----------------------------------------------------------------------------
3813 
3816  void abort();
3817 
3819  void commit();
3820 };
3821 
3830 protected:
3831  MDBX_cursor *handle_{nullptr};
3832  MDBX_CXX11_CONSTEXPR cursor(MDBX_cursor *ptr) noexcept;
3833 
3834 public:
3835  MDBX_CXX11_CONSTEXPR cursor() noexcept = default;
3836  cursor(const cursor &) noexcept = default;
3837  inline cursor &operator=(cursor &&other) noexcept;
3838  inline cursor(cursor &&other) noexcept;
3839  inline ~cursor() noexcept;
3840  MDBX_CXX14_CONSTEXPR operator bool() const noexcept;
3841  MDBX_CXX14_CONSTEXPR operator const MDBX_cursor *() const;
3842  MDBX_CXX14_CONSTEXPR operator MDBX_cursor *();
3843  friend MDBX_CXX11_CONSTEXPR bool operator==(const cursor &a,
3844  const cursor &b) noexcept;
3845  friend MDBX_CXX11_CONSTEXPR bool operator!=(const cursor &a,
3846  const cursor &b) noexcept;
3847 
3849  first = MDBX_FIRST,
3850  last = MDBX_LAST,
3851  next = MDBX_NEXT,
3852  previous = MDBX_PREV,
3853  get_current = MDBX_GET_CURRENT,
3854 
3855  multi_prevkey_lastvalue = MDBX_PREV_NODUP,
3856  multi_currentkey_firstvalue = MDBX_FIRST_DUP,
3857  multi_currentkey_prevvalue = MDBX_PREV_DUP,
3858  multi_currentkey_nextvalue = MDBX_NEXT_DUP,
3859  multi_currentkey_lastvalue = MDBX_LAST_DUP,
3860  multi_nextkey_firstvalue = MDBX_NEXT_NODUP,
3861 
3862  multi_find_pair = MDBX_GET_BOTH,
3863  multi_exactkey_lowerboundvalue = MDBX_GET_BOTH_RANGE,
3864 
3865  find_key = MDBX_SET,
3866  key_exact = MDBX_SET_KEY,
3867  key_lowerbound = MDBX_SET_RANGE
3868  };
3869 
3870  struct move_result : public pair_result {
3871  inline move_result(const cursor &cursor, bool throw_notfound);
3872  inline move_result(cursor &cursor, move_operation operation,
3873  bool throw_notfound);
3874  inline move_result(cursor &cursor, move_operation operation,
3875  const slice &key, bool throw_notfound);
3876  inline move_result(cursor &cursor, move_operation operation,
3877  const slice &key, const slice &value,
3878  bool throw_notfound);
3879  move_result(const move_result &) noexcept = default;
3880  move_result &operator=(const move_result &) noexcept = default;
3881  };
3882 
3883 protected:
3884  inline bool move(move_operation operation, MDBX_val *key, MDBX_val *value,
3885  bool throw_notfound) const
3886  /* fake const, i.e. for some operations */;
3887  inline ptrdiff_t estimate(move_operation operation, MDBX_val *key,
3888  MDBX_val *value) const;
3889 
3890 public:
3891  inline move_result move(move_operation operation, bool throw_notfound);
3892  inline move_result to_first(bool throw_notfound = true);
3893  inline move_result to_previous(bool throw_notfound = true);
3894  inline move_result to_previous_last_multi(bool throw_notfound = true);
3895  inline move_result to_current_first_multi(bool throw_notfound = true);
3896  inline move_result to_current_prev_multi(bool throw_notfound = true);
3897  inline move_result current(bool throw_notfound = true) const;
3898  inline move_result to_current_next_multi(bool throw_notfound = true);
3899  inline move_result to_current_last_multi(bool throw_notfound = true);
3900  inline move_result to_next_first_multi(bool throw_notfound = true);
3901  inline move_result to_next(bool throw_notfound = true);
3902  inline move_result to_last(bool throw_notfound = true);
3903 
3904  inline move_result move(move_operation operation, const slice &key,
3905  bool throw_notfound);
3906  inline move_result find(const slice &key, bool throw_notfound = true);
3907  inline move_result lower_bound(const slice &key, bool throw_notfound = true);
3908 
3909  inline move_result move(move_operation operation, const slice &key,
3910  const slice &value, bool throw_notfound);
3911  inline move_result find_multivalue(const slice &key, const slice &value,
3912  bool throw_notfound = true);
3913  inline move_result lower_bound_multivalue(const slice &key,
3914  const slice &value,
3915  bool throw_notfound = false);
3916 
3917  inline bool seek(const slice &key);
3918  inline bool move(move_operation operation, slice &key, slice &value,
3919  bool throw_notfound);
3920 
3922  inline size_t count_multivalue() const;
3923 
3924  inline bool eof() const;
3925  inline bool on_first() const;
3926  inline bool on_last() const;
3927  inline ptrdiff_t estimate(slice key, slice value) const;
3928  inline ptrdiff_t estimate(slice key) const;
3929  inline ptrdiff_t estimate(move_operation operation) const;
3930 
3931  //----------------------------------------------------------------------------
3932 
3935  inline void renew(::mdbx::txn &txn);
3936 
3939  inline void bind(::mdbx::txn &txn, ::mdbx::map_handle map_handle);
3940 
3942  inline ::mdbx::txn txn() const;
3943  inline map_handle map() const;
3944 
3945  inline operator ::mdbx::txn() const { return txn(); }
3946  inline operator ::mdbx::map_handle() const { return map(); }
3947 
3948  inline MDBX_error_t put(const slice &key, slice *value,
3949  MDBX_put_flags_t flags) noexcept;
3950  inline void insert(const slice &key, slice value);
3951  inline value_result try_insert(const slice &key, slice value);
3952  inline slice insert_reserve(const slice &key, size_t value_length);
3953  inline value_result try_insert_reserve(const slice &key, size_t value_length);
3954 
3955  inline void upsert(const slice &key, const slice &value);
3956  inline slice upsert_reserve(const slice &key, size_t value_length);
3957 
3958  inline void update(const slice &key, const slice &value);
3959  inline bool try_update(const slice &key, const slice &value);
3960  inline slice update_reserve(const slice &key, size_t value_length);
3961  inline value_result try_update_reserve(const slice &key, size_t value_length);
3962 
3965  inline bool erase(bool whole_multivalue = false);
3966 
3970  inline bool erase(const slice &key, bool whole_multivalue = true);
3971 
3974  inline bool erase(const slice &key, const slice &value);
3975 };
3976 
3985  using inherited = cursor;
3986  friend class txn;
3989  : inherited(ptr) {}
3990 
3991 public:
3994  if (MDBX_UNLIKELY(!handle_))
3996  }
3997 
3999  void close();
4000 
4001  cursor_managed(cursor_managed &&) = default;
4003  if (MDBX_UNLIKELY(handle_))
4005  assert(handle_ != other.handle_);
4006  close();
4007  }
4008  inherited::operator=(std::move(other));
4009  return *this;
4010  }
4011 
4012  cursor_managed(const cursor_managed &) = delete;
4013  cursor_managed &operator=(const cursor_managed &) = delete;
4014  ~cursor_managed() noexcept { ::mdbx_cursor_close(handle_); }
4015 };
4016 
4017 //------------------------------------------------------------------------------
4018 
4019 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const slice &);
4020 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const pair &);
4021 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const pair_result &);
4022 template <class ALLOCATOR, typename CAPACITY_POLICY>
4023 inline ::std::ostream &
4024 operator<<(::std::ostream &out, const buffer<ALLOCATOR, CAPACITY_POLICY> &it) {
4025  return (it.is_freestanding()
4026  ? out << "buf-" << it.headroom() << "." << it.tailroom()
4027  : out << "ref-")
4028  << it.slice();
4029 }
4030 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4031  const env::geometry::size &);
4032 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const env::geometry &);
4033 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4034  const env::operate_parameters &);
4035 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const env::mode &);
4036 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4037  const env::durability &);
4038 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4039  const env::reclaiming_options &);
4040 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4041  const env::operate_options &);
4042 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4043  const env_managed::create_parameters &);
4044 
4045 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4046  const MDBX_log_level_t &);
4047 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &,
4048  const MDBX_debug_flags_t &);
4049 LIBMDBX_API ::std::ostream &operator<<(::std::ostream &, const error &);
4050 inline ::std::ostream &operator<<(::std::ostream &out,
4051  const MDBX_error_t &errcode) {
4052  return out << error(errcode);
4053 }
4054 
4055 //==============================================================================
4056 //
4057 // Inline body of the libmdbx C++ API
4058 //
4059 
4062 }
4065 }
4066 
4067 static MDBX_CXX17_CONSTEXPR size_t strlen(const char *c_str) noexcept {
4068 #if defined(__cpp_lib_is_constant_evaluated) && \
4069  __cpp_lib_is_constant_evaluated >= 201811L
4070  if (::std::is_constant_evaluated()) {
4071  for (size_t i = 0; c_str; ++i)
4072  if (!c_str[i])
4073  return i;
4074  return 0;
4075  }
4076 #endif /* __cpp_lib_is_constant_evaluated >= 201811 */
4077 #if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
4078  return c_str ? ::std::string_view(c_str).length() : 0;
4079 #else
4080  return c_str ? ::std::strlen(c_str) : 0;
4081 #endif
4082 }
4083 
4084 static MDBX_CXX20_CONSTEXPR void *memcpy(void *dest, const void *src,
4085  size_t bytes) noexcept {
4086 #if defined(__cpp_lib_is_constant_evaluated) && \
4087  __cpp_lib_is_constant_evaluated >= 201811L
4088  if (::std::is_constant_evaluated()) {
4089  for (size_t i = 0; i < bytes; ++i)
4090  static_cast<byte *>(dest)[i] = static_cast<const byte *>(src)[i];
4091  return dest;
4092  } else
4093 #endif /* __cpp_lib_is_constant_evaluated >= 201811 */
4094  return ::std::memcpy(dest, src, bytes);
4095 }
4096 
4097 static MDBX_CXX20_CONSTEXPR int memcmp(const void *a, const void *b,
4098  size_t bytes) noexcept {
4099 #if defined(__cpp_lib_is_constant_evaluated) && \
4100  __cpp_lib_is_constant_evaluated >= 201811L
4101  if (::std::is_constant_evaluated()) {
4102  for (size_t i = 0; i < bytes; ++i) {
4103  const int diff =
4104  static_cast<const byte *>(a)[i] - static_cast<const byte *>(b)[i];
4105  if (diff)
4106  return diff;
4107  }
4108  return 0;
4109  } else
4110 #endif /* __cpp_lib_is_constant_evaluated >= 201811 */
4111  return ::std::memcmp(a, b, bytes);
4112 }
4113 
4114 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes) {
4115  if (MDBX_UNLIKELY(bytes > size_t(MDBX_MAXDATASIZE)))
4117  return bytes;
4118 }
4119 
4120 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom,
4121  size_t payload) {
4122  return check_length(check_length(headroom) + check_length(payload));
4123 }
4124 
4125 static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom, size_t payload,
4126  size_t tailroom) {
4127  return check_length(check_length(headroom, payload) + check_length(tailroom));
4128 }
4129 
4130 inline bool exception_thunk::is_clean() const noexcept { return !captured_; }
4131 
4132 inline void exception_thunk::capture() noexcept {
4133  assert(is_clean());
4134  captured_ = ::std::current_exception();
4135 }
4136 
4138  if (captured_)
4139  MDBX_CXX20_UNLIKELY ::std::rethrow_exception(captured_);
4140 }
4141 
4142 //------------------------------------------------------------------------------
4143 
4145  : code_(error_code) {}
4146 
4147 inline error &error::operator=(MDBX_error_t error_code) noexcept {
4148  code_ = error_code;
4149  return *this;
4150 }
4151 
4152 MDBX_CXX11_CONSTEXPR bool operator==(const error &a, const error &b) noexcept {
4153  return a.code_ == b.code_;
4154 }
4155 
4156 MDBX_CXX11_CONSTEXPR bool operator!=(const error &a, const error &b) noexcept {
4157  return !(a == b);
4158 }
4159 
4161  return code_ == MDBX_SUCCESS;
4162 }
4163 
4165  return code_ == MDBX_RESULT_FALSE;
4166 }
4167 
4169  return code_ == MDBX_RESULT_TRUE;
4170 }
4171 
4173  return code_ != MDBX_SUCCESS && code_ != MDBX_RESULT_TRUE;
4174 }
4175 
4176 MDBX_CXX11_CONSTEXPR MDBX_error_t error::code() const noexcept { return code_; }
4177 
4179  return (code() >= MDBX_FIRST_LMDB_ERRCODE &&
4180  code() <= MDBX_LAST_LMDB_ERRCODE) ||
4181  (code() >= MDBX_FIRST_ADDED_ERRCODE &&
4182  code() <= MDBX_LAST_ADDED_ERRCODE);
4183 }
4184 
4185 inline void error::throw_exception(int error_code) {
4186  const error trouble(static_cast<MDBX_error_t>(error_code));
4187  trouble.throw_exception();
4188 }
4189 
4190 inline void error::throw_on_failure() const {
4191  if (MDBX_UNLIKELY(is_failure()))
4192  MDBX_CXX20_UNLIKELY throw_exception();
4193 }
4194 
4195 inline void error::success_or_throw() const {
4196  if (MDBX_UNLIKELY(!is_success()))
4197  MDBX_CXX20_UNLIKELY throw_exception();
4198 }
4199 
4200 inline void error::success_or_throw(const exception_thunk &thunk) const {
4201  assert(thunk.is_clean() || code() != MDBX_SUCCESS);
4202  if (MDBX_UNLIKELY(!is_success())) {
4203  MDBX_CXX20_UNLIKELY if (!thunk.is_clean()) thunk.rethrow_captured();
4204  else throw_exception();
4205  }
4206 }
4207 
4208 inline void error::panic_on_failure(const char *context_where,
4209  const char *func_who) const noexcept {
4210  if (MDBX_UNLIKELY(is_failure()))
4211  MDBX_CXX20_UNLIKELY panic(context_where, func_who);
4212 }
4213 
4214 inline void error::success_or_panic(const char *context_where,
4215  const char *func_who) const noexcept {
4216  if (MDBX_UNLIKELY(!is_success()))
4217  MDBX_CXX20_UNLIKELY panic(context_where, func_who);
4218 }
4219 
4220 inline void error::throw_on_nullptr(const void *ptr, MDBX_error_t error_code) {
4221  if (MDBX_UNLIKELY(ptr == nullptr))
4223 }
4224 
4225 inline void error::throw_on_failure(int error_code) {
4226  error rc(static_cast<MDBX_error_t>(error_code));
4227  rc.throw_on_failure();
4228 }
4229 
4230 inline void error::success_or_throw(MDBX_error_t error_code) {
4231  error rc(error_code);
4232  rc.success_or_throw();
4233 }
4234 
4235 inline bool error::boolean_or_throw(int error_code) {
4236  switch (error_code) {
4237  case MDBX_RESULT_FALSE:
4238  return false;
4239  case MDBX_RESULT_TRUE:
4240  return true;
4241  default:
4242  MDBX_CXX20_UNLIKELY throw_exception(error_code);
4243  }
4244 }
4245 
4246 inline void error::success_or_throw(int error_code,
4247  const exception_thunk &thunk) {
4248  error rc(static_cast<MDBX_error_t>(error_code));
4249  rc.success_or_throw(thunk);
4250 }
4251 
4252 inline void error::panic_on_failure(int error_code, const char *context_where,
4253  const char *func_who) noexcept {
4254  error rc(static_cast<MDBX_error_t>(error_code));
4255  rc.panic_on_failure(context_where, func_who);
4256 }
4257 
4258 inline void error::success_or_panic(int error_code, const char *context_where,
4259  const char *func_who) noexcept {
4260  error rc(static_cast<MDBX_error_t>(error_code));
4261  rc.success_or_panic(context_where, func_who);
4262 }
4263 
4264 //------------------------------------------------------------------------------
4265 
4266 MDBX_CXX11_CONSTEXPR slice::slice() noexcept : ::MDBX_val({nullptr, 0}) {}
4267 
4268 MDBX_CXX14_CONSTEXPR slice::slice(const void *ptr, size_t bytes)
4269  : ::MDBX_val({const_cast<void *>(ptr), check_length(bytes)}) {}
4270 
4271 MDBX_CXX14_CONSTEXPR slice::slice(const void *begin, const void *end)
4272  : slice(begin, static_cast<const byte *>(end) -
4273  static_cast<const byte *>(begin)) {}
4274 
4276  : slice(c_str, ::mdbx::strlen(c_str)) {}
4277 
4279  : slice(src.iov_base, src.iov_len) {}
4280 
4282  src.iov_base = nullptr;
4283 }
4284 
4286  src.invalidate();
4287 }
4288 
4289 inline slice &slice::assign(const void *ptr, size_t bytes) {
4290  iov_base = const_cast<void *>(ptr);
4291  iov_len = check_length(bytes);
4292  return *this;
4293 }
4294 
4295 inline slice &slice::assign(const slice &src) noexcept {
4296  iov_base = src.iov_base;
4297  iov_len = src.iov_len;
4298  return *this;
4299 }
4300 
4302  return assign(src.iov_base, src.iov_len);
4303 }
4304 
4305 slice &slice::assign(slice &&src) noexcept {
4306  assign(src);
4307  src.invalidate();
4308  return *this;
4309 }
4310 
4311 inline slice &slice::assign(::MDBX_val &&src) {
4312  assign(src.iov_base, src.iov_len);
4313  src.iov_base = nullptr;
4314  return *this;
4315 }
4316 
4317 inline slice &slice::assign(const void *begin, const void *end) {
4318  return assign(begin, static_cast<const byte *>(end) -
4319  static_cast<const byte *>(begin));
4320 }
4321 
4322 inline slice &slice::assign(const char *c_str) {
4323  return assign(c_str, ::mdbx::strlen(c_str));
4324 }
4325 
4326 inline slice &slice::operator=(slice &&src) noexcept {
4327  return assign(::std::move(src));
4328 }
4329 
4330 inline slice &slice::operator=(::MDBX_val &&src) {
4331  return assign(::std::move(src));
4332 }
4333 
4334 inline void slice::swap(slice &other) noexcept {
4335  const auto temp = *this;
4336  *this = other;
4337  other = temp;
4338 }
4339 
4341  return static_cast<const byte *>(iov_base);
4342 }
4343 
4345  return byte_ptr() + length();
4346 }
4347 
4349  return static_cast<byte *>(iov_base);
4350 }
4351 
4353  return byte_ptr() + length();
4354 }
4355 
4356 MDBX_CXX11_CONSTEXPR const char *slice::char_ptr() const noexcept {
4357  return static_cast<const char *>(iov_base);
4358 }
4359 
4360 MDBX_CXX11_CONSTEXPR const char *slice::end_char_ptr() const noexcept {
4361  return char_ptr() + length();
4362 }
4363 
4364 MDBX_CXX11_CONSTEXPR char *slice::char_ptr() noexcept {
4365  return static_cast<char *>(iov_base);
4366 }
4367 
4368 MDBX_CXX11_CONSTEXPR char *slice::end_char_ptr() noexcept {
4369  return char_ptr() + length();
4370 }
4371 
4372 MDBX_CXX11_CONSTEXPR const void *slice::data() const noexcept {
4373  return iov_base;
4374 }
4375 
4376 MDBX_CXX11_CONSTEXPR const void *slice::end() const noexcept {
4377  return static_cast<const void *>(end_byte_ptr());
4378 }
4379 
4380 MDBX_CXX11_CONSTEXPR void *slice::data() noexcept { return iov_base; }
4381 
4382 MDBX_CXX11_CONSTEXPR void *slice::end() noexcept {
4383  return static_cast<void *>(end_byte_ptr());
4384 }
4385 
4386 MDBX_CXX11_CONSTEXPR size_t slice::length() const noexcept { return iov_len; }
4387 
4389  iov_len = check_length(bytes);
4390  return *this;
4391 }
4392 
4394  MDBX_CONSTEXPR_ASSERT(static_cast<const char *>(ptr) >= char_ptr());
4395  return set_length(static_cast<const char *>(ptr) - char_ptr());
4396 }
4397 
4398 MDBX_CXX11_CONSTEXPR bool slice::empty() const noexcept {
4399  return length() == 0;
4400 }
4401 
4402 MDBX_CXX11_CONSTEXPR bool slice::is_null() const noexcept {
4403  return data() == nullptr;
4404 }
4405 
4406 MDBX_CXX11_CONSTEXPR size_t slice::size() const noexcept { return length(); }
4407 
4408 MDBX_CXX11_CONSTEXPR slice::operator bool() const noexcept {
4409  return !is_null();
4410 }
4411 
4412 MDBX_CXX14_CONSTEXPR void slice::invalidate() noexcept { iov_base = nullptr; }
4413 
4415  iov_base = nullptr;
4416  iov_len = 0;
4417 }
4418 
4419 inline void slice::remove_prefix(size_t n) noexcept {
4420  assert(n <= size());
4421  iov_base = static_cast<byte *>(iov_base) + n;
4422  iov_len -= n;
4423 }
4424 
4425 inline void slice::safe_remove_prefix(size_t n) {
4426  if (MDBX_UNLIKELY(n > size()))
4428  remove_prefix(n);
4429 }
4430 
4431 inline void slice::remove_suffix(size_t n) noexcept {
4432  assert(n <= size());
4433  iov_len -= n;
4434 }
4435 
4436 inline void slice::safe_remove_suffix(size_t n) {
4437  if (MDBX_UNLIKELY(n > size()))
4439  remove_suffix(n);
4440 }
4441 
4443 slice::starts_with(const slice &prefix) const noexcept {
4444  return length() >= prefix.length() &&
4445  memcmp(data(), prefix.data(), prefix.length()) == 0;
4446 }
4447 
4448 MDBX_CXX14_CONSTEXPR bool slice::ends_with(const slice &suffix) const noexcept {
4449  return length() >= suffix.length() &&
4450  memcmp(byte_ptr() + length() - suffix.length(), suffix.data(),
4451  suffix.length()) == 0;
4452 }
4453 
4455 slice::hash_value() const noexcept {
4456  size_t h = length() * 3977471;
4457  for (size_t i = 0; i < length(); ++i)
4458  h = (h ^ static_cast<const uint8_t *>(data())[i]) * 1664525 + 1013904223;
4459  return h ^ 3863194411 * (h >> 11);
4460 }
4461 
4462 MDBX_CXX11_CONSTEXPR byte slice::operator[](size_t n) const noexcept {
4463  MDBX_CONSTEXPR_ASSERT(n < size());
4464  return byte_ptr()[n];
4465 }
4466 
4467 MDBX_CXX11_CONSTEXPR byte slice::at(size_t n) const {
4468  if (MDBX_UNLIKELY(n >= size()))
4470  return byte_ptr()[n];
4471 }
4472 
4473 MDBX_CXX14_CONSTEXPR slice slice::head(size_t n) const noexcept {
4474  MDBX_CONSTEXPR_ASSERT(n <= size());
4475  return slice(data(), n);
4476 }
4477 
4478 MDBX_CXX14_CONSTEXPR slice slice::tail(size_t n) const noexcept {
4479  MDBX_CONSTEXPR_ASSERT(n <= size());
4480  return slice(char_ptr() + size() - n, n);
4481 }
4482 
4483 MDBX_CXX14_CONSTEXPR slice slice::middle(size_t from, size_t n) const noexcept {
4484  MDBX_CONSTEXPR_ASSERT(from + n <= size());
4485  return slice(char_ptr() + from, n);
4486 }
4487 
4489  if (MDBX_UNLIKELY(n > size()))
4491  return head(n);
4492 }
4493 
4495  if (MDBX_UNLIKELY(n > size()))
4497  return tail(n);
4498 }
4499 
4500 MDBX_CXX14_CONSTEXPR slice slice::safe_middle(size_t from, size_t n) const {
4501  if (MDBX_UNLIKELY(n > max_length))
4503  if (MDBX_UNLIKELY(from + n > size()))
4505  return middle(from, n);
4506 }
4507 
4509  const slice &b) noexcept {
4510  const intptr_t diff = intptr_t(a.length()) - intptr_t(b.length());
4511  return diff ? diff
4512  : MDBX_UNLIKELY(a.length() == 0 || a.data() == b.data())
4513  ? 0
4514  : memcmp(a.data(), b.data(), a.length());
4515 }
4516 
4517 MDBX_CXX14_CONSTEXPR intptr_t
4518 slice::compare_lexicographically(const slice &a, const slice &b) noexcept {
4519  const size_t shortest = ::std::min(a.length(), b.length());
4520  if (MDBX_LIKELY(shortest > 0))
4522  const intptr_t diff = memcmp(a.data(), b.data(), shortest);
4523  if (MDBX_LIKELY(diff != 0))
4524  MDBX_CXX20_LIKELY return diff;
4525  }
4526  return intptr_t(a.length()) - intptr_t(b.length());
4527 }
4528 
4530 operator==(const slice &a, const slice &b) noexcept {
4531  return slice::compare_fast(a, b) == 0;
4532 }
4533 
4535 operator<(const slice &a, const slice &b) noexcept {
4536  return slice::compare_lexicographically(a, b) < 0;
4537 }
4538 
4540 operator>(const slice &a, const slice &b) noexcept {
4541  return slice::compare_lexicographically(a, b) > 0;
4542 }
4543 
4545 operator<=(const slice &a, const slice &b) noexcept {
4546  return slice::compare_lexicographically(a, b) <= 0;
4547 }
4548 
4550 operator>=(const slice &a, const slice &b) noexcept {
4551  return slice::compare_lexicographically(a, b) >= 0;
4552 }
4553 
4555 operator!=(const slice &a, const slice &b) noexcept {
4556  return slice::compare_fast(a, b) != 0;
4557 }
4558 
4559 template <class ALLOCATOR>
4560 inline string<ALLOCATOR>
4561 slice::as_hex_string(bool uppercase, unsigned wrap_width,
4562  const ALLOCATOR &allocator) const {
4563  return to_hex(*this, uppercase, wrap_width).as_string<ALLOCATOR>(allocator);
4564 }
4565 
4566 template <class ALLOCATOR>
4567 inline string<ALLOCATOR>
4568 slice::as_base58_string(unsigned wrap_width, const ALLOCATOR &allocator) const {
4569  return to_base58(*this, wrap_width).as_string<ALLOCATOR>(allocator);
4570 }
4571 
4572 template <class ALLOCATOR>
4573 inline string<ALLOCATOR>
4574 slice::as_base64_string(unsigned wrap_width, const ALLOCATOR &allocator) const {
4575  return to_base64(*this, wrap_width).as_string<ALLOCATOR>(allocator);
4576 }
4577 
4578 template <class ALLOCATOR, class CAPACITY_POLICY>
4580 slice::encode_hex(bool uppercase, unsigned wrap_width,
4581  const ALLOCATOR &allocator) const {
4582  return to_hex(*this, uppercase, wrap_width)
4583  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4584 }
4585 
4586 template <class ALLOCATOR, class CAPACITY_POLICY>
4588 slice::encode_base58(unsigned wrap_width, const ALLOCATOR &allocator) const {
4589  return to_base58(*this, wrap_width)
4590  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4591 }
4592 
4593 template <class ALLOCATOR, class CAPACITY_POLICY>
4595 slice::encode_base64(unsigned wrap_width, const ALLOCATOR &allocator) const {
4596  return to_base64(*this, wrap_width)
4597  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4598 }
4599 
4600 template <class ALLOCATOR, class CAPACITY_POLICY>
4602 slice::hex_decode(bool ignore_spaces, const ALLOCATOR &allocator) const {
4603  return from_hex(*this, ignore_spaces)
4604  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4605 }
4606 
4607 template <class ALLOCATOR, class CAPACITY_POLICY>
4609 slice::base58_decode(bool ignore_spaces, const ALLOCATOR &allocator) const {
4610  return from_base58(*this, ignore_spaces)
4611  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4612 }
4613 
4614 template <class ALLOCATOR, class CAPACITY_POLICY>
4616 slice::base64_decode(bool ignore_spaces, const ALLOCATOR &allocator) const {
4617  return from_base64(*this, ignore_spaces)
4618  .as_buffer<ALLOCATOR, CAPACITY_POLICY>(allocator);
4619 }
4620 
4621 inline MDBX_NOTHROW_PURE_FUNCTION bool
4622 slice::is_hex(bool ignore_spaces) const noexcept {
4623  return !from_hex(*this, ignore_spaces).is_erroneous();
4624 }
4625 
4626 inline MDBX_NOTHROW_PURE_FUNCTION bool
4627 slice::is_base58(bool ignore_spaces) const noexcept {
4628  return !from_base58(*this, ignore_spaces).is_erroneous();
4629 }
4630 
4631 inline MDBX_NOTHROW_PURE_FUNCTION bool
4632 slice::is_base64(bool ignore_spaces) const noexcept {
4633  return !from_base64(*this, ignore_spaces).is_erroneous();
4634 }
4635 
4636 //------------------------------------------------------------------------------
4637 
4638 template <class ALLOCATOR, typename CAPACITY_POLICY>
4640  const txn &txn, const struct slice &src, const allocator_type &allocator)
4641  : buffer(src, !txn.is_dirty(src.data()), allocator) {}
4642 
4643 //------------------------------------------------------------------------------
4644 
4646  map_handle::state state) noexcept
4647  : flags(flags), state(state) {}
4648 
4649 #if CONSTEXPR_ENUM_FLAGS_OPERATIONS
4651 #endif
4654 }
4655 
4656 #if CONSTEXPR_ENUM_FLAGS_OPERATIONS
4658 #endif
4662 }
4663 
4664 //------------------------------------------------------------------------------
4665 
4666 MDBX_CXX11_CONSTEXPR env::env(MDBX_env *ptr) noexcept : handle_(ptr) {}
4667 
4668 inline env &env::operator=(env &&other) noexcept {
4669  handle_ = other.handle_;
4670  other.handle_ = nullptr;
4671  return *this;
4672 }
4673 
4674 inline env::env(env &&other) noexcept : handle_(other.handle_) {
4675  other.handle_ = nullptr;
4676 }
4677 
4678 inline env::~env() noexcept {
4679 #ifndef NDEBUG
4680  handle_ = reinterpret_cast<MDBX_env *>(uintptr_t(0xDeadBeef));
4681 #endif
4682 }
4683 
4684 MDBX_CXX14_CONSTEXPR env::operator bool() const noexcept {
4685  return handle_ != nullptr;
4686 }
4687 
4688 MDBX_CXX14_CONSTEXPR env::operator const MDBX_env *() const { return handle_; }
4689 
4690 MDBX_CXX14_CONSTEXPR env::operator MDBX_env *() { return handle_; }
4691 
4692 MDBX_CXX11_CONSTEXPR bool operator==(const env &a, const env &b) noexcept {
4693  return a.handle_ == b.handle_;
4694 }
4695 
4696 MDBX_CXX11_CONSTEXPR bool operator!=(const env &a, const env &b) noexcept {
4697  return a.handle_ != b.handle_;
4698 }
4699 
4700 inline env::geometry &env::geometry::make_fixed(intptr_t size) noexcept {
4701  size_lower = size_now = size_upper = size;
4702  growth_step = shrink_threshold = 0;
4703  return *this;
4704 }
4705 
4707  intptr_t upper) noexcept {
4708  size_now = size_lower = lower;
4709  size_upper = upper;
4710  growth_step = shrink_threshold = default_value;
4711  return *this;
4712 }
4713 
4715  MDBX_env_flags_t flags) noexcept {
4716  return reclaiming_options(flags);
4717 }
4718 
4719 inline env::operate_options
4721  return operate_options(flags);
4722 }
4723 
4724 inline size_t env::limits::pagesize_min() noexcept { return MDBX_MIN_PAGESIZE; }
4725 
4726 inline size_t env::limits::pagesize_max() noexcept { return MDBX_MAX_PAGESIZE; }
4727 
4728 inline size_t env::limits::dbsize_min(intptr_t pagesize) {
4729  const intptr_t result = mdbx_limits_dbsize_min(pagesize);
4730  if (result < 0)
4732  return static_cast<size_t>(result);
4733 }
4734 
4735 inline size_t env::limits::dbsize_max(intptr_t pagesize) {
4736  const intptr_t result = mdbx_limits_dbsize_max(pagesize);
4737  if (result < 0)
4739  return static_cast<size_t>(result);
4740 }
4741 
4742 inline size_t env::limits::key_min(MDBX_db_flags_t flags) noexcept {
4743  return (flags & MDBX_INTEGERKEY) ? 4 : 0;
4744 }
4745 
4746 inline size_t env::limits::key_min(key_mode mode) noexcept {
4747  return key_min(MDBX_db_flags_t(mode));
4748 }
4749 
4750 inline size_t env::limits::key_max(intptr_t pagesize, MDBX_db_flags_t flags) {
4751  const intptr_t result = mdbx_limits_keysize_max(pagesize, flags);
4752  if (result < 0)
4754  return static_cast<size_t>(result);
4755 }
4756 
4757 inline size_t env::limits::key_max(intptr_t pagesize, key_mode mode) {
4758  return key_max(pagesize, MDBX_db_flags_t(mode));
4759 }
4760 
4762  const intptr_t result = mdbx_env_get_maxkeysize_ex(env, flags);
4763  if (result < 0)
4765  return static_cast<size_t>(result);
4766 }
4767 
4768 inline size_t env::limits::key_max(const env &env, key_mode mode) {
4769  return key_max(env, MDBX_db_flags_t(mode));
4770 }
4771 
4773  return (flags & MDBX_INTEGERDUP) ? 4 : 0;
4774 }
4775 
4776 inline size_t env::limits::value_min(value_mode mode) noexcept {
4777  return value_min(MDBX_db_flags_t(mode));
4778 }
4779 
4780 inline size_t env::limits::value_max(intptr_t pagesize, MDBX_db_flags_t flags) {
4781  const intptr_t result = mdbx_limits_valsize_max(pagesize, flags);
4782  if (result < 0)
4784  return static_cast<size_t>(result);
4785 }
4786 
4787 inline size_t env::limits::value_max(intptr_t pagesize, value_mode mode) {
4788  return value_max(pagesize, MDBX_db_flags_t(mode));
4789 }
4790 
4792  const intptr_t result = mdbx_env_get_maxvalsize_ex(env, flags);
4793  if (result < 0)
4795  return static_cast<size_t>(result);
4796 }
4797 
4799  return value_max(env, MDBX_db_flags_t(mode));
4800 }
4801 
4802 inline size_t env::limits::transaction_size_max(intptr_t pagesize) {
4803  const intptr_t result = mdbx_limits_txnsize_max(pagesize);
4804  if (result < 0)
4806  return static_cast<size_t>(result);
4807 }
4808 
4810  const auto flags = get_flags();
4811  return operate_parameters(max_maps(), max_readers(),
4812  operate_parameters::mode_from_flags(flags),
4813  operate_parameters::durability_from_flags(flags),
4814  operate_parameters::reclaiming_from_flags(flags),
4815  operate_parameters::options_from_flags(flags));
4816 }
4817 
4818 inline env::mode env::get_mode() const {
4819  return operate_parameters::mode_from_flags(get_flags());
4820 }
4821 
4824 }
4825 
4828 }
4829 
4831  return env::operate_parameters::options_from_flags(get_flags());
4832 }
4833 
4834 inline env::stat env::get_stat() const {
4835  env::stat r;
4836  error::success_or_throw(::mdbx_env_stat_ex(handle_, nullptr, &r, sizeof(r)));
4837  return r;
4838 }
4839 
4840 inline env::stat env::get_stat(const txn &txn) const {
4841  env::stat r;
4842  error::success_or_throw(::mdbx_env_stat_ex(handle_, txn, &r, sizeof(r)));
4843  return r;
4844 }
4845 
4846 inline env::info env::get_info() const {
4847  env::info r;
4848  error::success_or_throw(::mdbx_env_info_ex(handle_, nullptr, &r, sizeof(r)));
4849  return r;
4850 }
4851 
4852 inline env::info env::get_info(const txn &txn) const {
4853  env::info r;
4854  error::success_or_throw(::mdbx_env_info_ex(handle_, txn, &r, sizeof(r)));
4855  return r;
4856 }
4857 
4859  filehandle fd;
4860  error::success_or_throw(::mdbx_env_get_fd(handle_, &fd));
4861  return fd;
4862 }
4863 
4865  unsigned bits;
4866  error::success_or_throw(::mdbx_env_get_flags(handle_, &bits));
4867  return MDBX_env_flags_t(bits);
4868 }
4869 
4870 inline unsigned env::max_readers() const {
4871  unsigned r;
4873  return r;
4874 }
4875 
4876 inline unsigned env::max_maps() const {
4877  unsigned r;
4879  return r;
4880 }
4881 
4882 inline void *env::get_context() const noexcept {
4883  return mdbx_env_get_userctx(handle_);
4884 }
4885 
4886 inline env &env::set_context(void *ptr) {
4888  return *this;
4889 }
4890 
4891 inline env &env::set_sync_threshold(size_t bytes) {
4893  return *this;
4894 }
4895 
4896 inline env &env::set_sync_period(unsigned seconds_16dot16) {
4897  error::success_or_throw(::mdbx_env_set_syncperiod(handle_, seconds_16dot16));
4898  return *this;
4899 }
4900 
4901 inline env &env::set_sync_period(double seconds) {
4902  return set_sync_period(unsigned(seconds * 65536));
4903 }
4904 
4906  error::success_or_throw(::mdbx_env_set_flags(handle_, flags, on_off));
4907  return *this;
4908 }
4909 
4910 inline env &env::set_geometry(const geometry &geo) {
4912  handle_, geo.size_lower, geo.size_now, geo.size_upper, geo.growth_step,
4913  geo.shrink_threshold, geo.pagesize));
4914  return *this;
4915 }
4916 
4917 inline bool env::sync_to_disk(bool force, bool nonblock) {
4918  const int err = ::mdbx_env_sync_ex(handle_, force, nonblock);
4919  switch (err) {
4920  case MDBX_SUCCESS /* flush done */:
4921  case MDBX_RESULT_TRUE /* no data pending for flush to disk */:
4922  return true;
4923  case MDBX_BUSY /* the environment is used by other thread */:
4924  return false;
4925  default:
4927  }
4928 }
4929 
4930 inline void env::close_map(const map_handle &handle) {
4931  error::success_or_throw(::mdbx_dbi_close(*this, handle.dbi));
4932 }
4933 
4936  uint64_t txnid, uint64_t lag, size_t used,
4937  size_t retained) noexcept
4938  : slot(slot), pid(pid), thread(thread), transaction_id(txnid),
4939  transaction_lag(lag), bytes_used(used), bytes_retained(retained) {}
4940 
4941 template <typename VISITOR>
4942 inline int env::enumerate_readers(VISITOR &visitor) {
4943  struct reader_visitor_thunk : public exception_thunk {
4944  VISITOR &visitor_;
4945  static int cb(void *ctx, int number, int slot, mdbx_pid_t pid,
4946  mdbx_tid_t thread, uint64_t txnid, uint64_t lag, size_t used,
4947  size_t retained) noexcept {
4948  reader_visitor_thunk *thunk = static_cast<reader_visitor_thunk *>(ctx);
4949  assert(thunk->is_clean());
4950  try {
4951  const reader_info info(slot, pid, thread, txnid, lag, used, retained);
4952  return loop_control(thunk->visitor_(info, number));
4953  } catch (... /* capture any exception to rethrow it over C code */) {
4954  thunk->capture();
4955  return loop_control::exit_loop;
4956  }
4957  }
4958  MDBX_CXX11_CONSTEXPR reader_visitor_thunk(VISITOR &visitor) noexcept
4959  : visitor_(visitor) {}
4960  };
4961  reader_visitor_thunk thunk(visitor);
4962  const auto rc = ::mdbx_reader_list(*this, thunk.cb, &thunk);
4963  thunk.rethrow_captured();
4964  return rc;
4965 }
4966 
4967 inline unsigned env::check_readers() {
4968  int dead_count;
4969  error::throw_on_failure(::mdbx_reader_check(*this, &dead_count));
4970  assert(dead_count >= 0);
4971  return static_cast<unsigned>(dead_count);
4972 }
4973 
4975  error::success_or_throw(::mdbx_env_set_hsr(handle_, cb));
4976  return *this;
4977 }
4978 
4979 inline MDBX_hsr_func *env::get_HandleSlowReaders() const noexcept {
4980  return ::mdbx_env_get_hsr(handle_);
4981 }
4982 
4984  ::MDBX_txn *ptr;
4986  ::mdbx_txn_begin(handle_, nullptr, MDBX_TXN_RDONLY, &ptr));
4987  assert(ptr != nullptr);
4988  return txn_managed(ptr);
4989 }
4990 
4992  ::MDBX_txn *ptr;
4994  ::mdbx_txn_begin(handle_, nullptr, MDBX_TXN_RDONLY_PREPARE, &ptr));
4995  assert(ptr != nullptr);
4996  return txn_managed(ptr);
4997 }
4998 
4999 inline txn_managed env::start_write(bool dont_wait) {
5000  ::MDBX_txn *ptr;
5002  handle_, nullptr, dont_wait ? MDBX_TXN_TRY : MDBX_TXN_READWRITE, &ptr));
5003  assert(ptr != nullptr);
5004  return txn_managed(ptr);
5005 }
5006 
5007 inline txn_managed env::try_start_write() { return start_write(true); }
5008 
5009 //------------------------------------------------------------------------------
5010 
5011 MDBX_CXX11_CONSTEXPR txn::txn(MDBX_txn *ptr) noexcept : handle_(ptr) {}
5012 
5013 inline txn &txn::operator=(txn &&other) noexcept {
5014  handle_ = other.handle_;
5015  other.handle_ = nullptr;
5016  return *this;
5017 }
5018 
5019 inline txn::txn(txn &&other) noexcept : handle_(other.handle_) {
5020  other.handle_ = nullptr;
5021 }
5022 
5023 inline txn::~txn() noexcept {
5024 #ifndef NDEBUG
5025  handle_ = reinterpret_cast<MDBX_txn *>(uintptr_t(0xDeadBeef));
5026 #endif
5027 }
5028 
5029 MDBX_CXX14_CONSTEXPR txn::operator bool() const noexcept {
5030  return handle_ != nullptr;
5031 }
5032 
5033 MDBX_CXX14_CONSTEXPR txn::operator const MDBX_txn *() const { return handle_; }
5034 
5035 MDBX_CXX14_CONSTEXPR txn::operator MDBX_txn *() { return handle_; }
5036 
5037 MDBX_CXX11_CONSTEXPR bool operator==(const txn &a, const txn &b) noexcept {
5038  return a.handle_ == b.handle_;
5039 }
5040 
5041 MDBX_CXX11_CONSTEXPR bool operator!=(const txn &a, const txn &b) noexcept {
5042  return a.handle_ != b.handle_;
5043 }
5044 
5045 inline bool txn::is_dirty(const void *ptr) const {
5046  int err = ::mdbx_is_dirty(handle_, ptr);
5047  switch (err) {
5048  default:
5050  case MDBX_RESULT_TRUE:
5051  return true;
5052  case MDBX_RESULT_FALSE:
5053  return false;
5054  }
5055 }
5056 
5057 inline ::mdbx::env txn::env() const noexcept { return ::mdbx_txn_env(handle_); }
5058 
5060  const int bits = mdbx_txn_flags(handle_);
5062  return static_cast<MDBX_txn_flags_t>(bits);
5063 }
5064 
5065 inline uint64_t txn::id() const {
5066  const uint64_t txnid = mdbx_txn_id(handle_);
5068  return txnid;
5069 }
5070 
5071 inline void txn::reset_reading() {
5073 }
5074 
5075 inline void txn::renew_reading() {
5077 }
5078 
5079 inline txn::info txn::get_info(bool scan_reader_lock_table) const {
5080  txn::info r;
5081  error::success_or_throw(::mdbx_txn_info(handle_, &r, scan_reader_lock_table));
5082  return r;
5083 }
5084 
5086  MDBX_cursor *ptr;
5087  error::success_or_throw(::mdbx_cursor_open(handle_, map.dbi, &ptr));
5088  return cursor_managed(ptr);
5089 }
5090 
5091 inline ::mdbx::map_handle
5094  ::mdbx::map_handle map;
5097  &map.dbi));
5098  assert(map.dbi != 0);
5099  return map;
5100 }
5101 
5102 inline ::mdbx::map_handle
5105  return open_map(name.c_str(), key_mode, value_mode);
5106 }
5107 
5108 inline ::mdbx::map_handle txn::create_map(const char *name,
5111  ::mdbx::map_handle map;
5113  handle_, name,
5115  &map.dbi));
5116  assert(map.dbi != 0);
5117  return map;
5118 }
5119 
5120 inline ::mdbx::map_handle txn::create_map(const ::std::string &name,
5123  return create_map(name.c_str(), key_mode, value_mode);
5124 }
5125 
5126 inline void txn::drop_map(map_handle map) {
5127  error::success_or_throw(::mdbx_drop(handle_, map.dbi, true));
5128 }
5129 
5130 inline bool txn::drop_map(const ::std::string &name, bool throw_if_absent) {
5131  return drop_map(name.c_str(), throw_if_absent);
5132 }
5133 
5134 inline void txn::clear_map(map_handle map) {
5135  error::success_or_throw(::mdbx_drop(handle_, map.dbi, false));
5136 }
5137 
5138 inline bool txn::clear_map(const ::std::string &name, bool throw_if_absent) {
5139  return clear_map(name.c_str(), throw_if_absent);
5140 }
5141 
5143  txn::map_stat r;
5144  error::success_or_throw(::mdbx_dbi_stat(handle_, map.dbi, &r, sizeof(r)));
5145  return r;
5146 }
5147 
5148 inline uint32_t txn::get_tree_deepmask(map_handle map) const {
5149  uint32_t r;
5151  return r;
5152 }
5153 
5155  unsigned flags, state;
5157  ::mdbx_dbi_flags_ex(handle_, map.dbi, &flags, &state));
5159 }
5160 
5163  return *this;
5164 }
5165 
5167  txn::canary r;
5168  error::success_or_throw(::mdbx_canary_get(handle_, &r));
5169  return r;
5170 }
5171 
5172 inline uint64_t txn::sequence(map_handle map) const {
5173  uint64_t result;
5174  error::success_or_throw(::mdbx_dbi_sequence(handle_, map.dbi, &result, 0));
5175  return result;
5176 }
5177 
5178 inline uint64_t txn::sequence(map_handle map, uint64_t increment) {
5179  uint64_t result;
5181  ::mdbx_dbi_sequence(handle_, map.dbi, &result, increment));
5182  return result;
5183 }
5184 
5185 inline int txn::compare_keys(map_handle map, const slice &a,
5186  const slice &b) const noexcept {
5187  return ::mdbx_cmp(handle_, map.dbi, &a, &b);
5188 }
5189 
5190 inline int txn::compare_values(map_handle map, const slice &a,
5191  const slice &b) const noexcept {
5192  return ::mdbx_dcmp(handle_, map.dbi, &a, &b);
5193 }
5194 
5195 inline int txn::compare_keys(map_handle map, const pair &a,
5196  const pair &b) const noexcept {
5197  return compare_keys(map, a.key, b.key);
5198 }
5199 
5200 inline int txn::compare_values(map_handle map, const pair &a,
5201  const pair &b) const noexcept {
5202  return compare_values(map, a.value, b.value);
5203 }
5204 
5205 inline slice txn::get(map_handle map, const slice &key) const {
5206  slice result;
5207  error::success_or_throw(::mdbx_get(handle_, map.dbi, &key, &result));
5208  return result;
5209 }
5210 
5211 inline slice txn::get(map_handle map, slice key, size_t &values_count) const {
5212  slice result;
5214  ::mdbx_get_ex(handle_, map.dbi, &key, &result, &values_count));
5215  return result;
5216 }
5217 
5218 inline slice txn::get(map_handle map, const slice &key,
5219  const slice &value_at_absence) const {
5220  slice result;
5221  const int err = ::mdbx_get(handle_, map.dbi, &key, &result);
5222  switch (err) {
5223  case MDBX_SUCCESS:
5224  return result;
5225  case MDBX_NOTFOUND:
5226  return value_at_absence;
5227  default:
5229  }
5230 }
5231 
5232 inline slice txn::get(map_handle map, slice key, size_t &values_count,
5233  const slice &value_at_absence) const {
5234  slice result;
5235  const int err = ::mdbx_get_ex(handle_, map.dbi, &key, &result, &values_count);
5236  switch (err) {
5237  case MDBX_SUCCESS:
5238  return result;
5239  case MDBX_NOTFOUND:
5240  return value_at_absence;
5241  default:
5243  }
5244 }
5245 
5247  const slice &key) const {
5248  pair result(key, slice());
5249  bool exact = !error::boolean_or_throw(
5250  ::mdbx_get_equal_or_great(handle_, map.dbi, &result.key, &result.value));
5251  return pair_result(result.key, result.value, exact);
5252 }
5253 
5254 inline pair_result
5256  const slice &value_at_absence) const {
5257  pair result{key, slice()};
5258  const int err =
5259  ::mdbx_get_equal_or_great(handle_, map.dbi, &result.key, &result.value);
5260  switch (err) {
5261  case MDBX_SUCCESS:
5262  return pair_result{result.key, result.value, true};
5263  case MDBX_RESULT_TRUE:
5264  return pair_result{result.key, result.value, false};
5265  case MDBX_NOTFOUND:
5266  return pair_result{key, value_at_absence, false};
5267  default:
5269  }
5270 }
5271 
5272 inline MDBX_error_t txn::put(map_handle map, const slice &key, slice *value,
5273  MDBX_put_flags_t flags) noexcept {
5274  return MDBX_error_t(::mdbx_put(handle_, map.dbi, &key, value, flags));
5275 }
5276 
5277 inline void txn::put(map_handle map, const slice &key, slice value,
5278  put_mode mode) {
5279  error::success_or_throw(put(map, key, &value, MDBX_put_flags_t(mode)));
5280 }
5281 
5282 inline void txn::insert(map_handle map, const slice &key, slice value) {
5284  put(map, key, &value /* takes the present value in case MDBX_KEYEXIST */,
5286 }
5287 
5289  slice value) {
5290  const int err =
5291  put(map, key, &value /* takes the present value in case MDBX_KEYEXIST */,
5293  switch (err) {
5294  case MDBX_SUCCESS:
5295  return value_result{slice(), true};
5296  case MDBX_KEYEXIST:
5297  return value_result{value, false};
5298  default:
5300  }
5301 }
5302 
5304  size_t value_length) {
5305  slice result(nullptr, value_length);
5307  put(map, key, &result /* takes the present value in case MDBX_KEYEXIST */,
5309  return result;
5310 }
5311 
5313  size_t value_length) {
5314  slice result(nullptr, value_length);
5315  const int err =
5316  put(map, key, &result /* takes the present value in case MDBX_KEYEXIST */,
5318  switch (err) {
5319  case MDBX_SUCCESS:
5320  return value_result{result, true};
5321  case MDBX_KEYEXIST:
5322  return value_result{result, false};
5323  default:
5325  }
5326 }
5327 
5328 inline void txn::upsert(map_handle map, const slice &key, const slice &value) {
5329  error::success_or_throw(put(map, key, const_cast<slice *>(&value),
5331 }
5332 
5334  size_t value_length) {
5335  slice result(nullptr, value_length);
5337  map, key, &result, MDBX_put_flags_t(put_mode::upsert) | MDBX_RESERVE));
5338  return result;
5339 }
5340 
5341 inline void txn::update(map_handle map, const slice &key, const slice &value) {
5342  error::success_or_throw(put(map, key, const_cast<slice *>(&value),
5344 }
5345 
5346 inline bool txn::try_update(map_handle map, const slice &key,
5347  const slice &value) {
5348  const int err = put(map, key, const_cast<slice *>(&value),
5350  switch (err) {
5351  case MDBX_SUCCESS:
5352  return true;
5353  case MDBX_NOTFOUND:
5354  return false;
5355  default:
5357  }
5358 }
5359 
5361  size_t value_length) {
5362  slice result(nullptr, value_length);
5364  map, key, &result, MDBX_put_flags_t(put_mode::update) | MDBX_RESERVE));
5365  return result;
5366 }
5367 
5369  size_t value_length) {
5370  slice result(nullptr, value_length);
5371  const int err =
5372  put(map, key, &result, MDBX_put_flags_t(put_mode::update) | MDBX_RESERVE);
5373  switch (err) {
5374  case MDBX_SUCCESS:
5375  return value_result{result, true};
5376  case MDBX_NOTFOUND:
5377  return value_result{slice(), false};
5378  default:
5380  }
5381 }
5382 
5383 inline bool txn::erase(map_handle map, const slice &key) {
5384  const int err = ::mdbx_del(handle_, map.dbi, &key, nullptr);
5385  switch (err) {
5386  case MDBX_SUCCESS:
5387  return true;
5388  case MDBX_NOTFOUND:
5389  return false;
5390  default:
5392  }
5393 }
5394 
5395 inline bool txn::erase(map_handle map, const slice &key, const slice &value) {
5396  const int err = ::mdbx_del(handle_, map.dbi, &key, &value);
5397  switch (err) {
5398  case MDBX_SUCCESS:
5399  return true;
5400  case MDBX_NOTFOUND:
5401  return false;
5402  default:
5404  }
5405 }
5406 
5407 inline void txn::replace(map_handle map, const slice &key, slice old_value,
5408  const slice &new_value) {
5410  handle_, map.dbi, &key, const_cast<slice *>(&new_value), &old_value,
5411  MDBX_CURRENT | MDBX_NOOVERWRITE, nullptr, nullptr));
5412 }
5413 
5414 template <class ALLOCATOR, typename CAPACITY_POLICY>
5418  &allocator) {
5419  typename buffer<ALLOCATOR, CAPACITY_POLICY>::data_preserver result(allocator);
5420  error::success_or_throw(::mdbx_replace_ex(handle_, map.dbi, &key, nullptr,
5421  &result.slice_, MDBX_CURRENT,
5422  result, &result),
5423  result);
5424  return result;
5425 }
5426 
5427 template <class ALLOCATOR, typename CAPACITY_POLICY>
5429 txn::replace(map_handle map, const slice &key, const slice &new_value,
5431  &allocator) {
5432  typename buffer<ALLOCATOR, CAPACITY_POLICY>::data_preserver result(allocator);
5434  ::mdbx_replace_ex(handle_, map.dbi, &key, const_cast<slice *>(&new_value),
5435  &result.slice_, MDBX_CURRENT, result, &result),
5436  result);
5437  return result;
5438 }
5439 
5440 template <class ALLOCATOR, typename CAPACITY_POLICY>
5442  map_handle map, const slice &key, slice &new_value,
5444  &allocator) {
5445  typename buffer<ALLOCATOR, CAPACITY_POLICY>::data_preserver result(allocator);
5447  ::mdbx_replace_ex(handle_, map.dbi, &key, &new_value, &result.slice_,
5448  MDBX_CURRENT | MDBX_RESERVE, result, &result),
5449  result);
5450  return result;
5451 }
5452 
5453 inline void txn::append(map_handle map, const slice &key, const slice &value,
5454  bool multivalue_order_preserved) {
5456  handle_, map.dbi, const_cast<slice *>(&key), const_cast<slice *>(&value),
5457  multivalue_order_preserved ? (MDBX_APPEND | MDBX_APPENDDUP)
5458  : MDBX_APPEND));
5459 }
5460 
5461 inline size_t txn::put_multiple(map_handle map, const slice &key,
5462  const size_t value_length,
5463  const void *values_array, size_t values_count,
5464  put_mode mode, bool allow_partial) {
5465  MDBX_val args[2] = {{const_cast<void *>(values_array), value_length},
5466  {nullptr, values_count}};
5467  const int err = ::mdbx_put(handle_, map.dbi, const_cast<slice *>(&key), args,
5469  switch (err) {
5470  case MDBX_SUCCESS:
5471  MDBX_CXX20_LIKELY break;
5472  case MDBX_KEYEXIST:
5473  if (allow_partial)
5474  break;
5475  mdbx_txn_break(handle_);
5476  MDBX_CXX17_FALLTHROUGH /* fallthrough */;
5477  default:
5479  }
5480  return args[1].iov_len /* done item count */;
5481 }
5482 
5483 inline ptrdiff_t txn::estimate(map_handle map, pair from, pair to) const {
5484  ptrdiff_t result;
5486  handle_, map.dbi, &from.key, &from.value, &to.key, &to.value, &result));
5487  return result;
5488 }
5489 
5490 inline ptrdiff_t txn::estimate(map_handle map, slice from, slice to) const {
5491  ptrdiff_t result;
5492  error::success_or_throw(mdbx_estimate_range(handle_, map.dbi, &from, nullptr,
5493  &to, nullptr, &result));
5494  return result;
5495 }
5496 
5497 inline ptrdiff_t txn::estimate_from_first(map_handle map, slice to) const {
5498  ptrdiff_t result;
5499  error::success_or_throw(mdbx_estimate_range(handle_, map.dbi, nullptr,
5500  nullptr, &to, nullptr, &result));
5501  return result;
5502 }
5503 
5504 inline ptrdiff_t txn::estimate_to_last(map_handle map, slice from) const {
5505  ptrdiff_t result;
5506  error::success_or_throw(mdbx_estimate_range(handle_, map.dbi, &from, nullptr,
5507  nullptr, nullptr, &result));
5508  return result;
5509 }
5510 
5511 //------------------------------------------------------------------------------
5512 
5513 MDBX_CXX11_CONSTEXPR cursor::cursor(MDBX_cursor *ptr) noexcept : handle_(ptr) {}
5514 
5515 inline cursor &cursor::operator=(cursor &&other) noexcept {
5516  handle_ = other.handle_;
5517  other.handle_ = nullptr;
5518  return *this;
5519 }
5520 
5521 inline cursor::cursor(cursor &&other) noexcept : handle_(other.handle_) {
5522  other.handle_ = nullptr;
5523 }
5524 
5525 inline cursor::~cursor() noexcept {
5526 #ifndef NDEBUG
5527  handle_ = reinterpret_cast<MDBX_cursor *>(uintptr_t(0xDeadBeef));
5528 #endif
5529 }
5530 
5531 MDBX_CXX14_CONSTEXPR cursor::operator bool() const noexcept {
5532  return handle_ != nullptr;
5533 }
5534 
5535 MDBX_CXX14_CONSTEXPR cursor::operator const MDBX_cursor *() const {
5536  return handle_;
5537 }
5538 
5539 MDBX_CXX14_CONSTEXPR cursor::operator MDBX_cursor *() { return handle_; }
5540 
5542  const cursor &b) noexcept {
5543  return a.handle_ == b.handle_;
5544 }
5545 
5547  const cursor &b) noexcept {
5548  return a.handle_ != b.handle_;
5549 }
5550 
5552  bool throw_notfound)
5553  : pair_result(key, value, false) {
5554  done = cursor.move(get_current, &key, &value, throw_notfound);
5555 }
5556 
5558  move_operation operation,
5559  bool throw_notfound)
5560  : pair_result(key, value, false) {
5561  done = cursor.move(operation, &key, &value, throw_notfound);
5562 }
5563 
5565  move_operation operation,
5566  const slice &key, bool throw_notfound)
5567  : pair_result(key, slice(), false) {
5568  this->done = cursor.move(operation, &this->key, &this->value, throw_notfound);
5569 }
5570 
5572  move_operation operation,
5573  const slice &key, const slice &value,
5574  bool throw_notfound)
5575  : pair_result(key, value, false) {
5576  this->done = cursor.move(operation, &this->key, &this->value, throw_notfound);
5577 }
5578 
5579 inline bool cursor::move(move_operation operation, MDBX_val *key,
5580  MDBX_val *value, bool throw_notfound) const {
5581  const int err =
5582  ::mdbx_cursor_get(handle_, key, value, MDBX_cursor_op(operation));
5583  switch (err) {
5584  case MDBX_SUCCESS:
5585  MDBX_CXX20_LIKELY return true;
5586  case MDBX_NOTFOUND:
5587  if (!throw_notfound)
5588  return false;
5589  MDBX_CXX17_FALLTHROUGH /* fallthrough */;
5590  default:
5592  }
5593 }
5594 
5595 inline ptrdiff_t cursor::estimate(move_operation operation, MDBX_val *key,
5596  MDBX_val *value) const {
5597  ptrdiff_t result;
5599  *this, key, value, MDBX_cursor_op(operation), &result));
5600  return result;
5601 }
5602 
5603 inline ptrdiff_t estimate(const cursor &from, const cursor &to) {
5604  ptrdiff_t result;
5605  error::success_or_throw(mdbx_estimate_distance(from, to, &result));
5606  return result;
5607 }
5608 
5610  bool throw_notfound) {
5611  return move_result(*this, operation, throw_notfound);
5612 }
5613 
5614 inline cursor::move_result cursor::to_first(bool throw_notfound) {
5615  return move(first, throw_notfound);
5616 }
5617 
5618 inline cursor::move_result cursor::to_previous(bool throw_notfound) {
5619  return move(previous, throw_notfound);
5620 }
5621 
5623  return move(multi_prevkey_lastvalue, throw_notfound);
5624 }
5625 
5627  return move(multi_currentkey_firstvalue, throw_notfound);
5628 }
5629 
5631  return move(multi_currentkey_prevvalue, throw_notfound);
5632 }
5633 
5634 inline cursor::move_result cursor::current(bool throw_notfound) const {
5635  return move_result(*this, throw_notfound);
5636 }
5637 
5639  return move(multi_currentkey_nextvalue, throw_notfound);
5640 }
5641 
5643  return move(multi_currentkey_lastvalue, throw_notfound);
5644 }
5645 
5647  return move(multi_nextkey_firstvalue, throw_notfound);
5648 }
5649 
5650 inline cursor::move_result cursor::to_next(bool throw_notfound) {
5651  return move(next, throw_notfound);
5652 }
5653 
5654 inline cursor::move_result cursor::to_last(bool throw_notfound) {
5655  return move(last, throw_notfound);
5656 }
5657 
5659  const slice &key, bool throw_notfound) {
5660  return move_result(*this, operation, key, throw_notfound);
5661 }
5662 
5663 inline cursor::move_result cursor::find(const slice &key, bool throw_notfound) {
5664  return move(key_exact, key, throw_notfound);
5665 }
5666 
5668  bool throw_notfound) {
5669  return move(key_lowerbound, key, throw_notfound);
5670 }
5671 
5673  const slice &key, const slice &value,
5674  bool throw_notfound) {
5675  return move_result(*this, operation, key, value, throw_notfound);
5676 }
5677 
5679  const slice &value,
5680  bool throw_notfound) {
5681  return move(multi_find_pair, key, value, throw_notfound);
5682 }
5683 
5685  const slice &value,
5686  bool throw_notfound) {
5687  return move(multi_exactkey_lowerboundvalue, key, value, throw_notfound);
5688 }
5689 
5690 inline bool cursor::seek(const slice &key) {
5691  return move(find_key, const_cast<slice *>(&key), nullptr, false);
5692 }
5693 
5694 inline bool cursor::move(move_operation operation, slice &key, slice &value,
5695  bool throw_notfound) {
5696  return move(operation, &key, &value, throw_notfound);
5697 }
5698 
5699 inline size_t cursor::count_multivalue() const {
5700  size_t result;
5701  error::success_or_throw(::mdbx_cursor_count(*this, &result));
5702  return result;
5703 }
5704 
5705 inline bool cursor::eof() const {
5706  return error::boolean_or_throw(::mdbx_cursor_eof(*this));
5707 }
5708 
5709 inline bool cursor::on_first() const {
5711 }
5712 
5713 inline bool cursor::on_last() const {
5715 }
5716 
5717 inline ptrdiff_t cursor::estimate(slice key, slice value) const {
5718  return estimate(multi_exactkey_lowerboundvalue, &key, &value);
5719 }
5720 
5721 inline ptrdiff_t cursor::estimate(slice key) const {
5722  return estimate(key_lowerbound, &key, nullptr);
5723 }
5724 
5725 inline ptrdiff_t cursor::estimate(move_operation operation) const {
5726  slice unused_key;
5727  return estimate(operation, &unused_key, nullptr);
5728 }
5729 
5730 inline void cursor::renew(::mdbx::txn &txn) {
5732 }
5733 
5736 }
5737 
5738 inline txn cursor::txn() const {
5741  return ::mdbx::txn(txn);
5742 }
5743 
5744 inline map_handle cursor::map() const {
5745  const MDBX_dbi dbi = ::mdbx_cursor_dbi(handle_);
5746  if (MDBX_UNLIKELY(dbi > MDBX_MAX_DBI))
5748  return map_handle(dbi);
5749 }
5750 
5751 inline MDBX_error_t cursor::put(const slice &key, slice *value,
5752  MDBX_put_flags_t flags) noexcept {
5753  return MDBX_error_t(::mdbx_cursor_put(handle_, &key, value, flags));
5754 }
5755 
5756 inline void cursor::insert(const slice &key, slice value) {
5758  put(key, &value /* takes the present value in case MDBX_KEYEXIST */,
5760 }
5761 
5762 inline value_result cursor::try_insert(const slice &key, slice value) {
5763  const int err =
5764  put(key, &value /* takes the present value in case MDBX_KEYEXIST */,
5766  switch (err) {
5767  case MDBX_SUCCESS:
5768  return value_result{slice(), true};
5769  case MDBX_KEYEXIST:
5770  return value_result{value, false};
5771  default:
5773  }
5774 }
5775 
5776 inline slice cursor::insert_reserve(const slice &key, size_t value_length) {
5777  slice result(nullptr, value_length);
5779  put(key, &result /* takes the present value in case MDBX_KEYEXIST */,
5781  return result;
5782 }
5783 
5785  size_t value_length) {
5786  slice result(nullptr, value_length);
5787  const int err =
5788  put(key, &result /* takes the present value in case MDBX_KEYEXIST */,
5790  switch (err) {
5791  case MDBX_SUCCESS:
5792  return value_result{result, true};
5793  case MDBX_KEYEXIST:
5794  return value_result{result, false};
5795  default:
5797  }
5798 }
5799 
5800 inline void cursor::upsert(const slice &key, const slice &value) {
5801  error::success_or_throw(put(key, const_cast<slice *>(&value),
5803 }
5804 
5805 inline slice cursor::upsert_reserve(const slice &key, size_t value_length) {
5806  slice result(nullptr, value_length);
5809  return result;
5810 }
5811 
5812 inline void cursor::update(const slice &key, const slice &value) {
5813  error::success_or_throw(put(key, const_cast<slice *>(&value),
5815 }
5816 
5817 inline bool cursor::try_update(const slice &key, const slice &value) {
5818  const int err =
5819  put(key, const_cast<slice *>(&value), MDBX_put_flags_t(put_mode::update));
5820  switch (err) {
5821  case MDBX_SUCCESS:
5822  return true;
5823  case MDBX_NOTFOUND:
5824  return false;
5825  default:
5827  }
5828 }
5829 
5830 inline slice cursor::update_reserve(const slice &key, size_t value_length) {
5831  slice result(nullptr, value_length);
5834  return result;
5835 }
5836 
5838  size_t value_length) {
5839  slice result(nullptr, value_length);
5840  const int err =
5842  switch (err) {
5843  case MDBX_SUCCESS:
5844  return value_result{result, true};
5845  case MDBX_NOTFOUND:
5846  return value_result{slice(), false};
5847  default:
5849  }
5850 }
5851 
5852 inline bool cursor::erase(bool whole_multivalue) {
5853  const int err = ::mdbx_cursor_del(handle_, whole_multivalue ? MDBX_ALLDUPS
5854  : MDBX_CURRENT);
5855  switch (err) {
5856  case MDBX_SUCCESS:
5857  MDBX_CXX20_LIKELY return true;
5858  case MDBX_NOTFOUND:
5859  return false;
5860  default:
5862  }
5863 }
5864 
5865 inline bool cursor::erase(const slice &key, bool whole_multivalue) {
5866  bool found = seek(key);
5867  return found ? erase(whole_multivalue) : found;
5868 }
5869 
5870 inline bool cursor::erase(const slice &key, const slice &value) {
5871  move_result data = find_multivalue(key, value, false);
5872  return data.done && erase();
5873 }
5874 
5875 } // namespace mdbx
5876 
5877 //------------------------------------------------------------------------------
5878 
5879 namespace std {
5880 
5881 inline string to_string(const ::mdbx::slice &value) {
5882  ostringstream out;
5883  out << value;
5884  return out.str();
5885 }
5886 
5887 template <class ALLOCATOR, typename CAPACITY_POLICY>
5888 inline string
5889 to_string(const ::mdbx::buffer<ALLOCATOR, CAPACITY_POLICY> &buffer) {
5890  ostringstream out;
5891  out << buffer;
5892  return out.str();
5893 }
5894 
5895 inline string to_string(const ::mdbx::pair &value) {
5896  ostringstream out;
5897  out << value;
5898  return out.str();
5899 }
5900 
5901 inline string to_string(const ::mdbx::env::geometry &value) {
5902  ostringstream out;
5903  out << value;
5904  return out.str();
5905 }
5906 
5907 inline string to_string(const ::mdbx::env::operate_parameters &value) {
5908  ostringstream out;
5909  out << value;
5910  return out.str();
5911 }
5912 
5913 inline string to_string(const ::mdbx::env::mode &value) {
5914  ostringstream out;
5915  out << value;
5916  return out.str();
5917 }
5918 
5919 inline string to_string(const ::mdbx::env::durability &value) {
5920  ostringstream out;
5921  out << value;
5922  return out.str();
5923 }
5924 
5925 inline string to_string(const ::mdbx::env::reclaiming_options &value) {
5926  ostringstream out;
5927  out << value;
5928  return out.str();
5929 }
5930 
5931 inline string to_string(const ::mdbx::env::operate_options &value) {
5932  ostringstream out;
5933  out << value;
5934  return out.str();
5935 }
5936 
5937 inline string to_string(const ::mdbx::env_managed::create_parameters &value) {
5938  ostringstream out;
5939  out << value;
5940  return out.str();
5941 }
5942 
5943 inline string to_string(const ::MDBX_log_level_t &value) {
5944  ostringstream out;
5945  out << value;
5946  return out.str();
5947 }
5948 
5949 inline string to_string(const ::MDBX_debug_flags_t &value) {
5950  ostringstream out;
5951  out << value;
5952  return out.str();
5953 }
5954 
5955 inline string to_string(const ::mdbx::error &value) {
5956  ostringstream out;
5957  out << value;
5958  return out.str();
5959 }
5960 
5961 inline string to_string(const ::MDBX_error_t &errcode) {
5962  return to_string(::mdbx::error(errcode));
5963 }
5964 
5965 template <> struct hash<::mdbx::slice> {
5966  MDBX_CXX14_CONSTEXPR size_t
5967  operator()(::mdbx::slice const &slice) const noexcept {
5968  return slice.hash_value();
5969  }
5970 };
5971 
5972 } // namespace std
5973 
5974 #ifdef _MSC_VER
5975 #pragma warning(pop)
5976 #endif
5977 
mdbx::pair::pair
pair(const slice &key, const slice &value) noexcept
Definition: mdbx.h++:2715
mdbx::cursor::on_first
bool on_first() const
Definition: mdbx.h++:5709
mdbx::to_base64
Base64 encoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1241
mdbx::from_base58::source
const slice source
Definition: mdbx.h++:1352
mdbx::cursor::multi_exactkey_lowerboundvalue
@ multi_exactkey_lowerboundvalue
Definition: mdbx.h++:3863
mdbx::error::panic_on_failure
void panic_on_failure(const char *context_where, const char *func_who) const noexcept
Definition: mdbx.h++:4208
mdbx::slice::slice
MDBX_CXX20_CONSTEXPR slice(const ::std::basic_string< CHAR, T, A > &str)
Create a slice that refers to the contents of "str".
Definition: mdbx.h++:593
MDBX_RESERVE
@ MDBX_RESERVE
Definition: mdbx.h:1497
mdbx::env::get_info
info get_info() const
Return snapshot information about the MDBX environment.
Definition: mdbx.h++:4846
mdbx::slice::slice
slice(::std::basic_string_view< CHAR, T > &&sv)
Definition: mdbx.h++:609
mdbx::env::limits::dbsize_min
static size_t dbsize_min(intptr_t pagesize)
Returns the minimal database size in bytes for specified page size.
Definition: mdbx.h++:4728
mdbx::slice::as_string
MDBX_CXX20_CONSTEXPR ::std::basic_string< CHAR, T, ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Definition: mdbx.h++:687
mdbx::buffer::silo::bin::allocated::allocated
constexpr allocated(allocator_pointer ptr, size_t bytes) noexcept
Definition: mdbx.h++:1523
mdbx::slice::is_null
MDBX_CXX11_CONSTEXPR bool is_null() const noexcept
Checks whether the slice data pointer is nullptr.
Definition: mdbx.h++:4402
MDBX_ASSERT_CXX20_CONCEPT_SATISFIED
#define MDBX_ASSERT_CXX20_CONCEPT_SATISFIED(CONCEPT, TYPE)
Definition: mdbx.h++:226
mdbx::cursor::multi_currentkey_lastvalue
@ multi_currentkey_lastvalue
Definition: mdbx.h++:3859
mdbx::from_base58::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1390
mdbx_key_from_ptrdouble
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_ptrdouble(const double *const ieee754_64bit)
mdbx::cursor::to_next
move_result to_next(bool throw_notfound=true)
Definition: mdbx.h++:5650
mdbx::error::is_success
MDBX_CXX11_CONSTEXPR bool is_success() const noexcept
Definition: mdbx.h++:4160
mdbx::cursor::multi_find_pair
@ multi_find_pair
Definition: mdbx.h++:3862
MDBX_dbi_state_t
MDBX_dbi_state_t
DBI state bits returted by mdbx_dbi_flags_ex()
Definition: mdbx.h:3849
mdbx::env::set_sync_period
env & set_sync_period(unsigned seconds_16dot16)
Sets relative period since the last unsteady commit to force flush the data buffers to disk,...
Definition: mdbx.h++:4896
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const char *c_str, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2169
mdbx::buffer::buffer
buffer(size_t capacity, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2188
mdbx::error::throw_on_failure
void throw_on_failure() const
Definition: mdbx.h++:4190
mdbx::txn::id
uint64_t id() const
Return the transaction's ID.
Definition: mdbx.h++:5065
mdbx::env::durability
durability
Durability level.
Definition: mdbx.h++:2995
MDBX_MAX_DBI
@ MDBX_MAX_DBI
Definition: mdbx.h:765
mdbx::txn::extract
buffer< ALLOCATOR, CAPACITY_POLICY > extract(map_handle map, const slice &key, const typename buffer< ALLOCATOR, CAPACITY_POLICY >::allocator_type &allocator=buffer< ALLOCATOR, CAPACITY_POLICY >::allocator_type())
Removes and return a value of the key.
Definition: mdbx.h++:5416
mdbx::env::limits
Definition: mdbx.h++:3098
mdbx::key_mode::reverse
@ reverse
mdbx_cursor_bind
LIBMDBX_API int mdbx_cursor_bind(MDBX_txn *txn, MDBX_cursor *cursor, MDBX_dbi dbi)
Bind cursor to specified transaction and DBI handle.
mdbx::buffer::assign
buffer & assign(const ::std::basic_string< CHAR, T, A > &str, bool make_reference=false)
Definition: mdbx.h++:2310
mdbx::from_base64::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1439
mdbx::env::get_stat
stat get_stat() const
Returns snapshot statistics about the MDBX environment.
Definition: mdbx.h++:4834
mdbx_cursor_get
LIBMDBX_API int mdbx_cursor_get(MDBX_cursor *cursor, MDBX_val *key, MDBX_val *data, MDBX_cursor_op op)
Retrieve by cursor.
mdbx::buffer::silo::bin::operator=
MDBX_CXX17_CONSTEXPR bin & operator=(bin &&ditto) noexcept
Definition: mdbx.h++:1657
mdbx::get_build
const MDBX_CXX11_CONSTEXPR build_info & get_build() noexcept
Returns libmdbx build information.
Definition: mdbx.h++:4063
mdbx::to_base58::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the buffer size in bytes needed for Base58 dump of passed slice.
Definition: mdbx.h++:1213
mdbx::cursor::find_multivalue
move_result find_multivalue(const slice &key, const slice &value, bool throw_notfound=true)
Definition: mdbx.h++:5678
MDBX_SET_KEY
@ MDBX_SET_KEY
Definition: mdbx.h:1598
mdbx::buffer::clear
void clear() noexcept
Clears the contents and storage.
Definition: mdbx.h++:2415
mdbx::env::limits::key_max
static size_t key_max(intptr_t pagesize, MDBX_db_flags_t flags)
Returns the maximal key size in bytes for specified page size and database flags.
Definition: mdbx.h++:4750
MDBX_version_info
libmdbx version information
Definition: mdbx.h:613
mdbx::to_base64::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1286
mdbx::buffer::safe_remove_suffix
void safe_remove_suffix(size_t n)
Drops the last "n" bytes from the data chunk.
Definition: mdbx.h++:2437
mdbx::buffer::silo::bin::~bin
MDBX_CXX20_CONSTEXPR ~bin()
Definition: mdbx.h++:1621
mdbx::allocation_aware_details::copy_assign_alloc< T, A, true >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:1030
mdbx::map_handle::info
Definition: mdbx.h++:2848
mdbx::insert_unique
@ insert_unique
Insert only unique keys.
Definition: mdbx.h++:2872
mdbx::env::get_reclaiming
env::reclaiming_options get_reclaiming() const
Returns current reclaiming options.
Definition: mdbx.h++:4826
mdbx::cursor::update_reserve
slice update_reserve(const slice &key, size_t value_length)
Definition: mdbx.h++:5830
mdbx::slice::compare_fast
static MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR intptr_t compare_fast(const slice &a, const slice &b) noexcept
Three-way fast non-lexicographically length-based comparison.
Definition: mdbx.h++:4508
mdbx::buffer::assign
buffer & assign(const ::MDBX_val &src, bool make_reference=false)
Definition: mdbx.h++:2285
mdbx::buffer::starts_with
MDBX_NOTHROW_PURE_FUNCTION bool starts_with(const struct slice &prefix) const noexcept
Checks if the data starts with the given prefix.
Definition: mdbx.h++:2404
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const struct slice &src, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2148
mdbx::buffer::byte_ptr
MDBX_CXX11_CONSTEXPR byte * byte_ptr() noexcept
Returns casted to pointer to byte an address of data.
Definition: mdbx.h++:2017
mdbx::txn::put_multiple
void put_multiple(map_handle map, const slice &key, const ::std::vector< VALUE > &vector, put_mode mode)
Definition: mdbx.h++:3769
mdbx::env_managed::operator=
env_managed & operator=(env_managed &&other)
Definition: mdbx.h++:3500
mdbx::map_handle::info::flags
map_handle::flags flags
Definition: mdbx.h++:2849
mdbx::SliceTranscoder
concept SliceTranscoder
Definition: mdbx.h++:527
mdbx::cursor::multi_nextkey_firstvalue
@ multi_nextkey_firstvalue
Definition: mdbx.h++:3860
mdbx::cursor::multi_currentkey_firstvalue
@ multi_currentkey_firstvalue
Definition: mdbx.h++:3856
mdbx_filehandle_t
int mdbx_filehandle_t
Definition: mdbx.h:196
mdbx_env_stat_ex
LIBMDBX_API int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, MDBX_stat *stat, size_t bytes)
Return statistics about the MDBX environment.
mdbx::map_handle::dbi
MDBX_dbi dbi
Definition: mdbx.h++:2839
mdbx::env::sync_to_disk
bool sync_to_disk(bool force=true, bool nonblock=false)
Flush the environment data buffers.
Definition: mdbx.h++:4917
mdbx::txn::insert
void insert(map_handle map, const slice &key, slice value)
Definition: mdbx.h++:5282
MDBX_ENV_JUST_DELETE
@ MDBX_ENV_JUST_DELETE
Just delete the environment's files and directory if any.
Definition: mdbx.h:2184
mdbx::buffer::char_ptr
const MDBX_CXX11_CONSTEXPR char * char_ptr() const noexcept
Returns casted to const pointer to char an address of data.
Definition: mdbx.h++:2031
mdbx_key_from_float
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint32_t mdbx_key_from_float(const float ieee754_32bit)
mdbx::buffer::char_ptr
MDBX_CXX11_CONSTEXPR char * char_ptr() noexcept
Returns casted to pointer to char an address of data.
Definition: mdbx.h++:2043
mdbx_build
LIBMDBX_VERINFO_API const struct MDBX_build_info mdbx_build
libmdbx build information
mdbx::txn::get_info
info get_info(bool scan_reader_lock_table=false) const
Returns information about the MDBX transaction.
Definition: mdbx.h++:5079
mdbx::buffer::assign
buffer & assign(const struct slice &src, bool make_reference=false)
Definition: mdbx.h++:2281
mdbx::default_capacity_policy::round
static MDBX_CXX11_CONSTEXPR size_t round(const size_t value)
Definition: mdbx.h++:1102
mdbx::fatal::fatal
fatal(const fatal &src) noexcept
Definition: mdbx.h++:448
MDBX_CXX20_LIKELY
#define MDBX_CXX20_LIKELY
Definition: mdbx.h++:190
mdbx::slice::swap
void swap(::std::basic_string_view< CHAR, T > &view) noexcept
Definition: mdbx.h++:801
mdbx_txn_begin
int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, MDBX_txn **txn)
Create a transaction for use with the environment.
Definition: mdbx.h:3262
mdbx_limits_txnsize_max
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_txnsize_max(intptr_t pagesize)
Returns maximal write transaction size (i.e. limit for summary volume of dirty pages) in bytes for gi...
mdbx::env::reader_info
Reader information.
Definition: mdbx.h++:3357
mdbx::error::is_mdbx_error
MDBX_CXX11_CONSTEXPR bool is_mdbx_error() const noexcept
Returns true for MDBX's errors.
Definition: mdbx.h++:4178
mdbx::from_base58
Base58 decoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1351
mdbx::cursor_managed
Managed cursor.
Definition: mdbx.h++:3984
mdbx::fatal::fatal
fatal(exception &&src) noexcept
Definition: mdbx.h++:447
mdbx::slice::operator[]
MDBX_CXX11_CONSTEXPR byte operator[](size_t n) const noexcept
Returns the nth byte in the referenced data.
Definition: mdbx.h++:4462
mdbx::txn::estimate
ptrdiff_t estimate(map_handle map, pair from, pair to) const
Definition: mdbx.h++:5483
mdbx::allocation_aware_details::move_assign_alloc< T, A, true >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source)
Definition: mdbx.h++:1008
mdbx::to_base64::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the buffer size in bytes needed for Base64 dump of passed slice.
Definition: mdbx.h++:1268
mdbx::to_hex::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1177
mdbx::from_base64::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base64 dump from a passed slice to returned buffer.
Definition: mdbx.h++:1421
mdbx::env::geometry::geometry
MDBX_CXX11_CONSTEXPR geometry() noexcept
Definition: mdbx.h++:2973
mdbx::cursor::renew
void renew(::mdbx::txn &txn)
Renew/bind a cursor with a new transaction and previously used key-value map handle.
Definition: mdbx.h++:5730
mdbx::env::geometry::geometry
MDBX_CXX11_CONSTEXPR geometry(intptr_t size_lower, intptr_t size_now=default_value, intptr_t size_upper=maximal_value, intptr_t growth_step=default_value, intptr_t shrink_threshold=default_value, intptr_t pagesize=default_value) noexcept
Definition: mdbx.h++:2976
mdbx_env_set_userctx
LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx)
Sets application information (a context pointer) associated with the environment.
mdbx::buffer::buffer
buffer(const ::std::basic_string_view< CHAR, T > &view, bool make_reference, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2142
mdbx::env::operate_parameters::reclaiming_from_flags
static env::reclaiming_options reclaiming_from_flags(MDBX_env_flags_t flags) noexcept
Definition: mdbx.h++:4714
mdbx::loop_control
loop_control
Loop control constants for readers enumeration functor and other cases.
Definition: mdbx.h++:2743
mdbx::buffer::silo::bin::make_allocated
MDBX_CXX17_CONSTEXPR byte * make_allocated(allocator_pointer ptr, size_t capacity_bytes) noexcept
Definition: mdbx.h++:1592
mdbx::env::get_HandleSlowReaders
MDBX_hsr_func * get_HandleSlowReaders() const noexcept
Returns the current Handle-Slow-Readers callback used to resolve database full/overflow issue due to ...
Definition: mdbx.h++:4979
mdbx::buffer::slice
MDBX_CXX11_CONSTEXPR const struct slice & slice() const noexcept
Definition: mdbx.h++:2213
mdbx_env_get_flags
LIBMDBX_API int mdbx_env_get_flags(const MDBX_env *env, unsigned *flags)
Get environment flags.
mdbx::cursor::key_exact
@ key_exact
Definition: mdbx.h++:3866
mdbx::env::operator=
env & operator=(env &&other) noexcept
Definition: mdbx.h++:4668
mdbx::key_mode::ordinal
@ ordinal
mdbx_cursor_open
LIBMDBX_API int mdbx_cursor_open(MDBX_txn *txn, MDBX_dbi dbi, MDBX_cursor **cursor)
Create a cursor handle for the specified transaction and DBI handle.
MDBX_DUPFIXED
@ MDBX_DUPFIXED
Definition: mdbx.h:1436
mdbx::slice::empty
MDBX_CXX11_CONSTEXPR bool empty() const noexcept
Checks whether the slice is empty.
Definition: mdbx.h++:4398
mdbx::map_handle::state
::MDBX_dbi_state_t state
Definition: mdbx.h++:2847
mdbx::txn::compare_keys
int compare_keys(map_handle map, const slice &a, const slice &b) const noexcept
Compare two keys according to a particular key-value map (aka sub-database).
Definition: mdbx.h++:5185
mdbx::env::geometry::growth_step
intptr_t growth_step
The growth step in bytes, must be greater than zero to allow the database to grow.
Definition: mdbx.h++:2958
mdbx::env::set_sync_threshold
env & set_sync_threshold(size_t bytes)
Sets threshold to force flush the data buffers to disk, for non-sync durability modes.
Definition: mdbx.h++:4891
mdbx::slice::max_length
@ max_length
Definition: mdbx.h++:569
mdbx_limits_dbsize_max
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_max(intptr_t pagesize)
Returns maximal database size in bytes for given page size, or -1 if pagesize is invalid.
mdbx::env::geometry::shrink_threshold
intptr_t shrink_threshold
The shrink threshold in bytes, must be greater than zero to allow the database to shrink.
Definition: mdbx.h++:2962
mdbx::txn::get
slice get(map_handle map, const slice &key) const
Get value by key from a key-value map (aka sub-database).
Definition: mdbx.h++:5205
mdbx::env::limits::dbsize_max
static size_t dbsize_max(intptr_t pagesize)
Returns the maximal database size in bytes for specified page size.
Definition: mdbx.h++:4735
mdbx::env
Unmanaged database environment.
Definition: mdbx.h++:2885
mdbx::txn::handle_
MDBX_txn * handle_
Definition: mdbx.h++:3525
mdbx::to_hex::to_hex
MDBX_CXX11_CONSTEXPR to_hex(const slice &source, bool uppercase=false, unsigned wrap_width=0) noexcept
Definition: mdbx.h++:1139
mdbx::from_base64::source
const slice source
Definition: mdbx.h++:1401
mdbx::buffer::data
MDBX_CXX11_CONSTEXPR void * data() noexcept
Return a pointer to the beginning of the referenced data.
Definition: mdbx.h++:2067
mdbx::allocation_aware_details::copy_assign_alloc< T, A, false >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:1020
MDBX_env_flags_t
MDBX_env_flags_t
Environment flags.
Definition: mdbx.h:964
mdbx::env::enumerate_readers
int enumerate_readers(VISITOR &visitor)
Enumerate readers.
Definition: mdbx.h++:4942
mdbx::buffer::assign
buffer & assign(struct slice &&src, bool make_reference=false)
Definition: mdbx.h++:2289
mdbx::buffer::swap
MDBX_CXX20_CONSTEXPR void swap(buffer &other) noexcept(swap_alloc::is_nothrow())
Definition: mdbx.h++:2262
mdbx::buffer::silo::bin::address
MDBX_CXX17_CONSTEXPR byte * address() noexcept
Definition: mdbx.h++:1680
mdbx::filehandle
::mdbx_filehandle_t filehandle
Definition: mdbx.h++:321
MDBX_NOTHROW_PURE_FUNCTION
#define MDBX_NOTHROW_PURE_FUNCTION
Definition: mdbx.h:270
mdbx::buffer::allocator_type
typename ::std::allocator_traits< ALLOCATOR >::template rebind_alloc< uint64_t > allocator_type
Definition: mdbx.h++:1452
mdbx::to_base64::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid data and could be encoded or unexpectedly not...
Definition: mdbx.h++:1290
mdbx_canary_put
LIBMDBX_API int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary)
Set integers markers (aka "canary") associated with the environment.
mdbx::value_result::value
slice value
Definition: mdbx.h++:2699
mdbx::txn::clear_map
void clear_map(map_handle map)
Clear key-value map.
Definition: mdbx.h++:5134
mdbx_txn_renew
LIBMDBX_API int mdbx_txn_renew(MDBX_txn *txn)
Renew a read-only transaction.
mdbx::allocation_aware_details::move_assign_alloc< T, A, false >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source) noexcept
Definition: mdbx.h++:995
mdbx::exception::error
const ::mdbx::error error() const noexcept
Definition: mdbx.h++:436
mdbx::cursor::seek
bool seek(const slice &key)
Definition: mdbx.h++:5690
mdbx::cursor::update
void update(const slice &key, const slice &value)
Definition: mdbx.h++:5812
mdbx_cursor_on_last
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_on_last(const MDBX_cursor *cursor)
Determines whether the cursor is pointed to the last key-value pair or not.
MDBX_BAD_TXN
@ MDBX_BAD_TXN
Definition: mdbx.h:1724
mdbx::txn::renew_reading
void renew_reading()
Renew a read-only transaction.
Definition: mdbx.h++:5075
MDBX_NOTFOUND
@ MDBX_NOTFOUND
Definition: mdbx.h:1662
mdbx::env::reader_info::reader_info
MDBX_CXX11_CONSTEXPR reader_info(int slot, mdbx_pid_t pid, mdbx_tid_t thread, uint64_t txnid, uint64_t lag, size_t used, size_t retained) noexcept
Definition: mdbx.h++:4935
MDBX_TXN_TRY
@ MDBX_TXN_TRY
Definition: mdbx.h:1397
mdbx_get_equal_or_great
LIBMDBX_API int mdbx_get_equal_or_great(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data)
Get equal or great item from a database.
MDBX_build_info
libmdbx build information
Definition: mdbx.h:630
mdbx::to_base58::to_base58
MDBX_CXX11_CONSTEXPR to_base58(const slice &source, unsigned wrap_width=0) noexcept
Definition: mdbx.h++:1190
mdbx::env::limits::value_max
static size_t value_max(intptr_t pagesize, MDBX_db_flags_t flags)
Returns the maximal value size in bytes for specified page size and database flags.
Definition: mdbx.h++:4780
mdbx_estimate_distance
LIBMDBX_API int mdbx_estimate_distance(const MDBX_cursor *first, const MDBX_cursor *last, ptrdiff_t *distance_items)
Estimates the distance between cursors as a number of elements.
mdbx::env::reader_info::slot
int slot
The reader lock table slot number.
Definition: mdbx.h++:3358
mdbx::from_base58::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid Base58 dump, and therefore there could be dec...
mdbx::env::start_write
txn_managed start_write(bool dont_wait=false)
Starts write (read-write) transaction.
Definition: mdbx.h++:4999
mdbx::map_handle::info::info
MDBX_CXX11_CONSTEXPR info(map_handle::flags flags, map_handle::state state) noexcept
Definition: mdbx.h++:4645
mdbx::buffer::silo::bin
Definition: mdbx.h++:1519
mdbx::throw_too_small_target_buffer
LIBMDBX_API void throw_too_small_target_buffer()
MDBX_UPSERT
@ MDBX_UPSERT
Definition: mdbx.h:1474
mdbx::from_hex
Hexadecimal decoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1306
mdbx::cursor::key_lowerbound
@ key_lowerbound
Definition: mdbx.h++:3867
mdbx::slice::base58_decode
buffer< ALLOCATOR, CAPACITY_POLICY > base58_decode(bool ignore_spaces=false, const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base58 dump from the slice content to returned buffer.
Definition: mdbx.h++:4609
MDBX_envinfo
Information about the environment.
Definition: mdbx.h:2328
MDBX_debug_flags_t
MDBX_debug_flags_t
Runtime debug flags.
Definition: mdbx.h:857
mdbx_txn_id
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t mdbx_txn_id(const MDBX_txn *txn)
Return the transaction's ID.
mdbx::env::geometry::size_upper
intptr_t size_upper
The upper bound of database size in bytes.
Definition: mdbx.h++:2954
MDBX_MULTIPLE
@ MDBX_MULTIPLE
Definition: mdbx.h:1510
MDBX_stat
Statistics for a database in the environment.
Definition: mdbx.h:2280
mdbx::value_mode::multi_reverse
@ multi_reverse
mdbx::MDBX_DECLARE_EXCEPTION
MDBX_DECLARE_EXCEPTION(bad_map_id)
__ORDER_LITTLE_ENDIAN__
#define __ORDER_LITTLE_ENDIAN__
Definition: mdbx.h++:97
mdbx::buffer::at
MDBX_CXX14_CONSTEXPR byte & at(size_t n)
Accesses the specified byte of data chunk with bounds checking.
Definition: mdbx.h++:2459
mdbx::env::reader_info::thread
mdbx_tid_t thread
The reader thread ID.
Definition: mdbx.h++:3360
mdbx::map_handle
A handle for an individual database (key-value spaces) in the environment.
Definition: mdbx.h++:2838
mdbx_env_set_syncbytes
int mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold)
Sets threshold to force flush the data buffers to disk, even any of MDBX_SAFE_NOSYNC flag in the envi...
Definition: mdbx.h:2506
mdbx::slice::encode_hex
buffer< ALLOCATOR, CAPACITY_POLICY > encode_hex(bool uppercase=false, unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a hexadecimal dump of the slice content.
Definition: mdbx.h++:4580
mdbx::txn::is_readwrite
bool is_readwrite() const
Checks whether the transaction is read-write.
Definition: mdbx.h++:3557
mdbx::operator>=
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool operator>=(const slice &a, const slice &b) noexcept
Definition: mdbx.h++:4550
mdbx::from_hex::source
const slice source
Definition: mdbx.h++:1307
mdbx::from_base64::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the number of bytes needed for conversion Base64 dump from a passed slice to decoded data.
Definition: mdbx.h++:1428
mdbx::slice::set_end
MDBX_CXX14_CONSTEXPR slice & set_end(const void *ptr)
Sets the length by specifying the end of the slice data.
Definition: mdbx.h++:4393
mdbx::pair::key
slice key
Definition: mdbx.h++:2714
mdbx::slice::remove_suffix
void remove_suffix(size_t n) noexcept
Drops the last "n" bytes from this slice.
Definition: mdbx.h++:4431
mdbx::buffer::end
MDBX_CXX11_CONSTEXPR void * end() noexcept
Return a pointer to the end of the referenced data.
Definition: mdbx.h++:2075
mdbx::env::get_filehandle
filehandle get_filehandle() const
Returns the file descriptor for the DXB file of MDBX environment.
Definition: mdbx.h++:4858
mdbx::update
@ update
Update existing, don't insert new.
Definition: mdbx.h++:2874
mdbx::cursor::multi_currentkey_prevvalue
@ multi_currentkey_prevvalue
Definition: mdbx.h++:3857
mdbx::buffer::key_from
static buffer key_from(const char(&text)[SIZE], bool make_reference=true)
Definition: mdbx.h++:2574
LIBMDBX_API
#define LIBMDBX_API
Definition: mdbx.h:592
MDBX_NEXT
@ MDBX_NEXT
Definition: mdbx.h:1572
mdbx::buffer::add_header
buffer & add_header(const void *src, size_t bytes)
Definition: mdbx.h++:2514
mdbx::env::check_readers
unsigned check_readers()
Checks for stale readers in the lock table and return number of cleared slots.
Definition: mdbx.h++:4967
mdbx::buffer::key_from
static buffer key_from(const char *src, bool make_reference=false)
Definition: mdbx.h++:2587
mdbx::buffer::operator[]
MDBX_CXX11_CONSTEXPR byte & operator[](size_t n) noexcept
Accesses the specified byte of data chunk.
Definition: mdbx.h++:2448
mdbx::cursor::insert
void insert(const slice &key, slice value)
Definition: mdbx.h++:5756
mdbx::default_capacity_policy::advise
static MDBX_CXX11_CONSTEXPR size_t advise(const size_t current, const size_t wanna)
Definition: mdbx.h++:1113
mdbx::env::set_geometry
env & set_geometry(const geometry &size)
Set all size-related parameters of environment.
Definition: mdbx.h++:4910
mdbx::buffer::ends_with
MDBX_NOTHROW_PURE_FUNCTION bool ends_with(const struct slice &suffix) const noexcept
Checks if the data ends with the given suffix.
Definition: mdbx.h++:2410
mdbx::allocation_aware_details::swap_alloc< T, A, true >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:1072
mdbx::slice::clear
MDBX_CXX14_CONSTEXPR void clear() noexcept
Makes the slice empty and referencing to nothing.
Definition: mdbx.h++:4414
mdbx::buffer::buffer
buffer(size_t head_room, size_t tail_room, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2181
MDBX_ENV_ENSURE_UNUSED
@ MDBX_ENV_ENSURE_UNUSED
Make sure that the environment is not being used by other processes, or return an error otherwise.
Definition: mdbx.h:2187
MDBX_SUCCESS
@ MDBX_SUCCESS
Definition: mdbx.h:1647
MDBX_hsr_func
int() MDBX_hsr_func(const MDBX_env *env, const MDBX_txn *txn, mdbx_pid_t pid, mdbx_tid_t tid, uint64_t laggard, unsigned gap, size_t space, int retry) MDBX_CXX17_NOEXCEPT
A Handle-Slow-Readers callback function to resolve database full/overflow issue due to a reader(s) wh...
Definition: mdbx.h:4985
mdbx::env::operate_parameters::durability_from_flags
static env::durability durability_from_flags(MDBX_env_flags_t) noexcept
mdbx::slice::byte_ptr
const MDBX_CXX11_CONSTEXPR byte * byte_ptr() const noexcept
Returns casted to pointer to byte an address of data.
Definition: mdbx.h++:4340
mdbx_env_get_maxvalsize_ex
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxvalsize_ex(const MDBX_env *env, MDBX_db_flags_t flags)
Returns the maximum size of data we can put.
mdbx::buffer::silo::bin::make_inplace
MDBX_CXX17_CONSTEXPR byte * make_inplace() noexcept
Definition: mdbx.h++:1575
mdbx_dbi_flags_ex
LIBMDBX_API int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags, unsigned *state)
Retrieve the DB flags and status for a database handle.
mdbx::cursor::to_previous
move_result to_previous(bool throw_notfound=true)
Definition: mdbx.h++:5618
mdbx::map_handle::map_handle
MDBX_CXX11_CONSTEXPR map_handle() noexcept
Definition: mdbx.h++:2840
mdbx::byte
char8_t byte
Definition: mdbx.h++:261
MDBX_LIKELY
#define MDBX_LIKELY(cond)
Definition: mdbx.h++:157
mdbx_dbi_stat
LIBMDBX_API int mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat, size_t bytes)
Retrieve statistics for a database.
mdbx::buffer::assign
buffer & assign(const char *c_str, bool make_reference=false)
Definition: mdbx.h++:2315
mdbx::env::limits::pagesize_max
static size_t pagesize_max() noexcept
Returns the maximal database page size in bytes.
Definition: mdbx.h++:4726
mdbx::allocation_aware_details::move_assign_alloc< T, A, false >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:988
mdbx::from_base58::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the number of bytes needed for conversion Base58 dump from a passed slice to decoded data.
Definition: mdbx.h++:1379
mdbx::buffer::operator=
buffer & operator=(const ::std::basic_string_view< CHAR, T > &view) noexcept
Definition: mdbx.h++:2348
mdbx::cursor::handle_
MDBX_cursor * handle_
Definition: mdbx.h++:3831
mdbx_estimate_move
LIBMDBX_API int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key, MDBX_val *data, MDBX_cursor_op move_op, ptrdiff_t *distance_items)
Estimates the move distance.
mdbx::to_base58::output
::std::ostream & output(::std::ostream &out) const
Output Base58 dump of passed slice to the std::ostream.
mdbx::env::reclaiming_options::reclaiming_options
MDBX_CXX11_CONSTEXPR reclaiming_options() noexcept
Definition: mdbx.h++:3008
mdbx::buffer::key_from
static buffer key_from(const float *ieee754_32bit)
Definition: mdbx.h++:2625
mdbx_key_from_int32
MDBX_NOTHROW_CONST_FUNCTION uint32_t mdbx_key_from_int32(const int32_t i32)
Definition: mdbx.h:3785
mdbx::from_hex::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid hexadecimal dump, and therefore there could b...
mdbx::buffer::silo::bin::lastbyte
constexpr byte lastbyte() const noexcept
Definition: mdbx.h++:1562
mdbx::exception_thunk::is_clean
bool is_clean() const noexcept
Definition: mdbx.h++:4130
mdbx::txn::size_current
size_t size_current() const
Returns current write transaction size (i.e.summary volume of dirty pages) in bytes.
Definition: mdbx.h++:3569
mdbx::env::max_readers
unsigned max_readers() const
Returns the maximum number of threads/reader slots for the environment.
Definition: mdbx.h++:4870
mdbx_cursor_dbi
LIBMDBX_API MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *cursor)
Return the cursor's database handle.
bool
#define bool
Definition: mdbx.h:379
mdbx_key_from_ptrfloat
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint32_t mdbx_key_from_ptrfloat(const float *const ieee754_32bit)
mdbx::value_mode::multi_reverse_samelength
@ multi_reverse_samelength
mdbx::buffer::silo::bin::bin
MDBX_CXX20_CONSTEXPR bin(allocator_pointer ptr, size_t capacity_bytes) noexcept
Definition: mdbx.h++:1616
mdbx_get_ex
LIBMDBX_API int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, size_t *values_count)
Get items from a database and optionally number of data items for a given key.
MDBX_CXX14_CONSTEXPR
#define MDBX_CXX14_CONSTEXPR
Definition: mdbx.h:433
mdbx::cursor::get_current
@ get_current
Definition: mdbx.h++:3853
mdbx::cursor::multi_currentkey_nextvalue
@ multi_currentkey_nextvalue
Definition: mdbx.h++:3858
mdbx::buffer::operator=
buffer & operator=(buffer &&src) noexcept(move_assign_alloc::is_nothrow())
Definition: mdbx.h++:2337
mdbx::key_mode::usual
@ usual
MDBX_cursor_op
MDBX_cursor_op
Cursor operations.
Definition: mdbx.h:1543
mdbx::MutableByteProducer
concept MutableByteProducer
Definition: mdbx.h++:513
mdbx_cursor_eof
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_eof(const MDBX_cursor *cursor)
Determines whether the cursor is pointed to a key-value pair or not, i.e. was not positioned or point...
mdbx::cursor::move_result::move_result
move_result(const cursor &cursor, bool throw_notfound)
Definition: mdbx.h++:5551
mdbx::txn::update
void update(map_handle map, const slice &key, const slice &value)
Definition: mdbx.h++:5341
mdbx::env::prepare_read
txn_managed prepare_read() const
Creates but not start read transaction.
Definition: mdbx.h++:4991
mdbx::env::operate_parameters::options_from_flags
static env::operate_options options_from_flags(MDBX_env_flags_t flags) noexcept
Definition: mdbx.h++:4720
mdbx::ImmutableByteProducer
concept ImmutableByteProducer
Definition: mdbx.h++:520
mdbx::env::operate_options
Operate options.
Definition: mdbx.h++:3017
MDBX_LAST
@ MDBX_LAST
Definition: mdbx.h:1566
mdbx::buffer::operator=
buffer & operator=(const buffer &src)
Definition: mdbx.h++:2335
mdbx::error::throw_on_nullptr
static void throw_on_nullptr(const void *ptr, MDBX_error_t error_code)
Definition: mdbx.h++:4220
mdbx::cursor::upsert_reserve
slice upsert_reserve(const slice &key, size_t value_length)
Definition: mdbx.h++:5805
mdbx::buffer::key_from
static buffer key_from(const ::std::basic_string_view< CHAR, T > &src, bool make_reference=false)
Definition: mdbx.h++:2581
mdbx::cursor::to_current_last_multi
move_result to_current_last_multi(bool throw_notfound=true)
Definition: mdbx.h++:5642
mdbx::txn::put
MDBX_error_t put(map_handle map, const slice &key, slice *value, MDBX_put_flags_t flags) noexcept
Definition: mdbx.h++:5272
mdbx::buffer::silo::bin::address
constexpr const byte * address() const noexcept
Definition: mdbx.h++:1675
mdbx::cursor::try_insert
value_result try_insert(const slice &key, slice value)
Definition: mdbx.h++:5762
MDBX_CXX20_CONCEPT
#define MDBX_CXX20_CONCEPT(CONCEPT, NAME)
Definition: mdbx.h++:212
mdbx::buffer::append_producer
buffer & append_producer(PRODUCER &producer)
Definition: mdbx.h++:2528
mdbx::fatal
Fatal exception that lead termination anyway in dangerous unrecoverable cases.
Definition: mdbx.h++:441
mdbx::buffer::is_reference
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool is_reference() const noexcept
Checks whether the buffer just refers to data located outside the buffer, rather than stores it.
Definition: mdbx.h++:1979
mdbx::cursor
Unmanaged cursor.
Definition: mdbx.h++:3829
mdbx::txn::replace_reserve
buffer< ALLOCATOR, CAPACITY_POLICY > replace_reserve(map_handle map, const slice &key, slice &new_value, const typename buffer< ALLOCATOR, CAPACITY_POLICY >::allocator_type &allocator=buffer< ALLOCATOR, CAPACITY_POLICY >::allocator_type())
Definition: mdbx.h++:5441
mdbx::buffer::reservation_policy
CAPACITY_POLICY reservation_policy
Definition: mdbx.h++:1457
mdbx::txn::put_multiple
size_t put_multiple(map_handle map, const slice &key, const size_t value_length, const void *values_array, size_t values_count, put_mode mode, bool allow_partial=false)
Definition: mdbx.h++:5461
mdbx::buffer::append_base58
buffer & append_base58(const struct slice &data, unsigned wrap_width=0)
Definition: mdbx.h++:2548
mdbx_txn_env
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_env * mdbx_txn_env(const MDBX_txn *txn)
Returns the transaction's MDBX_env.
mdbx::txn::erase
bool erase(map_handle map, const slice &key)
Removes all values for given key.
Definition: mdbx.h++:5383
mdbx::from_base58::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base58 dump from a passed slice to returned string.
Definition: mdbx.h++:1363
mdbx::env::env
MDBX_CXX11_CONSTEXPR env() noexcept=default
mdbx::buffer::key_from
static buffer key_from(const int32_t signed_int32)
Definition: mdbx.h++:2633
mdbx_env_get_userctx
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API void * mdbx_env_get_userctx(const MDBX_env *env)
Returns an application information (a context pointer) associated with the environment.
mdbx::buffer::append_base64
buffer & append_base64(const struct slice &data, unsigned wrap_width=0)
Definition: mdbx.h++:2552
mdbx::slice::safe_tail
MDBX_CXX14_CONSTEXPR slice safe_tail(size_t n) const
Returns the last "n" bytes of the slice.
Definition: mdbx.h++:4494
MDBX_env
struct MDBX_env MDBX_env
Opaque structure for a database environment.
Definition: mdbx.h:692
mdbx::buffer
The chunk of data stored inside the buffer or located outside it.
Definition: mdbx.h++:302
mdbx::cursor::move
bool move(move_operation operation, MDBX_val *key, MDBX_val *value, bool throw_notfound) const
Definition: mdbx.h++:5579
mdbx::env::key_max
size_t key_max(key_mode mode) const
Returns the maximal key size in bytes for specified keys mode.
Definition: mdbx.h++:3157
mdbx::env::operate_parameters::operate_parameters
MDBX_CXX11_CONSTEXPR operate_parameters(const unsigned max_maps, const unsigned max_readers=0, const env::mode mode=env::mode::write_mapped_io, env::durability durability=env::durability::robust_synchronous, const env::reclaiming_options &reclaiming=env::reclaiming_options(), const env::operate_options &options=env::operate_options()) noexcept
Definition: mdbx.h++:3050
mdbx::env::reclaiming_options
Garbage reclaiming options.
Definition: mdbx.h++:3003
mdbx::cursor::try_update_reserve
value_result try_update_reserve(const slice &key, size_t value_length)
Definition: mdbx.h++:5837
mdbx::slice::remove_prefix
void remove_prefix(size_t n) noexcept
Drops the first "n" bytes from this slice.
Definition: mdbx.h++:4419
MDBX_MAXDATASIZE
@ MDBX_MAXDATASIZE
Definition: mdbx.h:768
mdbx_tid_t
pthread_t mdbx_tid_t
Definition: mdbx.h:198
mdbx::buffer::buffer
buffer(buffer &&src) noexcept(move_assign_alloc::is_nothrow())
Definition: mdbx.h++:2210
mdbx_env_get_maxkeysize_ex
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags)
Returns the maximum size of keys can put.
mdbx::txn::get_handle_info
map_handle::info get_handle_info(map_handle map) const
Returns information about key-value map (aka sub-database) handle.
Definition: mdbx.h++:5154
mdbx::to_base58::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a Base58 dump of a passed slice.
Definition: mdbx.h++:1198
mdbx::make_string
string< ALLOCATOR > make_string(PRODUCER &producer, const ALLOCATOR &allocator=ALLOCATOR())
Definition: mdbx.h++:2669
mdbx::error::boolean_or_throw
static bool boolean_or_throw(int error_code)
Definition: mdbx.h++:4235
mdbx::env::set_context
env & set_context(void *)
Sets the application context associated with the environment.
Definition: mdbx.h++:4886
mdbx::map_handle::map_handle
MDBX_CXX11_CONSTEXPR map_handle(MDBX_dbi dbi) noexcept
Definition: mdbx.h++:2841
mdbx::buffer::key_from
static buffer key_from(const silo &&src) noexcept
Definition: mdbx.h++:2597
mdbx::string
::std::basic_string< char, ::std::char_traits< char >, ALLOCATOR > string
Default singe-byte string.
Definition: mdbx.h++:319
mdbx::env::geometry::make_fixed
geometry & make_fixed(intptr_t size) noexcept
Definition: mdbx.h++:4700
mdbx::txn::try_update_reserve
value_result try_update_reserve(map_handle map, const slice &key, size_t value_length)
Definition: mdbx.h++:5368
mdbx::throw_allocators_mismatch
LIBMDBX_API void throw_allocators_mismatch()
MDBX_ENV_WAIT_FOR_UNUSED
@ MDBX_ENV_WAIT_FOR_UNUSED
Wait until other processes closes the environment before deletion.
Definition: mdbx.h:2190
mdbx::put_mode
put_mode
Key-value pairs put mode.
Definition: mdbx.h++:2871
MDBX_ENOMEM
@ MDBX_ENOMEM
Definition: mdbx.h:1796
mdbx::to_hex::output
::std::ostream & output(::std::ostream &out) const
Output hexadecimal dump of passed slice to the std::ostream.
mdbx::txn::get_map_stat
map_stat get_map_stat(map_handle map) const
Returns statistics for a sub-database.
Definition: mdbx.h++:5142
mdbx::to_base58::source
const slice source
Definition: mdbx.h++:1187
mdbx::cursor_managed::~cursor_managed
~cursor_managed() noexcept
Definition: mdbx.h++:4014
mdbx::txn::env
inline ::mdbx::env env() const noexcept
Returns the transaction's environment.
Definition: mdbx.h++:5057
MDBX_preserve_func
int(* MDBX_preserve_func)(void *context, MDBX_val *target, const void *src, size_t bytes)
Definition: mdbx.h:4149
mdbx::buffer::buffer
buffer(const char *c_str, bool make_reference, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2135
MDBX_DB_DEFAULTS
@ MDBX_DB_DEFAULTS
Definition: mdbx.h:1419
mdbx_cursor_close
LIBMDBX_API void mdbx_cursor_close(MDBX_cursor *cursor)
Close a cursor handle.
mdbx_cursor_on_first
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cursor_on_first(const MDBX_cursor *cursor)
Determines whether the cursor is pointed to the first key-value pair or not.
mdbx::slice::starts_with
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool starts_with(const slice &prefix) const noexcept
Checks if the data starts with the given prefix.
Definition: mdbx.h++:4443
mdbx::pair_result
Combines pair of slices for key and value with boolean flag to represent result of certain operations...
Definition: mdbx.h++:2727
mdbx::buffer::buffer
buffer(const buffer &src, bool make_reference, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2122
mdbx_key_from_int64
MDBX_NOTHROW_CONST_FUNCTION uint64_t mdbx_key_from_int64(const int64_t i64)
Definition: mdbx.h:3781
mdbx::slice::as_base58_string
string< ALLOCATOR > as_base58_string(unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a Base58 dump of the slice content.
Definition: mdbx.h++:4568
mdbx::polymorphic_allocator
::std::pmr::string::allocator_type polymorphic_allocator
Default polymorphic allocator for modern code.
Definition: mdbx.h++:314
mdbx::value_mode::multi_ordinal
@ multi_ordinal
mdbx::buffer::key_from
static buffer key_from(const int64_t signed_int64)
Definition: mdbx.h++:2613
mdbx::buffer::append
buffer & append(const void *src, size_t bytes)
Definition: mdbx.h++:2502
MDBX_PREV_NODUP
@ MDBX_PREV_NODUP
Definition: mdbx.h:1592
mdbx::env::operate_parameters::options
env::operate_options options
Definition: mdbx.h++:3046
mdbx::txn::compare_values
int compare_values(map_handle map, const slice &a, const slice &b) const noexcept
Compare two values according to a particular key-value map (aka sub-database).
Definition: mdbx.h++:5190
mdbx::map_handle::flags
::MDBX_db_flags_t flags
Definition: mdbx.h++:2846
mdbx::pair::value
slice value
Definition: mdbx.h++:2714
MDBX_CXX17_FALLTHROUGH
#define MDBX_CXX17_FALLTHROUGH
Definition: mdbx.h++:183
mdbx::map_handle::info::key_mode
MDBX_CXX11_CONSTEXPR ::mdbx::key_mode key_mode() const noexcept
Definition: mdbx.h++:4652
mdbx::buffer::end_char_ptr
const MDBX_CXX11_CONSTEXPR char * end_char_ptr() const noexcept
Returns casted to const pointer to char an end of data.
Definition: mdbx.h++:2036
mdbx::pair_result::pair_result
pair_result(const slice &key, const slice &value, bool done) noexcept
Definition: mdbx.h++:2729
mdbx::slice::invalid
static MDBX_CXX14_CONSTEXPR slice invalid() noexcept
Build an invalid slice which non-zero length and refers to null address.
Definition: mdbx.h++:960
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const buffer &src, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2154
mdbx_drop
LIBMDBX_API int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del)
Empty or delete and close a database.
mdbx
Definition: mdbx.h++:251
MDBX_MAX_PAGESIZE
@ MDBX_MAX_PAGESIZE
Definition: mdbx.h:774
mdbx_del
LIBMDBX_API int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, const MDBX_val *data)
Delete items from a database.
mdbx::value_result::done
bool done
Definition: mdbx.h++:2700
mdbx::env::operate_parameters
Operate parameters.
Definition: mdbx.h++:3036
mdbx::to_base64::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a Base64 dump of a passed slice.
Definition: mdbx.h++:1253
mdbx::from_base58::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base58 dump from a passed slice to returned buffer.
Definition: mdbx.h++:1372
mdbx::txn::get_equal_or_great
pair_result get_equal_or_great(map_handle map, const slice &key) const
Get value for equal or great key from a database.
Definition: mdbx.h++:5246
mdbx::txn
Unmanaged database transaction.
Definition: mdbx.h++:3522
mdbx::cursor::estimate
ptrdiff_t estimate(move_operation operation, MDBX_val *key, MDBX_val *value) const
Definition: mdbx.h++:5595
mdbx::env::readonly
@ readonly
Definition: mdbx.h++:2989
mdbx::cursor::insert_reserve
slice insert_reserve(const slice &key, size_t value_length)
Definition: mdbx.h++:5776
mdbx::txn::put_canary
txn & put_canary(const canary &)
Set integers markers (aka "canary") associated with the environment.
Definition: mdbx.h++:5161
mdbx::buffer::assign
buffer & assign(const void *begin, const void *end, bool make_reference=false)
Definition: mdbx.h++:2301
mdbx::buffer::append_decoded_base64
buffer & append_decoded_base64(const struct slice &data, bool ignore_spaces=false)
Definition: mdbx.h++:2566
mdbx::to_base64::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a Base64 dump of a passed slice.
Definition: mdbx.h++:1262
mdbx::buffer::hash_value
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t hash_value() const noexcept
Returns the hash value of the data.
Definition: mdbx.h++:2385
mdbx::buffer::buffer
buffer(const struct slice &src, bool make_reference, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2115
mdbx::value_mode
value_mode
Kind of the values and sorted multi-values with corresponding comparison.
Definition: mdbx.h++:2764
mdbx::buffer::silo::bin::allocated
Definition: mdbx.h++:1520
mdbx::buffer::safe_remove_prefix
void safe_remove_prefix(size_t n)
Drops the first "n" bytes from the data chunk.
Definition: mdbx.h++:2433
mdbx::env::value_max
size_t value_max(value_mode mode) const
Returns the maximal value size in bytes for specified values mode.
Definition: mdbx.h++:3163
mdbx::buffer::shrink_to_fit
void shrink_to_fit()
Reduces memory usage by freeing unused storage space.
Definition: mdbx.h++:2421
mdbx::txn::operator=
txn & operator=(txn &&other) noexcept
Definition: mdbx.h++:5013
mdbx::cursor::cursor
MDBX_CXX11_CONSTEXPR cursor() noexcept=default
mdbx::error::is_result_true
MDBX_CXX11_CONSTEXPR bool is_result_true() const noexcept
Definition: mdbx.h++:4164
mdbx_txn_break
LIBMDBX_API int mdbx_txn_break(MDBX_txn *txn)
Marks transaction as broken.
mdbx::exception
Base class for all libmdbx's exceptions that are corresponds to libmdbx errors.
Definition: mdbx.h++:425
mdbx::operator>
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool operator>(const slice &a, const slice &b) noexcept
Definition: mdbx.h++:4540
mdbx::slice::wrap
static MDBX_CXX14_CONSTEXPR slice wrap(const char(&text)[SIZE])
Definition: mdbx.h++:615
MDBX_LAST_ADDED_ERRCODE
@ MDBX_LAST_ADDED_ERRCODE
Definition: mdbx.h:1774
mdbx::to_base58::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1232
mdbx::buffer::is_freestanding
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool is_freestanding() const noexcept
Checks whether data chunk stored inside the buffer, otherwise buffer just refers to data located outs...
Definition: mdbx.h++:1971
false
#define false
Definition: mdbx.h:385
mdbx::buffer::string_view
::std::basic_string_view< CHAR, T > string_view() const noexcept
Return a string_view that references the data of this buffer.
Definition: mdbx.h++:2354
mdbx_key_from_jsonInteger
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer)
mdbx::buffer::silo::bin::capacity
constexpr size_t capacity() const noexcept
Definition: mdbx.h++:1684
mdbx::txn::estimate_to_last
ptrdiff_t estimate_to_last(map_handle map, slice from) const
Definition: mdbx.h++:5504
mdbx::env::geometry::size
Tagged type for output to std::ostream.
Definition: mdbx.h++:2930
mdbx::buffer::assign
buffer & assign(const void *ptr, size_t bytes, bool make_reference=false)
Definition: mdbx.h++:2276
mdbx::error::code
MDBX_CXX11_CONSTEXPR MDBX_error_t code() const noexcept
Returns error code.
Definition: mdbx.h++:4176
mdbx::env::remove_mode
remove_mode
Deletion modes for remove().
Definition: mdbx.h++:3189
mdbx::txn::~txn
~txn() noexcept
Definition: mdbx.h++:5023
MDBX_SET_RANGE
@ MDBX_SET_RANGE
Definition: mdbx.h:1601
mdbx::cursor::to_current_first_multi
move_result to_current_first_multi(bool throw_notfound=true)
Definition: mdbx.h++:5626
mdbx::estimate
ptrdiff_t estimate(const cursor &from, const cursor &to)
Definition: mdbx.h++:5603
mdbx::txn::replace
void replace(map_handle map, const slice &key, slice old_value, const slice &new_value)
Replaces the particular multi-value of the key with a new value.
Definition: mdbx.h++:5407
MDBX_REVERSEKEY
@ MDBX_REVERSEKEY
Definition: mdbx.h:1422
mdbx::env::lazy_weak_tail
@ lazy_weak_tail
Definition: mdbx.h++:2998
mdbx::slice::assign
slice & assign(const ::std::basic_string< CHAR, T, ALLOCATOR > &str)
Definition: mdbx.h++:634
mdbx::txn::try_insert_reserve
value_result try_insert_reserve(map_handle map, const slice &key, size_t value_length)
Definition: mdbx.h++:5312
MDBX_GET_CURRENT
@ MDBX_GET_CURRENT
Definition: mdbx.h:1558
mdbx::cursor::to_current_prev_multi
move_result to_current_prev_multi(bool throw_notfound=true)
Definition: mdbx.h++:5630
mdbx::txn::txn
MDBX_CXX11_CONSTEXPR txn() noexcept=default
mdbx::slice::safe_remove_suffix
void safe_remove_suffix(size_t n)
Drops the last "n" bytes from this slice.
Definition: mdbx.h++:4436
mdbx::fatal::fatal
fatal(fatal &&src) noexcept
Definition: mdbx.h++:449
mdbx::cursor::previous
@ previous
Definition: mdbx.h++:3852
MDBX_dbi
uint32_t MDBX_dbi
A handle for an individual database (key-value spaces) in the environment.
Definition: mdbx.h:715
std::hash<::mdbx::slice >::operator()
MDBX_CXX14_CONSTEXPR size_t operator()(::mdbx::slice const &slice) const noexcept
Definition: mdbx.h++:5967
mdbx::from_base64
Base64 decoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1400
mdbx::error::is_result_false
MDBX_CXX11_CONSTEXPR bool is_result_false() const noexcept
Definition: mdbx.h++:4168
mdbx::slice::operator=
slice & operator=(const ::std::basic_string_view< CHAR, T > &view)
Definition: mdbx.h++:659
mdbx::continue_loop
@ continue_loop
Definition: mdbx.h++:2743
mdbx::buffer::assign
buffer & assign(const buffer &src, bool make_reference=false)
Definition: mdbx.h++:2272
mdbx::env::handle_
MDBX_env * handle_
Definition: mdbx.h++:2889
MDBX_CXX17_CONSTEXPR
#define MDBX_CXX17_CONSTEXPR
Definition: mdbx.h++:130
mdbx::buffer::length
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t length() const noexcept
Returns the number of bytes.
Definition: mdbx.h++:2082
mdbx::env::operate_options::operate_options
MDBX_CXX11_CONSTEXPR operate_options() noexcept
Definition: mdbx.h++:3027
mdbx::env::limits::key_min
static size_t key_min(MDBX_db_flags_t flags) noexcept
Returns the minimal key size in bytes for specified database flags.
Definition: mdbx.h++:4742
mdbx::buffer::remove_suffix
void remove_suffix(size_t n) noexcept
Drops the last "n" bytes from the data chunk.
Definition: mdbx.h++:2429
mdbx::to_hex::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the buffer size in bytes needed for hexadecimal dump of a passed slice.
Definition: mdbx.h++:1161
mdbx::operator<<
inline ::std::ostream & operator<<(::std::ostream &out, const to_hex &wrapper)
Definition: mdbx.h++:1293
mdbx::fatal::fatal
fatal(const exception &src) noexcept
Definition: mdbx.h++:446
MDBX_error_t
MDBX_error_t
Errors and return codes.
Definition: mdbx.h:1645
MDBX_APPENDDUP
@ MDBX_APPENDDUP
Definition: mdbx.h:1506
mdbx::cursor::put
MDBX_error_t put(const slice &key, slice *value, MDBX_put_flags_t flags) noexcept
Definition: mdbx.h++:5751
mdbx::slice::tail
MDBX_CXX14_CONSTEXPR slice tail(size_t n) const noexcept
Returns the last "n" bytes of the slice.
Definition: mdbx.h++:4478
mdbx_limits_keysize_max
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags)
Returns maximal key size in bytes for given page size and database flags, or -1 if pagesize is invali...
mdbx::slice::at
MDBX_CXX11_CONSTEXPR byte at(size_t n) const
Returns the nth byte in the referenced data with bounds checking.
Definition: mdbx.h++:4467
mdbx::env::geometry::pagesize
intptr_t pagesize
The database page size for new database creation or default_value otherwise.
Definition: mdbx.h++:2968
mdbx::allocation_aware_details::move_assign_alloc< T, A, true >::is_moveable
static constexpr bool is_moveable(T *, T &) noexcept
Definition: mdbx.h++:1007
mdbx::buffer::assign_reference
buffer & assign_reference(const void *ptr, size_t bytes)
Definition: mdbx.h++:2248
mdbx_reader_list
LIBMDBX_API int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func, void *ctx)
Enumerate the entries in the reader lock table.
mdbx::buffer::reserve_headroom
void reserve_headroom(size_t wanna_headroom)
Reserves space before the payload.
Definition: mdbx.h++:2243
mdbx::env::write_file_io
@ write_file_io
Definition: mdbx.h++:2990
mdbx::allocation_aware_details::swap_alloc< T, A, false >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source) noexcept(is_nothrow())
Definition: mdbx.h++:1058
mdbx::env::robust_synchronous
@ robust_synchronous
Definition: mdbx.h++:2996
mdbx::map_handle::info::value_mode
MDBX_CXX11_CONSTEXPR ::mdbx::value_mode value_mode() const noexcept
Definition: mdbx.h++:4659
mdbx::txn::append
void append(map_handle map, const slice &key, const slice &value, bool multivalue_order_preserved=true)
Adding a key-value pair, provided that ascending order of the keys and (optionally) values are preser...
Definition: mdbx.h++:5453
mdbx::cursor::erase
bool erase(bool whole_multivalue=false)
Removes single key-value pair or all multi-values at the current cursor position.
Definition: mdbx.h++:5852
mdbx::buffer::operator[]
MDBX_CXX11_CONSTEXPR byte operator[](size_t n) const noexcept
Accesses the specified byte of data chunk.
Definition: mdbx.h++:2441
mdbx::buffer::as_string
MDBX_CXX20_CONSTEXPR ::std::basic_string< CHAR, T, A > as_string(const A &allocator=A()) const
Definition: mdbx.h++:2392
mdbx_env_set_flags
LIBMDBX_API int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags, bool onoff)
Set environment flags.
mdbx::slice::as_base64_string
string< ALLOCATOR > as_base64_string(unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a Base58 dump of the slice content.
Definition: mdbx.h++:4574
MDBX_db_flags_t
MDBX_db_flags_t
Database flags.
Definition: mdbx.h:1417
mdbx::slice::head
MDBX_CXX14_CONSTEXPR slice head(size_t n) const noexcept
Returns the first "n" bytes of the slice.
Definition: mdbx.h++:4473
mdbx_cursor_count
LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *pcount)
Return count of duplicates for current key.
mdbx::txn::try_update
bool try_update(map_handle map, const slice &key, const slice &value)
Definition: mdbx.h++:5346
MDBX_STD_FILESYSTEM_PATH
#define MDBX_STD_FILESYSTEM_PATH
Definition: mdbx.h++:329
__ORDER_BIG_ENDIAN__
#define __ORDER_BIG_ENDIAN__
Definition: mdbx.h++:98
mdbx::slice::end
const MDBX_CXX11_CONSTEXPR void * end() const noexcept
Return a pointer to the ending of the referenced data.
Definition: mdbx.h++:4376
mdbx_default_pagesize
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API size_t mdbx_default_pagesize(void)
Returns the default size of database page for the current system.
mdbx::env::value_min
size_t value_min(value_mode mode) const noexcept
Returns the minimal value size in bytes for specified values mode.
Definition: mdbx.h++:3159
mdbx_env_get_maxdbs
int mdbx_env_get_maxdbs(const MDBX_env *env, MDBX_dbi *dbs)
Get the maximum number of named databases for the environment.
Definition: mdbx.h:3060
mdbx::buffer::silo::bin::bin
MDBX_CXX20_CONSTEXPR bin(size_t capacity_bytes=0) noexcept
Definition: mdbx.h++:1611
mdbx::buffer::at
MDBX_CXX14_CONSTEXPR byte at(size_t n) const
Accesses the specified byte of data chunk with bounds checking.
Definition: mdbx.h++:2455
mdbx_replace_ex
LIBMDBX_API int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *new_data, MDBX_val *old_data, MDBX_put_flags_t flags, MDBX_preserve_func preserver, void *preserver_context)
MDBX_txn_flags_t
MDBX_txn_flags_t
Definition: mdbx.h:1371
MDBX_FIRST_LMDB_ERRCODE
@ MDBX_FIRST_LMDB_ERRCODE
Definition: mdbx.h:1659
mdbx::txn::update_reserve
slice update_reserve(map_handle map, const slice &key, size_t value_length)
Definition: mdbx.h++:5360
mdbx::env::get_flags
MDBX_env_flags_t get_flags() const
Returns environment flags.
Definition: mdbx.h++:4864
mdbx_dcmp
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b)
Compare two data items according to a particular database.
MDBX_txn_info
Information about the transaction.
Definition: mdbx.h:3295
mdbx::cursor::on_last
bool on_last() const
Definition: mdbx.h++:5713
mdbx::txn::get_tree_deepmask
uint32_t get_tree_deepmask(map_handle map) const
Returns depth (bitmask) information of nested dupsort (multi-value) B+trees for given database.
Definition: mdbx.h++:5148
mdbx::buffer::end_char_ptr
MDBX_CXX11_CONSTEXPR char * end_char_ptr() noexcept
Returns casted to pointer to char an end of data.
Definition: mdbx.h++:2051
mdbx::key_mode
key_mode
Kinds of the keys and corresponding modes of comparing it.
Definition: mdbx.h++:2746
mdbx::cursor::first
@ first
Definition: mdbx.h++:3849
mdbx_reader_check
LIBMDBX_API int mdbx_reader_check(MDBX_env *env, int *dead)
Check for stale entries in the reader lock table.
mdbx::exception_thunk
Transfers C++ exceptions thru C callbacks.
Definition: mdbx.h++:348
mdbx::buffer::buffer
buffer(const void *ptr, size_t bytes, bool make_reference, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2126
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const ::std::basic_string< CHAR, T, A > &str, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2164
mdbx::buffer::append_producer
buffer & append_producer(const PRODUCER &producer)
Definition: mdbx.h++:2536
mdbx::env::reader_info::transaction_id
uint64_t transaction_id
Definition: mdbx.h++:3361
mdbx::env::close_map
void close_map(const map_handle &)
Close a key-value map (aka sub-database) handle. Normally unnecessary.
Definition: mdbx.h++:4930
std::to_string
string to_string(const ::mdbx::slice &value)
Definition: mdbx.h++:5881
mdbx::exception_thunk::capture
void capture() noexcept
Definition: mdbx.h++:4132
mdbx::buffer::append_decoded_base58
buffer & append_decoded_base58(const struct slice &data, bool ignore_spaces=false)
Definition: mdbx.h++:2561
mdbx_env_get_maxreaders
int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers)
Get the maximum number of threads/reader slots for the environment.
Definition: mdbx.h:3015
MDBX_CONSTEXPR_ASSERT
#define MDBX_CONSTEXPR_ASSERT(expr)
Definition: mdbx.h++:149
mdbx::buffer::silo::bin::advise_capacity
static MDBX_CXX20_CONSTEXPR size_t advise_capacity(const size_t current, const size_t wanna)
Definition: mdbx.h++:1664
mdbx::buffer::silo::bin::bin
MDBX_CXX20_CONSTEXPR bin(bin &&ditto) noexcept
Definition: mdbx.h++:1626
mdbx_key_from_double
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t mdbx_key_from_double(const double ieee754_64bit)
mdbx::buffer::wrap
static buffer wrap(const POD &pod, bool make_reference=false, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2222
mdbx::slice::char_ptr
const MDBX_CXX11_CONSTEXPR char * char_ptr() const noexcept
Returns casted to pointer to char an address of data.
Definition: mdbx.h++:4356
mdbx::cursor::eof
bool eof() const
Definition: mdbx.h++:5705
mdbx::buffer::assign_freestanding
buffer & assign_freestanding(const void *ptr, size_t bytes)
Definition: mdbx.h++:2254
mdbx::slice::ends_with
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool ends_with(const slice &suffix) const noexcept
Checks if the data ends with the given suffix.
Definition: mdbx.h++:4448
mdbx::buffer::key_from
static buffer key_from(const ::std::basic_string< CHAR, T, A > &src, bool make_reference=false)
Definition: mdbx.h++:2592
mdbx::slice::size
MDBX_CXX11_CONSTEXPR size_t size() const noexcept
Returns the number of bytes.
Definition: mdbx.h++:4406
mdbx_txn_info
LIBMDBX_API int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, bool scan_rlt)
Return information about the MDBX transaction.
mdbx::buffer::append_decoded_hex
buffer & append_decoded_hex(const struct slice &data, bool ignore_spaces=false)
Definition: mdbx.h++:2556
MDBX_EINVAL
@ MDBX_EINVAL
Definition: mdbx.h:1794
true
#define true
Definition: mdbx.h:382
MDBX_put_flags_t
MDBX_put_flags_t
Data changing flags.
Definition: mdbx.h:1472
mdbx::from_base64::from_base64
MDBX_CXX11_CONSTEXPR from_base64(const slice &source, bool ignore_spaces=false) noexcept
Definition: mdbx.h++:1403
MDBX_FIRST
@ MDBX_FIRST
Definition: mdbx.h:1545
mdbx::slice::length
MDBX_CXX11_CONSTEXPR size_t length() const noexcept
Returns the number of bytes.
Definition: mdbx.h++:4386
mdbx::buffer::headroom
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t headroom() const noexcept
Returns the number of bytes that available in currently allocated storage ahead the currently beginni...
Definition: mdbx.h++:1993
mdbx_env_set_syncperiod
int mdbx_env_set_syncperiod(MDBX_env *env, unsigned seconds_16dot16)
Sets relative period since the last unsteady commit to force flush the data buffers to disk,...
Definition: mdbx.h:2567
mdbx::env::try_start_write
txn_managed try_start_write()
Tries to start write (read-write) transaction without blocking.
Definition: mdbx.h++:5007
mdbx::txn::is_dirty
bool is_dirty(const void *ptr) const
Checks whether the given data is on a dirty page.
Definition: mdbx.h++:5045
mdbx::env::geometry::size::size
MDBX_CXX11_CONSTEXPR size(intptr_t bytes) noexcept
Definition: mdbx.h++:2932
mdbx::cursor::to_previous_last_multi
move_result to_previous_last_multi(bool throw_notfound=true)
Definition: mdbx.h++:5622
mdbx::cursor::txn
operator::mdbx::txn() const
Definition: mdbx.h++:3945
LIBMDBX_API_TYPE
#define LIBMDBX_API_TYPE
Definition: mdbx.h:603
mdbx::error
Implements error information and throwing corresponding exceptions.
Definition: mdbx.h++:363
mdbx::env::dbsize_min
size_t dbsize_min() const
Returns the minimal database size in bytes for the environment.
Definition: mdbx.h++:3151
mdbx::buffer::allocator_traits
::std::allocator_traits< allocator_type > allocator_traits
Definition: mdbx.h++:1456
mdbx::slice::assign
slice & assign(const void *ptr, size_t bytes)
Definition: mdbx.h++:4289
mdbx::env::dbsize_max
size_t dbsize_max() const
Returns the maximal database size in bytes for the environment.
Definition: mdbx.h++:3153
mdbx::env::start_read
txn_managed start_read() const
Starts read (read-only) transaction.
Definition: mdbx.h++:4983
mdbx::buffer::reserve_tailroom
void reserve_tailroom(size_t wanna_tailroom)
Reserves space after the payload.
Definition: mdbx.h++:2246
mdbx::to_base64::to_base64
MDBX_CXX11_CONSTEXPR to_base64(const slice &source, unsigned wrap_width=0) noexcept
Definition: mdbx.h++:1245
mdbx::slice::base64_decode
buffer< ALLOCATOR, CAPACITY_POLICY > base64_decode(bool ignore_spaces=false, const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base64 dump from the slice content to returned buffer.
Definition: mdbx.h++:4616
mdbx::txn::try_insert
value_result try_insert(map_handle map, const slice &key, slice value)
Definition: mdbx.h++:5288
mdbx::txn::flags
MDBX_txn_flags_t flags() const
Returns transaction's flags.
Definition: mdbx.h++:5059
mdbx_cmp
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b)
Compare two keys according to a particular database.
mdbx::env::geometry::size::bytes
intptr_t bytes
Definition: mdbx.h++:2931
mdbx::buffer::end
const MDBX_CXX11_CONSTEXPR void * end() const noexcept
Return a const pointer to the end of the referenced data.
Definition: mdbx.h++:2062
MDBX_NOOVERWRITE
@ MDBX_NOOVERWRITE
Definition: mdbx.h:1477
mdbx::env::reader_info::pid
mdbx_pid_t pid
The reader process ID.
Definition: mdbx.h++:3359
mdbx::slice::safe_head
MDBX_CXX14_CONSTEXPR slice safe_head(size_t n) const
Returns the first "n" bytes of the slice.
Definition: mdbx.h++:4488
MDBX_MIN_PAGESIZE
@ MDBX_MIN_PAGESIZE
Definition: mdbx.h:771
mdbx::allocation_aware_details::move_assign_alloc< T, A, true >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:1003
MDBX_CXX11_CONSTEXPR
#define MDBX_CXX11_CONSTEXPR
Definition: mdbx.h:416
mdbx::cursor::to_current_next_multi
move_result to_current_next_multi(bool throw_notfound=true)
Definition: mdbx.h++:5638
mdbx::buffer::make_freestanding
void make_freestanding()
Makes buffer owning the data.
Definition: mdbx.h++:2106
mdbx::allocation_aware_details::swap_alloc< T, A, false >::is_nothrow
static constexpr bool is_nothrow() noexcept
Definition: mdbx.h++:1055
mdbx::to_hex
Hexadecimal encoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1135
mdbx::operator==
MDBX_CXX11_CONSTEXPR bool operator==(const error &a, const error &b) noexcept
Definition: mdbx.h++:4152
mdbx::buffer::silo::bin::allocated::ptr_
allocator_pointer ptr_
Definition: mdbx.h++:1521
mdbx_canary_get
LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary)
Returns fours integers markers (aka "canary") associated with the environment.
mdbx::buffer::append
buffer & append(const struct slice &chunk)
Definition: mdbx.h++:2510
mdbx_cursor_put
LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, const MDBX_val *key, MDBX_val *data, MDBX_put_flags_t flags)
Store by cursor.
mdbx::to_base58
Base58 encoder which satisfy SliceTranscoder concept.
Definition: mdbx.h++:1186
mdbx::buffer::reserve
void reserve(size_t wanna_headroom, size_t wanna_tailroom)
Reserves storage space.
Definition: mdbx.h++:2228
mdbx::default_capacity_policy
Definition: mdbx.h++:1095
mdbx::txn::insert_reserve
slice insert_reserve(map_handle map, const slice &key, size_t value_length)
Definition: mdbx.h++:5303
mdbx::cursor::find_key
@ find_key
Definition: mdbx.h++:3865
mdbx::map_handle::info::state
map_handle::state state
Definition: mdbx.h++:2850
mdbx::slice::encode_base58
buffer< ALLOCATOR, CAPACITY_POLICY > encode_base58(unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a Base58 dump of the slice content.
Definition: mdbx.h++:4588
mdbx::env::get_pagesize
size_t get_pagesize() const
Returns pagesize of this MDBX environment.
Definition: mdbx.h++:3228
mdbx::allocation_aware_details::allocator_is_always_equal
constexpr bool allocator_is_always_equal() noexcept
Definition: mdbx.h++:973
mdbx::error::throw_exception
void throw_exception() const
mdbx::cursor::count_multivalue
size_t count_multivalue() const
Return count of duplicates for current key.
Definition: mdbx.h++:5699
mdbx::from_hex::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes hexadecimal dump from a passed slice to returned string.
Definition: mdbx.h++:1317
mdbx_limits_valsize_max
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags)
Returns maximal data size in bytes for given page size and database flags, or -1 if pagesize is inval...
mdbx::slice::data
const MDBX_CXX11_CONSTEXPR void * data() const noexcept
Return a pointer to the beginning of the referenced data.
Definition: mdbx.h++:4372
mdbx::slice::safe_remove_prefix
void safe_remove_prefix(size_t n)
Drops the first "n" bytes from this slice.
Definition: mdbx.h++:4425
MDBX_PREV
@ MDBX_PREV
Definition: mdbx.h:1586
mdbx::txn::open_cursor
cursor_managed open_cursor(map_handle map)
Opens cursor for specified key-value map handle.
Definition: mdbx.h++:5085
mdbx::slice::operator=
slice & operator=(const slice &) noexcept=default
mdbx::slice::end_byte_ptr
const MDBX_CXX11_CONSTEXPR byte * end_byte_ptr() const noexcept
Returns casted to pointer to byte an end of data.
Definition: mdbx.h++:4344
mdbx::cursor::try_update
bool try_update(const slice &key, const slice &value)
Definition: mdbx.h++:5817
mdbx_get
LIBMDBX_API int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data)
Get items from a database.
mdbx::cursor::bind
void bind(::mdbx::txn &txn, ::mdbx::map_handle map_handle)
Bind/renew a cursor with a new transaction and specified key-value map handle.
Definition: mdbx.h++:5734
mdbx_txn_flags
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn)
Return the transaction's flags.
mdbx::exception_thunk::rethrow_captured
void rethrow_captured() const
Definition: mdbx.h++:4137
mdbx::buffer::key_from_jsonInteger
static buffer key_from_jsonInteger(const int64_t json_integer)
Definition: mdbx.h++:2617
mdbx::pair
Combines pair of slices for key and value to represent result of certain operations.
Definition: mdbx.h++:2713
mdbx::txn::sequence
uint64_t sequence(map_handle map) const
Definition: mdbx.h++:5172
mdbx_put
LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, MDBX_put_flags_t flags)
Store items into a database.
mdbx::txn::upsert_reserve
slice upsert_reserve(map_handle map, const slice &key, size_t value_length)
Definition: mdbx.h++:5333
mdbx::txn_managed
Managed database transaction.
Definition: mdbx.h++:3789
mdbx::slice::wrap
static MDBX_CXX14_CONSTEXPR slice wrap(const POD &pod)
Definition: mdbx.h++:620
mdbx::operator!=
MDBX_CXX11_CONSTEXPR bool operator!=(const error &a, const error &b) noexcept
Definition: mdbx.h++:4156
mdbx::cursor::to_next_first_multi
move_result to_next_first_multi(bool throw_notfound=true)
Definition: mdbx.h++:5646
mdbx::allocation_aware_details::move_assign_alloc< T, A, false >::is_moveable
static MDBX_CXX20_CONSTEXPR bool is_moveable(T *target, T &source) noexcept
Definition: mdbx.h++:991
mdbx::env::get_mode
env::mode get_mode() const
Returns current operation mode.
Definition: mdbx.h++:4818
mdbx::slice::is_base58
MDBX_NOTHROW_PURE_FUNCTION bool is_base58(bool ignore_spaces=false) const noexcept
Checks whether the content of the slice is a Base58 dump.
Definition: mdbx.h++:4627
mdbx::buffer::key_from
static buffer key_from(const uint32_t unsigned_int32)
Definition: mdbx.h++:2629
mdbx::env::max_maps
unsigned max_maps() const
Returns the maximum number of named databases for the environment.
Definition: mdbx.h++:4876
mdbx::buffer::key_from
static buffer key_from(const float ieee754_32bit)
Definition: mdbx.h++:2621
mdbx::cursor::next
@ next
Definition: mdbx.h++:3851
mdbx::buffer::buffer
buffer(size_t head_room, const buffer &src, size_t tail_room, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2203
mdbx::buffer::remove_prefix
void remove_prefix(size_t n) noexcept
Drops the first "n" bytes from the data chunk.
Definition: mdbx.h++:2425
MDBX_TXN_READWRITE
@ MDBX_TXN_READWRITE
Definition: mdbx.h:1376
mdbx::env::~env
~env() noexcept
Definition: mdbx.h++:4678
mdbx::buffer::tailroom
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t tailroom() const noexcept
Returns the number of bytes that available in currently allocated storage after the currently data en...
Definition: mdbx.h++:2000
MDBX_TXN_RDONLY
@ MDBX_TXN_RDONLY
Definition: mdbx.h:1382
mdbx::buffer::empty
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR bool empty() const noexcept
Checks whether the string is empty.
Definition: mdbx.h++:2366
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const ::std::basic_string_view< CHAR, T > &view, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2176
mdbx::buffer::data
const MDBX_CXX11_CONSTEXPR void * data() const noexcept
Return a const pointer to the beginning of the referenced data.
Definition: mdbx.h++:2057
MDBX_REVERSEDUP
@ MDBX_REVERSEDUP
Definition: mdbx.h:1444
mdbx::buffer::silo::bin::lastbyte
MDBX_CXX17_CONSTEXPR byte & lastbyte() noexcept
Definition: mdbx.h++:1565
mdbx::key_mode::msgpack
@ msgpack
mdbx::env::key_min
size_t key_min(key_mode mode) const noexcept
Returns the minimal key size in bytes for specified keys mode.
Definition: mdbx.h++:3155
MDBX_SET
@ MDBX_SET
Definition: mdbx.h:1595
mdbx::allocation_aware_details::move_assign_alloc
Definition: mdbx.h++:985
mdbx::txn::create_map
map_handle create_map(const char *name, const ::mdbx::key_mode key_mode=::mdbx::key_mode::usual, const ::mdbx::value_mode value_mode=::mdbx::value_mode::single)
Create new or open existing key-value map.
Definition: mdbx.h++:5108
mdbx_cursor_txn
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_txn * mdbx_cursor_txn(const MDBX_cursor *cursor)
Return the cursor's transaction handle.
mdbx::env::half_synchronous_weak_last
@ half_synchronous_weak_last
Definition: mdbx.h++:2997
mdbx::buffer::silo::bin::is_inplace
constexpr bool is_inplace() const noexcept
Definition: mdbx.h++:1569
mdbx::error::is_failure
MDBX_CXX11_CONSTEXPR bool is_failure() const noexcept
Definition: mdbx.h++:4172
MDBX_UNLIKELY
#define MDBX_UNLIKELY(cond)
Definition: mdbx.h++:167
mdbx::buffer::set_length
MDBX_CXX14_CONSTEXPR buffer & set_length(size_t bytes)
Set length of data.
Definition: mdbx.h++:2090
mdbx::from_base58::from_base58
MDBX_CXX11_CONSTEXPR from_base58(const slice &source, bool ignore_spaces=false) noexcept
Definition: mdbx.h++:1354
mdbx::cursor::~cursor
~cursor() noexcept
Definition: mdbx.h++:5525
MDBX_txn
struct MDBX_txn MDBX_txn
Opaque structure for a transaction handle.
Definition: mdbx.h:703
mdbx::cursor::txn
inline ::mdbx::txn txn() const
Returns the cursor's transaction.
Definition: mdbx.h++:5738
mdbx::buffer::key_from
static buffer key_from(const uint64_t unsigned_int64)
Definition: mdbx.h++:2609
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer() noexcept=default
mdbx_env_info_ex
LIBMDBX_API int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, MDBX_envinfo *info, size_t bytes)
Return information about the MDBX environment.
mdbx::env::geometry::make_dynamic
geometry & make_dynamic(intptr_t lower=minimal_value, intptr_t upper=maximal_value) noexcept
Definition: mdbx.h++:4706
mdbx::txn::get_canary
canary get_canary() const
Returns fours integers markers (aka "canary") associated with the environment.
Definition: mdbx.h++:5166
mdbx::get_version
const MDBX_CXX11_CONSTEXPR version_info & get_version() noexcept
Returns libmdbx version information.
Definition: mdbx.h++:4060
mdbx::from_hex::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes hexadecimal dump from a passed slice to returned buffer.
Definition: mdbx.h++:1325
mdbx::error::success_or_throw
static void success_or_throw(int error_code)
Definition: mdbx.h++:409
mdbx::slice::swap
void swap(slice &other) noexcept
Definition: mdbx.h++:4334
mdbx::buffer::silo::bin::operator=
MDBX_CXX17_CONSTEXPR bin & operator=(const bin &ditto) noexcept
Definition: mdbx.h++:1639
mdbx::cursor::current
move_result current(bool throw_notfound=true) const
Definition: mdbx.h++:5634
mdbx::buffer::buffer
MDBX_CXX20_CONSTEXPR buffer(const void *ptr, size_t bytes, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2158
MDBX_RESULT_FALSE
@ MDBX_RESULT_FALSE
Definition: mdbx.h:1650
mdbx::from_hex::from_hex
MDBX_CXX11_CONSTEXPR from_hex(const slice &source, bool ignore_spaces=false) noexcept
Definition: mdbx.h++:1309
mdbx::env::alter_flags
env & alter_flags(MDBX_env_flags_t flags, bool on_off)
Alter environment flags.
Definition: mdbx.h++:4905
mdbx::env::geometry::size_lower
intptr_t size_lower
The lower bound of database size in bytes.
Definition: mdbx.h++:2937
mdbx::env::get_durability
env::durability get_durability() const
Returns current durability mode.
Definition: mdbx.h++:4822
MDBX_TXN_RDONLY_PREPARE
@ MDBX_TXN_RDONLY_PREPARE
Definition: mdbx.h:1391
mdbx::error::error
MDBX_CXX11_CONSTEXPR error(MDBX_error_t error_code) noexcept
Definition: mdbx.h++:4144
mdbx::operator<
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool operator<(const slice &a, const slice &b) noexcept
Definition: mdbx.h++:4535
mdbx::env::operate_parameters::operate_parameters
MDBX_CXX11_CONSTEXPR operate_parameters() noexcept
Definition: mdbx.h++:3048
mdbx::error::success_or_panic
void success_or_panic(const char *context_where, const char *func_who) const noexcept
Definition: mdbx.h++:4214
mdbx::path
MDBX_STD_FILESYSTEM_PATH path
Definition: mdbx.h++:337
mdbx_dbi_sequence
LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, uint64_t increment)
Sequence generation for a database.
mdbx::env::limits::value_min
static size_t value_min(MDBX_db_flags_t flags) noexcept
Returns the minimal values size in bytes for specified database flags.
Definition: mdbx.h++:4772
mdbx::buffer::is_null
MDBX_CXX11_CONSTEXPR bool is_null() const noexcept
Checks whether the data pointer of the buffer is nullptr.
Definition: mdbx.h++:2371
MDBX_APPEND
@ MDBX_APPEND
Definition: mdbx.h:1501
mdbx_dbi_close
LIBMDBX_API int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi)
Close a database handle. Normally unnecessary.
mdbx::allocation_aware_details::swap_alloc
Definition: mdbx.h++:1052
mdbx::buffer::capacity
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t capacity() const noexcept
Returns the number of bytes that can be held in currently allocated storage.
Definition: mdbx.h++:1986
mdbx::env::geometry::size_now
intptr_t size_now
The size in bytes to setup the database size for now.
Definition: mdbx.h++:2942
MDBX_CURRENT
@ MDBX_CURRENT
Definition: mdbx.h:1488
mdbx::txn::drop_map
void drop_map(map_handle map)
Drops key-value map using handle.
Definition: mdbx.h++:5126
mdbx::error::success_or_throw
void success_or_throw() const
Definition: mdbx.h++:4195
mdbx::make_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > make_buffer(PRODUCER &producer, const ALLOCATOR &allocator=ALLOCATOR())
Definition: mdbx.h++:2641
MDBX_NEXT_NODUP
@ MDBX_NEXT_NODUP
Definition: mdbx.h:1583
mdbx::to_hex::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a hexadecimal dump of a passed slice.
Definition: mdbx.h++:1147
mdbx_env_get_fd
LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd)
Return the file descriptor for the given environment.
mdbx::env::geometry
Database geometry for size management.
Definition: mdbx.h++:2910
mdbx::buffer::operator=
buffer & operator=(struct slice &&src)
Definition: mdbx.h++:2343
mdbx::txn::reset_reading
void reset_reading()
Reset a read-only transaction.
Definition: mdbx.h++:5071
mdbx::to_base64::output
::std::ostream & output(::std::ostream &out) const
Output Base64 dump of passed slice to the std::ostream.
mdbx_dbi_open
LIBMDBX_API int mdbx_dbi_open(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, MDBX_dbi *dbi)
Open or Create a database in the environment.
mdbx::value_mode::multi
@ multi
mdbx::env::get_options
env::operate_options get_options() const
Returns current operate options.
Definition: mdbx.h++:4830
mdbx::slice::compare_lexicographically
static MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR intptr_t compare_lexicographically(const slice &a, const slice &b) noexcept
Three-way lexicographically comparison.
Definition: mdbx.h++:4518
mdbx_txn_reset
LIBMDBX_API int mdbx_txn_reset(MDBX_txn *txn)
Reset a read-only transaction.
mdbx::slice::assign
slice & assign(const ::std::basic_string_view< CHAR, T > &view)
Definition: mdbx.h++:641
mdbx::slice::slice
MDBX_CXX11_CONSTEXPR slice(size_t invalid_length) noexcept
Definition: mdbx.h++:965
mdbx::allocation_aware_details::copy_assign_alloc< T, A, true >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, const T &source) noexcept(is_nothrow())
Definition: mdbx.h++:1035
mdbx_env_set_hsr
LIBMDBX_API int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr_callback)
Sets a Handle-Slow-Readers callback to resolve database full/overflow issue due to a reader(s) which ...
mdbx::slice::is_base64
MDBX_NOTHROW_PURE_FUNCTION bool is_base64(bool ignore_spaces=false) const noexcept
Checks whether the content of the slice is a Base64 dump.
Definition: mdbx.h++:4632
mdbx::slice
References a data located outside the slice.
Definition: mdbx.h++:564
mdbx::allocation_aware_details::copy_assign_alloc
Definition: mdbx.h++:1017
mdbx_env_set_geometry
LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, intptr_t size_upper, intptr_t growth_step, intptr_t shrink_threshold, intptr_t pagesize)
Set all size-related parameters of environment, including page size and the min/max size of the memor...
mdbx::cursor_managed::operator=
cursor_managed & operator=(cursor_managed &&other)
Definition: mdbx.h++:4002
MDBX_INTEGERDUP
@ MDBX_INTEGERDUP
Definition: mdbx.h:1441
mdbx::env_managed::create_parameters
Additional parameters for creating a new database.
Definition: mdbx.h++:3464
mdbx_dbi_dupsort_depthmask
LIBMDBX_API int mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi, uint32_t *mask)
Retrieve depth (bitmask) information of nested dupsort (multi-value) B+trees for given database.
mdbx::buffer::size
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX20_CONSTEXPR size_t size() const noexcept
Returns the number of bytes.
Definition: mdbx.h++:2376
MDBX_GET_BOTH_RANGE
@ MDBX_GET_BOTH_RANGE
Definition: mdbx.h:1555
mdbx::cursor::upsert
void upsert(const slice &key, const slice &value)
Definition: mdbx.h++:5800
mdbx::buffer::byte_ptr
const MDBX_CXX11_CONSTEXPR byte * byte_ptr() const noexcept
Returns casted to const pointer to byte an address of data.
Definition: mdbx.h++:2005
MDBX_RESULT_TRUE
@ MDBX_RESULT_TRUE
Definition: mdbx.h:1653
mdbx_pid_t
pid_t mdbx_pid_t
Definition: mdbx.h:197
mdbx::buffer::operator=
buffer & operator=(const struct slice &src)
Definition: mdbx.h++:2341
mdbx::env::transaction_size_max
size_t transaction_size_max() const
Returns the maximal write transaction size (i.e. limit for summary volume of dirty pages) in bytes.
Definition: mdbx.h++:3168
mdbx::env::limits::transaction_size_max
static size_t transaction_size_max(intptr_t pagesize)
Returns the maximal write transaction size (i.e. limit for summary volume of dirty pages) in bytes fo...
Definition: mdbx.h++:4802
MDBX_CXX20_UNLIKELY
#define MDBX_CXX20_UNLIKELY
Definition: mdbx.h++:198
mdbx::from_base64::as_string
string< ALLOCATOR > as_string(const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes Base64 dump from a passed slice to returned string.
Definition: mdbx.h++:1412
mdbx::slice::assign
slice & assign(::std::basic_string_view< CHAR, T > &&view)
Definition: mdbx.h++:645
MDBX_KEYEXIST
@ MDBX_KEYEXIST
Definition: mdbx.h:1656
mdbx::slice::hash_value
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR size_t hash_value() const noexcept
Returns the hash value of referenced data.
Definition: mdbx.h++:4455
mdbx::txn::size_max
size_t size_max() const
Returns maximal write transaction size (i.e. limit for summary volume of dirty pages) in bytes.
Definition: mdbx.h++:3565
MDBX_ALLDUPS
@ MDBX_ALLDUPS
Definition: mdbx.h:1493
MDBX_IF_CONSTEXPR
#define MDBX_IF_CONSTEXPR
Definition: mdbx.h++:176
mdbx::cursor::operator=
cursor & operator=(cursor &&other) noexcept
Definition: mdbx.h++:5515
mdbx::buffer::append_hex
buffer & append_hex(const struct slice &data, bool uppercase=false, unsigned wrap_width=0)
Definition: mdbx.h++:2543
mdbx::buffer::clone
static buffer clone(const buffer &src, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2267
mdbx_cursor_create
LIBMDBX_API MDBX_cursor * mdbx_cursor_create(void *context)
Create a cursor handle but not bind it to transaction nor DBI handle.
mdbx::pair_result::done
bool done
Definition: mdbx.h++:2728
mdbx::buffer::silo::bin::inplace_lastbyte_mask
static constexpr byte inplace_lastbyte_mask() noexcept
Definition: mdbx.h++:1555
mdbx::upsert
@ upsert
Insert or update.
Definition: mdbx.h++:2873
mdbx::slice::end_char_ptr
const MDBX_CXX11_CONSTEXPR char * end_char_ptr() const noexcept
Returns casted to pointer to char an end of data.
Definition: mdbx.h++:4360
mdbx::slice::invalidate
MDBX_CXX14_CONSTEXPR void invalidate() noexcept
Depletes content of slice and make it invalid.
Definition: mdbx.h++:4412
MDBX_NEXT_DUP
@ MDBX_NEXT_DUP
Definition: mdbx.h:1575
MDBX_LAST_DUP
@ MDBX_LAST_DUP
Definition: mdbx.h:1569
mdbx::txn::open_map
map_handle open_map(const char *name, const ::mdbx::key_mode key_mode=::mdbx::key_mode::usual, const ::mdbx::value_mode value_mode=::mdbx::value_mode::single) const
Open existing key-value map.
Definition: mdbx.h++:5092
mdbx::cursor_managed::cursor_managed
cursor_managed()
Creates a new managed cursor with underlying object.
Definition: mdbx.h++:3993
mdbx::buffer::silo::bin::allocated::capacity_bytes_
size_t capacity_bytes_
Definition: mdbx.h++:1522
MDBX_PREV_DUP
@ MDBX_PREV_DUP
Definition: mdbx.h:1589
mdbx.h
The libmdbx C API header file.
MDBX_val
struct iovec MDBX_val
Generic structure used for passing keys and data in and out of the database.
Definition: mdbx.h:760
mdbx::slice::set_length
MDBX_CXX14_CONSTEXPR slice & set_length(size_t bytes)
Set slice length.
Definition: mdbx.h++:4388
mdbx::legacy_allocator
::std::string::allocator_type legacy_allocator
Legacy default allocator but it is recommended to use polymorphic_allocator.
Definition: mdbx.h++:296
mdbx::buffer::silo::bin::is_allocated
constexpr bool is_allocated() const noexcept
Definition: mdbx.h++:1572
mdbx::throw_max_length_exceeded
LIBMDBX_API void throw_max_length_exceeded()
MDBX_FIRST_ADDED_ERRCODE
@ MDBX_FIRST_ADDED_ERRCODE
Definition: mdbx.h:1745
MDBX_BUSY
@ MDBX_BUSY
Definition: mdbx.h:1742
mdbx_is_dirty
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr)
Determines whether the given address is on a dirty database page of the transaction or not.
mdbx::buffer::key_from
static buffer key_from(const double *ieee754_64bit)
Definition: mdbx.h++:2605
MDBX_FIRST_DUP
@ MDBX_FIRST_DUP
Definition: mdbx.h:1548
mdbx_mode_t
mode_t mdbx_mode_t
Definition: mdbx.h:199
mdbx::slice::hex_decode
buffer< ALLOCATOR, CAPACITY_POLICY > hex_decode(bool ignore_spaces=false, const ALLOCATOR &allocator=ALLOCATOR()) const
Decodes hexadecimal dump from the slice content to returned buffer.
Definition: mdbx.h++:4602
mdbx::cursor::to_first
move_result to_first(bool throw_notfound=true)
Definition: mdbx.h++:5614
mdbx_env_sync_ex
LIBMDBX_API int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock)
Flush the environment data buffers to disk.
mdbx::slice::as_hex_string
string< ALLOCATOR > as_hex_string(bool uppercase=false, unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a string with a hexadecimal dump of the slice content.
Definition: mdbx.h++:4561
mdbx_cursor_renew
LIBMDBX_API int mdbx_cursor_renew(MDBX_txn *txn, MDBX_cursor *cursor)
Renew a cursor handle.
mdbx::to_base64::source
const slice source
Definition: mdbx.h++:1242
MDBX_LAST_LMDB_ERRCODE
@ MDBX_LAST_LMDB_ERRCODE
Definition: mdbx.h:1738
mdbx::cursor::map
map_handle map() const
Definition: mdbx.h++:5744
mdbx_cursor_del
LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags)
Delete current key/data pair.
mdbx::slice::encode_base64
buffer< ALLOCATOR, CAPACITY_POLICY > encode_base64(unsigned wrap_width=0, const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a Base64 dump of the slice content.
Definition: mdbx.h++:4595
mdbx::cursor::to_last
move_result to_last(bool throw_notfound=true)
Definition: mdbx.h++:5654
mdbx::to_hex::source
const slice source
Definition: mdbx.h++:1136
mdbx::slice::safe_middle
MDBX_CXX14_CONSTEXPR slice safe_middle(size_t from, size_t n) const
Returns the middle "n" bytes of the slice.
Definition: mdbx.h++:4500
mdbx::cursor::multi_prevkey_lastvalue
@ multi_prevkey_lastvalue
Definition: mdbx.h++:3855
mdbx::allocation_aware_details::copy_assign_alloc< T, A, false >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, const T &source) noexcept
Definition: mdbx.h++:1021
mdbx::to_base58::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid data and could be encoded or unexpectedly not...
Definition: mdbx.h++:1236
mdbx::slice::is_hex
MDBX_NOTHROW_PURE_FUNCTION bool is_hex(bool ignore_spaces=false) const noexcept
Checks whether the content of the slice is a hexadecimal dump.
Definition: mdbx.h++:4622
mdbx::operator<=
MDBX_NOTHROW_PURE_FUNCTION MDBX_CXX14_CONSTEXPR bool operator<=(const slice &a, const slice &b) noexcept
Definition: mdbx.h++:4545
mdbx::env::set_HandleSlowReaders
env & set_HandleSlowReaders(MDBX_hsr_func *)
Sets a Handle-Slow-Readers callback to resolve database full/overflow issue due to a reader(s) which ...
Definition: mdbx.h++:4974
mdbx::cursor::try_insert_reserve
value_result try_insert_reserve(const slice &key, size_t value_length)
Definition: mdbx.h++:5784
mdbx::to_hex::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a hexadecimal dump of a passed slice.
Definition: mdbx.h++:1155
mdbx::txn::upsert
void upsert(map_handle map, const slice &key, const slice &value)
Definition: mdbx.h++:5328
MDBX_INTEGERKEY
@ MDBX_INTEGERKEY
Definition: mdbx.h:1432
mdbx::value_mode::multi_samelength
@ multi_samelength
mdbx::buffer::add_header
buffer & add_header(const struct slice &chunk)
Definition: mdbx.h++:2523
mdbx::to_base58::as_buffer
buffer< ALLOCATOR, CAPACITY_POLICY > as_buffer(const ALLOCATOR &allocator=ALLOCATOR()) const
Returns a buffer with a Base58 dump of a passed slice.
Definition: mdbx.h++:1207
mdbx::cursor::find
move_result find(const slice &key, bool throw_notfound=true)
Definition: mdbx.h++:5663
mdbx::slice::slice
MDBX_CXX11_CONSTEXPR slice() noexcept
Create an empty slice.
Definition: mdbx.h++:4266
mdbx::cursor::lower_bound_multivalue
move_result lower_bound_multivalue(const slice &key, const slice &value, bool throw_notfound=false)
Definition: mdbx.h++:5684
MDBX_GET_BOTH
@ MDBX_GET_BOTH
Definition: mdbx.h:1551
mdbx::buffer::buffer
buffer(size_t head_room, const struct slice &src, size_t tail_room, const allocator_type &allocator=allocator_type())
Definition: mdbx.h++:2194
mdbx_version
LIBMDBX_VERINFO_API const struct MDBX_version_info mdbx_version
libmdbx version information
MDBX_CXX20_CONSTEXPR
#define MDBX_CXX20_CONSTEXPR
Definition: mdbx.h++:139
MDBX_DUPSORT
@ MDBX_DUPSORT
Definition: mdbx.h:1425
mdbx::to_hex::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid data and could be encoded or unexpectedly not...
Definition: mdbx.h++:1181
mdbx::env::limits::pagesize_min
static size_t pagesize_min() noexcept
Returns the minimal database page size in bytes.
Definition: mdbx.h++:4724
mdbx::env::mode
mode
Operation mode.
Definition: mdbx.h++:2988
mdbx::buffer::end_byte_ptr
MDBX_CXX11_CONSTEXPR byte * end_byte_ptr() noexcept
Returns casted to pointer to byte an end of data.
Definition: mdbx.h++:2025
mdbx::txn::estimate_from_first
ptrdiff_t estimate_from_first(map_handle map, slice to) const
Definition: mdbx.h++:5497
mdbx::cursor::lower_bound
move_result lower_bound(const slice &key, bool throw_notfound=true)
Definition: mdbx.h++:5667
MDBX_canary
The fours integers markers (aka "canary") associated with the environment.
Definition: mdbx.h:3581
mdbx::env::operate_parameters::reclaiming
env::reclaiming_options reclaiming
Definition: mdbx.h++:3045
mdbx::from_hex::is_empty
bool is_empty() const noexcept
Checks whether a passed slice is empty, and therefore there will be no output bytes.
Definition: mdbx.h++:1342
mdbx::allocation_aware_details::swap_alloc< T, A, true >::propagate
static MDBX_CXX20_CONSTEXPR void propagate(T *target, T &source) noexcept(is_nothrow())
Definition: mdbx.h++:1080
mdbx::value_result
Combines data slice with boolean flag to represent result of certain operations.
Definition: mdbx.h++:2698
mdbx::env::get_context
void * get_context() const noexcept
Returns the application context associated with the environment.
Definition: mdbx.h++:4882
mdbx::buffer::assign
buffer & assign(::MDBX_val &&src, bool make_reference=false)
Definition: mdbx.h++:2295
mdbx::slice::middle
MDBX_CXX14_CONSTEXPR slice middle(size_t from, size_t n) const noexcept
Returns the middle "n" bytes of the slice.
Definition: mdbx.h++:4483
mdbx::from_hex::envisage_result_length
MDBX_CXX11_CONSTEXPR size_t envisage_result_length() const noexcept
Returns the number of bytes needed for conversion hexadecimal dump from a passed slice to decoded dat...
Definition: mdbx.h++:1331
mdbx::throw_out_range
LIBMDBX_API void throw_out_range()
mdbx::cursor::move_result
Definition: mdbx.h++:3870
mdbx_env_get_hsr
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_hsr_func * mdbx_env_get_hsr(const MDBX_env *env)
Gets current Handle-Slow-Readers callback used to resolve database full/overflow issue due to a reade...
mdbx::env::default_pagesize
static size_t default_pagesize() noexcept
Returns default page size for current system/platform.
Definition: mdbx.h++:3094
mdbx::value_mode::single
@ single
mdbx::slice::slice
MDBX_CXX14_CONSTEXPR slice(const ::std::basic_string_view< CHAR, T > &sv)
Create a slice that refers to the same contents as "string_view".
Definition: mdbx.h++:605
mdbx::buffer::set_end
MDBX_CXX14_CONSTEXPR buffer & set_end(const void *ptr)
Sets the length by specifying the end of the data.
Definition: mdbx.h++:2098
mdbx::env::get_operation_parameters
env::operate_parameters get_operation_parameters() const
Returns current operation parameters.
Definition: mdbx.h++:4809
MDBX_log_level_t
MDBX_log_level_t
Definition: mdbx.h:797
mdbx::exit_loop
@ exit_loop
Definition: mdbx.h++:2743
mdbx::env_managed
Managed database environment.
Definition: mdbx.h++:3442
mdbx::slice::operator=
slice & operator=(::std::basic_string_view< CHAR, T > &&view)
Definition: mdbx.h++:664
mdbx::env_managed::create_parameters::geometry
env::geometry geometry
Definition: mdbx.h++:3465
mdbx::from_base64::is_erroneous
bool is_erroneous() const noexcept
Checks whether the content of a passed slice is a valid Base64 dump, and therefore there could be dec...
mdbx_limits_dbsize_min
MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_min(intptr_t pagesize)
Returns minimal database size in bytes for given page size, or -1 if pagesize is invalid.
MDBX_CREATE
@ MDBX_CREATE
Definition: mdbx.h:1447
mdbx::slice::string_view
MDBX_CXX11_CONSTEXPR ::std::basic_string_view< CHAR, T > string_view() const noexcept
Return a string_view that references the same data as this slice.
Definition: mdbx.h++:671
MDBX_cursor
struct MDBX_cursor MDBX_cursor
Opaque structure for navigating through a database.
Definition: mdbx.h:722
mdbx::buffer::end_byte_ptr
const MDBX_CXX11_CONSTEXPR byte * end_byte_ptr() const noexcept
Returns casted to const pointer to byte an end of data.
Definition: mdbx.h++:2010
mdbx::cursor::move_operation
move_operation
Definition: mdbx.h++:3848
mdbx::cursor::last
@ last
Definition: mdbx.h++:3850
mdbx::buffer::key_from
static buffer key_from(const double ieee754_64bit)
Definition: mdbx.h++:2601
mdbx_estimate_range
LIBMDBX_API int mdbx_estimate_range(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *begin_key, MDBX_val *begin_data, MDBX_val *end_key, MDBX_val *end_data, ptrdiff_t *distance_items)
Estimates the size of a range as a number of elements.
mdbx::buffer::get_allocator
MDBX_CXX20_CONSTEXPR allocator_type get_allocator() const
Returns the associated allocator.
Definition: mdbx.h++:1964
mdbx::value_result::value_result
value_result(const slice &value, bool done) noexcept
Definition: mdbx.h++:2701