diff options
author | George Hazan <ghazan@miranda.im> | 2020-12-04 16:00:34 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-12-04 16:00:34 +0300 |
commit | 85370ab3a02ba4e167f20424d547d5e17f240352 (patch) | |
tree | 80ae78814db3425562d7e343597cc06f498bb157 /libs/libmdbx/src/mdbx.h | |
parent | e81c72fefdc67622976c0444cba59ba4d77fee70 (diff) |
libmdbx: promoting to 0.9.2.0 release
Diffstat (limited to 'libs/libmdbx/src/mdbx.h')
-rw-r--r-- | libs/libmdbx/src/mdbx.h | 300 |
1 files changed, 242 insertions, 58 deletions
diff --git a/libs/libmdbx/src/mdbx.h b/libs/libmdbx/src/mdbx.h index 4cf29e4502..966cf2e701 100644 --- a/libs/libmdbx/src/mdbx.h +++ b/libs/libmdbx/src/mdbx.h @@ -350,6 +350,17 @@ typedef mode_t mdbx_mode_t; #endif #endif /* __dll_import */ +/** \brief Auxiliary macro for robustly define the both inline version of API + * function and non-inline fallback dll-exported version for applications linked + * with old version of libmdbx, with a strictly ODR-common implementation. */ +#if !defined(LIBMDBX_INTERNALS) +#define LIBMDBX_INLINE_API(TYPE, NAME, ARGS) static __inline TYPE NAME ARGS +#else +#define LIBMDBX_INLINE_API(TYPE, NAME, ARGS) \ + /* proto of exported which uses common impl */ LIBMDBX_API TYPE NAME ARGS; \ + /* definition of common impl */ static __inline TYPE __inline_##NAME ARGS +#endif /* LIBMDBX_INLINE_API */ + /*----------------------------------------------------------------------------*/ #ifndef __cplusplus @@ -440,8 +451,27 @@ typedef mode_t mdbx_mode_t; #endif #endif /* MDBX_PRINTF_ARGS */ +/* Oh, below are some songs and dances since: + * - C++ requires explicit definition of the necessary operators. + * - the proper implementation of DEFINE_ENUM_FLAG_OPERATORS for C++ required + * the constexpr feature which is broken in most old compilers; + * - DEFINE_ENUM_FLAG_OPERATORS may be defined broken as in the Windows SDK. */ #ifndef DEFINE_ENUM_FLAG_OPERATORS -#if defined(__cplusplus) + +#ifdef __cplusplus +#if !defined(__cpp_constexpr) || __cpp_constexpr < 200704L || \ + (defined(__LCC__) && __LCC__ < 124) || \ + (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) && \ + !defined(__clang__) && !defined(__LCC__)) || \ + (defined(_MSC_VER) && _MSC_VER < 1910) || \ + (defined(__clang__) && __clang_major__ < 4) +/* The constexpr feature is not available or (may be) broken */ +#define CONSTEXPR_ENUM_FLAGS_OPERATIONS 0 +#else +/* C always allows these operators for enums */ +#define CONSTEXPR_ENUM_FLAGS_OPERATIONS 1 +#endif /* __cpp_constexpr */ + /// Define operator overloads to enable bit operations on enum values that are /// used to define flags (based on Microsoft's DEFINE_ENUM_FLAG_OPERATORS). #define DEFINE_ENUM_FLAG_OPERATORS(ENUM) \ @@ -453,19 +483,41 @@ typedef mode_t mdbx_mode_t; MDBX_CXX01_CONSTEXPR ENUM operator&(ENUM a, ENUM b) { \ return ENUM(std::size_t(a) & std::size_t(b)); \ } \ + MDBX_CXX01_CONSTEXPR ENUM operator&(ENUM a, size_t b) { \ + return ENUM(std::size_t(a) & b); \ + } \ + MDBX_CXX01_CONSTEXPR ENUM operator&(size_t a, ENUM b) { \ + return ENUM(a & std::size_t(b)); \ + } \ MDBX_CXX14_CONSTEXPR ENUM &operator&=(ENUM &a, ENUM b) { return a = a & b; } \ - MDBX_CXX01_CONSTEXPR ENUM operator~(ENUM a) { \ - return ENUM(~std::size_t(a)); \ + MDBX_CXX14_CONSTEXPR ENUM &operator&=(ENUM &a, size_t b) { \ + return a = a & b; \ + } \ + MDBX_CXX01_CONSTEXPR std::size_t operator~(ENUM a) { \ + return ~std::size_t(a); \ } \ MDBX_CXX01_CONSTEXPR ENUM operator^(ENUM a, ENUM b) { \ return ENUM(std::size_t(a) ^ std::size_t(b)); \ } \ MDBX_CXX14_CONSTEXPR ENUM &operator^=(ENUM &a, ENUM b) { return a = a ^ b; } \ } -#else /* __cplusplus */ -#define DEFINE_ENUM_FLAG_OPERATORS(ENUM) /* nope, C allows these operators */ -#endif /* !__cplusplus */ -#endif /* DEFINE_ENUM_FLAG_OPERATORS */ +#else /* __cplusplus */ +/* nope for C since it always allows these operators for enums */ +#define DEFINE_ENUM_FLAG_OPERATORS(ENUM) +#define CONSTEXPR_ENUM_FLAGS_OPERATIONS 1 +#endif /* !__cplusplus */ + +#elif !defined(CONSTEXPR_ENUM_FLAGS_OPERATIONS) + +#ifdef __cplusplus +/* DEFINE_ENUM_FLAG_OPERATORS may be defined broken as in the Windows SDK */ +#define CONSTEXPR_ENUM_FLAGS_OPERATIONS 0 +#else +/* C always allows these operators for enums */ +#define CONSTEXPR_ENUM_FLAGS_OPERATIONS 1 +#endif + +#endif /* DEFINE_ENUM_FLAG_OPERATORS */ /** @} end of Common Macros */ @@ -1120,7 +1172,7 @@ enum MDBX_env_flags_t { /** Don't sync anything but keep previous steady commits. * - * Like \ref MDBX_UTTERLY_NOSYNC the `MDBX_SAFE_NOSYNC` flag similarly disable + * Like \ref MDBX_UTTERLY_NOSYNC the `MDBX_SAFE_NOSYNC` flag disable similarly * flush system buffers to disk when committing a transaction. But there is a * huge difference in how are recycled the MVCC snapshots corresponding to * previous "steady" transactions (see below). @@ -1202,7 +1254,7 @@ enum MDBX_env_flags_t { * - a system crash immediately after commit the write transaction * high likely lead to database corruption. * - successful completion of mdbx_env_sync(force = true) after one or - * more commited transactions guarantees consistency and durability. + * more committed transactions guarantees consistency and durability. * - BUT by committing two or more transactions you back database into * a weak state, in which a system crash may lead to database corruption! * In case single transaction after mdbx_env_sync, you may lose transaction @@ -1251,10 +1303,10 @@ enum MDBX_txn_flags_t { * will be ready for use with \ref mdbx_txn_renew(). This flag allows to * preallocate memory and assign a reader slot, thus avoiding these operations * at the next start of the transaction. */ -#if defined(__cplusplus) && !defined(__cpp_constexpr) && !defined(DOXYGEN) - MDBX_TXN_RDONLY_PREPARE = uint32_t(MDBX_RDONLY) | uint32_t(MDBX_NOMEMINIT), +#if CONSTEXPR_ENUM_FLAGS_OPERATIONS || defined(DOXYGEN) + MDBX_TXN_RDONLY_PREPARE = MDBX_RDONLY | MDBX_NOMEMINIT, #else - MDBX_TXN_RDONLY_PREPARE = MDBX_RDONLY + MDBX_NOMEMINIT, + MDBX_TXN_RDONLY_PREPARE = uint32_t(MDBX_RDONLY) | uint32_t(MDBX_NOMEMINIT), #endif /** Do not block when starting a write transaction. */ @@ -1295,9 +1347,9 @@ enum MDBX_db_flags_t { /** With \ref MDBX_DUPSORT; sorted dup items have fixed size */ MDBX_DUPFIXED = UINT32_C(0x10), - /** With \ref MDBX_DUPSORT; dups are \ref MDBX_INTEGERKEY -style integers. The - * data values must all be of the same size and must be aligned while passing - * as arguments. */ + /** With \ref MDBX_DUPSORT and with \ref MDBX_DUPFIXED; dups are fixed size + * \ref MDBX_INTEGERKEY -style integers. The data values must all be of the + * same size and must be aligned while passing as arguments. */ MDBX_INTEGERDUP = UINT32_C(0x20), /** With \ref MDBX_DUPSORT; use reverse string comparison */ @@ -1462,7 +1514,20 @@ enum MDBX_cursor_op { /** \ref MDBX_DUPFIXED -only: Position at previous page and return up to * a page of duplicate data items. */ - MDBX_PREV_MULTIPLE + MDBX_PREV_MULTIPLE, + + /** Position at first key-value pair greater than or equal to specified, + * return both key and data, and the return code depends on a exact match. + * + * For non DUPSORT-ed collections this work the same to \ref MDBX_SET_RANGE, + * but returns \ref MDBX_SUCCESS if key found exactly and + * \ref MDBX_RESULT_TRUE if greater key was found. + * + * For DUPSORT-ed a data value is taken into account for duplicates, + * i.e. for a pairs/tuples of a key and an each data value of duplicates. + * Returns \ref MDBX_SUCCESS if key-value pair found exactly and + * \ref MDBX_RESULT_TRUE if the next pair was returned. */ + MDBX_SET_LOWERBOUND }; #ifndef __cplusplus /** \ingroup c_cursors */ @@ -1737,8 +1802,9 @@ LIBMDBX_API int mdbx_env_create(MDBX_env **penv); * \param [in] env An environment handle returned * by \ref mdbx_env_create() * - * \param [in] pathname The directory in which the database files reside. - * This directory must already exist and be writable. + * \param [in] pathname The pathname for the database or the directory in which + * the database files reside. In the case of directory it + * must already exist and be writable. * * \param [in] flags Special options for this environment. This parameter * must be set to 0 or by bitwise OR'ing together one @@ -1800,6 +1866,49 @@ LIBMDBX_API int mdbx_env_create(MDBX_env **penv); LIBMDBX_API int mdbx_env_open(MDBX_env *env, const char *pathname, MDBX_env_flags_t flags, mdbx_mode_t mode); +/** \brief Deletion modes for \ref mdbx_env_delete(). + * \ingroup c_extra + * \see mdbx_env_delete() */ +enum MDBX_env_delete_mode_t { + /** \brief Just delete the environment's files and directory if any. + * \note On POSIX systems, processes already working with the database will + * continue to work without interference until it close the environment. + * \note On Windows, the behavior of `MDB_ENV_JUST_DELETE` is different + * because the system does not support deleting files that are currently + * memory mapped. */ + MDBX_ENV_JUST_DELETE = 0, + /** \brief Make sure that the environment is not being used by other + * processes, or return an error otherwise. */ + MDBX_ENV_ENSURE_UNUSED = 1, + /** \brief Wait until other processes closes the environment before deletion. + */ + MDBX_ENV_WAIT_FOR_UNUSED = 2, +}; +#ifndef __cplusplus +/** \ingroup c_extra */ +typedef enum MDBX_env_delete_mode_t MDBX_env_delete_mode_t; +#endif + +/** \brief Delete the environment's files in a proper and multiprocess-safe way. + * \ingroup c_extra + * + * \param [in] pathname The pathname for the database or the directory in which + * the database files reside. + * + * \param [in] mode Special deletion mode for the environment. This + * parameter must be set to one of the values described + * above in the \ref MDBX_env_delete_mode_t section. + * + * \note The \ref MDBX_ENV_JUST_DELETE don't supported on Windows since system + * unable to delete a memory-mapped files. + * + * \returns A non-zero error value on failure and 0 on success, + * some possible errors are: + * \retval MDBX_RESULT_TRUE No corresponding files or directories were found, + * so no deletion was performed. */ +LIBMDBX_API int mdbx_env_delete(const char *pathname, + MDBX_env_delete_mode_t mode); + /** \brief Copy an MDBX environment to the specified path, with options. * \ingroup c_extra * @@ -1867,7 +1976,7 @@ struct MDBX_stat { uint64_t ms_leaf_pages; /**< Number of leaf pages */ uint64_t ms_overflow_pages; /**< Number of overflow pages */ uint64_t ms_entries; /**< Number of data items */ - uint64_t ms_mod_txnid; /**< Transaction ID of commited last modification */ + uint64_t ms_mod_txnid; /**< Transaction ID of committed last modification */ }; #ifndef __cplusplus /** \ingroup c_statinfo */ @@ -1895,11 +2004,15 @@ typedef struct MDBX_stat MDBX_stat; * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, MDBX_stat *stat, size_t bytes); + /** \brief Return statistics about the MDBX environment. * \ingroup c_statinfo * \deprecated Please use mdbx_env_stat_ex() instead. */ -MDBX_DEPRECATED LIBMDBX_API int mdbx_env_stat(MDBX_env *env, MDBX_stat *stat, - size_t bytes); +MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_stat, + (const MDBX_env *env, MDBX_stat *stat, + size_t bytes)) { + return mdbx_env_stat_ex(env, NULL, stat, bytes); +} /** \brief Information about the environment * \ingroup c_statinfo @@ -1985,8 +2098,11 @@ LIBMDBX_API int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, /** \brief Return information about the MDBX environment. * \ingroup c_statinfo * \deprecated Please use mdbx_env_info_ex() instead. */ -MDBX_DEPRECATED LIBMDBX_API int mdbx_env_info(MDBX_env *env, MDBX_envinfo *info, - size_t bytes); +MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_info, + (const MDBX_env *env, MDBX_envinfo *info, + size_t bytes)) { + return mdbx_env_info_ex(env, NULL, info, bytes); +} /** \brief Flush the environment data buffers to disk. * \ingroup c_extra @@ -2028,12 +2144,16 @@ LIBMDBX_API int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock); /** \brief The shortcut to calling \ref mdbx_env_sync_ex() with * the `force=true` and `nonblock=false` arguments. * \ingroup c_extra */ -LIBMDBX_API int mdbx_env_sync(MDBX_env *env); +LIBMDBX_INLINE_API(int, mdbx_env_sync, (MDBX_env * env)) { + return mdbx_env_sync_ex(env, true, false); +} /** \brief The shortcut to calling \ref mdbx_env_sync_ex() with * the `force=false` and `nonblock=true` arguments. * \ingroup c_extra */ -LIBMDBX_API int mdbx_env_sync_poll(MDBX_env *env); +LIBMDBX_INLINE_API(int, mdbx_env_sync_poll, (MDBX_env * env)) { + return mdbx_env_sync_ex(env, false, true); +} /** \brief Sets threshold to force flush the data buffers to disk, even any of * \ref MDBX_SAFE_NOSYNC flag in the environment. @@ -2135,7 +2255,9 @@ LIBMDBX_API int mdbx_env_close_ex(MDBX_env *env, bool dont_sync); /** \brief The shortcut to calling \ref mdbx_env_close_ex() with * the `dont_sync=false` argument. * \ingroup c_opening */ -LIBMDBX_API int mdbx_env_close(MDBX_env *env); +LIBMDBX_INLINE_API(int, mdbx_env_close, (MDBX_env * env)) { + return mdbx_env_close_ex(env, false); +} /** \brief Set environment flags. * \ingroup c_settings @@ -2356,9 +2478,11 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd); * means "keep current or use default". * * \param [in] shrink_threshold The shrink threshold in bytes, must be greater - * than zero to allow the database to shrink. + * than zero to allow the database to shrink and + * greater than growth_step to avoid shrinking + * right after grow. * Negative value means "keep current - * or use default". + * or use default". Default is 2*growth_step. * * \param [in] pagesize The database page size for new database * creation or -1 otherwise. Must be power of 2 @@ -2389,8 +2513,10 @@ LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, /** \deprecated Please use \ref mdbx_env_set_geometry() instead. * \ingroup c_settings */ -MDBX_DEPRECATED LIBMDBX_API int mdbx_env_set_mapsize(MDBX_env *env, - size_t size); +MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_set_mapsize, + (MDBX_env * env, size_t size)) { + return mdbx_env_set_geometry(env, size, size, size, -1, -1, -1); +} /** \brief Find out whether to use readahead or not, based on the given database * size and the amount of available memory. \ingroup c_extra @@ -2411,13 +2537,15 @@ LIBMDBX_API int mdbx_is_readahead_reasonable(size_t volume, /** \brief Returns the minimal database page size in bytes. * \ingroup c_statinfo */ -MDBX_NOTHROW_CONST_FUNCTION __inline intptr_t mdbx_limits_pgsize_min(void) { +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(intptr_t, mdbx_limits_pgsize_min, + (void)) { return MDBX_MIN_PAGESIZE; } /** \brief Returns the maximal database page size in bytes. * \ingroup c_statinfo */ -MDBX_NOTHROW_CONST_FUNCTION __inline intptr_t mdbx_limits_pgsize_max(void) { +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(intptr_t, mdbx_limits_pgsize_max, + (void)) { return MDBX_MAX_PAGESIZE; } @@ -2574,12 +2702,13 @@ LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API void * mdbx_env_get_userctx(const MDBX_env *env); -/** \brief Create a transaction for use with the environment. +/** \brief Create a transaction with a user provided context pointer + * for use with the environment. * \ingroup c_transactions * * The transaction handle may be discarded using \ref mdbx_txn_abort() * or \ref mdbx_txn_commit(). - * \see mdbx_txn_begin_ex() + * \see mdbx_txn_begin() * * \note A transaction and its cursors must only be used by a single thread, * and a thread may only have a single transaction at a time. If \ref MDBX_NOTLS @@ -2587,7 +2716,8 @@ mdbx_env_get_userctx(const MDBX_env *env); * * \note Cursors may not span transactions. * - * \param [in] env An environment handle returned by \ref mdbx_env_create() + * \param [in] env An environment handle returned by \ref mdbx_env_create(). + * * \param [in] parent If this parameter is non-NULL, the new transaction will * be a nested transaction, with the transaction indicated * by parent as its parent. Transactions may be nested @@ -2595,6 +2725,7 @@ mdbx_env_get_userctx(const MDBX_env *env); * not issue any other operations than mdbx_txn_commit and * \ref mdbx_txn_abort() while it has active child * transactions. + * * \param [in] flags Special options for this transaction. This parameter * must be set to 0 or by bitwise OR'ing together one * or more of the values described here: @@ -2611,6 +2742,10 @@ mdbx_env_get_userctx(const MDBX_env *env); * * \param [out] txn Address where the new MDBX_txn handle will be stored. * + * \param [in] context A pointer to application context to be associated with + * created transaction and could be retrieved by + * \ref mdbx_txn_get_userctx() until transaction finished. + * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_PANIC A fatal error occurred earlier and the @@ -2625,16 +2760,16 @@ mdbx_env_get_userctx(const MDBX_env *env); * \retval MDBX_ENOMEM Out of memory. * \retval MDBX_BUSY The write transaction is already started by the * current thread. */ -LIBMDBX_API int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, - MDBX_txn_flags_t flags, MDBX_txn **txn); +LIBMDBX_API int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, + MDBX_txn_flags_t flags, MDBX_txn **txn, + void *context); -/** \brief Create a transaction with a user provided context pointer - * for use with the environment. +/** \brief Create a transaction for use with the environment. * \ingroup c_transactions * * The transaction handle may be discarded using \ref mdbx_txn_abort() * or \ref mdbx_txn_commit(). - * \see mdbx_txn_begin() + * \see mdbx_txn_begin_ex() * * \note A transaction and its cursors must only be used by a single thread, * and a thread may only have a single transaction at a time. If \ref MDBX_NOTLS @@ -2668,10 +2803,6 @@ LIBMDBX_API int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, * * \param [out] txn Address where the new MDBX_txn handle will be stored. * - * \param [in] context A pointer to application context to be associated with - * created transaction and could be retrieved by - * \ref mdbx_txn_get_userctx() until transaction finished. - * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_PANIC A fatal error occurred earlier and the @@ -2686,9 +2817,11 @@ LIBMDBX_API int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, * \retval MDBX_ENOMEM Out of memory. * \retval MDBX_BUSY The write transaction is already started by the * current thread. */ -LIBMDBX_API int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, - MDBX_txn_flags_t flags, MDBX_txn **txn, - void *context); +LIBMDBX_INLINE_API(int, mdbx_txn_begin, + (MDBX_env * env, MDBX_txn *parent, MDBX_txn_flags_t flags, + MDBX_txn **txn)) { + return mdbx_txn_begin_ex(env, parent, flags, txn, NULL); +} /** \brief Set application information associated with the \ref MDBX_txn. * \ingroup c_transactions @@ -2722,9 +2855,9 @@ struct MDBX_txn_info { uint64_t txn_id; /** For READ-ONLY transaction: the lag from a recent MVCC-snapshot, i.e. the - number of committed transaction since read transaction started. For WRITE - transaction (provided if `scan_rlt=true`): the lag of the oldest reader - from current transaction (i.e. at least 1 if any reader running). */ + number of committed transaction since read transaction started. + For WRITE transaction (provided if `scan_rlt=true`): the lag of the oldest + reader from current transaction (i.e. at least 1 if any reader running). */ uint64_t txn_reader_lag; /** Used space by this transaction, i.e. corresponding to the last used @@ -2748,7 +2881,8 @@ struct MDBX_txn_info { /** For READ-ONLY transaction: the space available for writer(s) and that must be exhausted for reason to call the Handle-Slow-Readers callback for - this read transaction. For WRITE transaction: the space inside transaction + this read transaction. + For WRITE transaction: the space inside transaction that left to `MDBX_TXN_FULL` error. */ uint64_t txn_space_leftover; @@ -2812,6 +2946,38 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t mdbx_txn_id(const MDBX_txn *txn); +/** \brief Latency of commit stages in 1/65536 of seconds units. + * \warning This structure may be changed in future releases. + * \see mdbx_txn_commit_ex() */ +struct MDBX_commit_latency { + /** \brief Duration of preparation (commit child transactions, update + * sub-databases records and cursors destroying). */ + uint32_t preparation; + /** \brief Duration of GC/freeDB handling & updation. */ + uint32_t gc; + /** \brief Duration of internal audit if enabled. */ + uint32_t audit; + /** \brief Duration of writing dirty/modified data pages. */ + uint32_t write; + /** \brief Duration of syncing written data to the dist/storage. */ + uint32_t sync; + /** \brief Duration of transaction ending (releasing resources). */ + uint32_t ending; + /** \brief The total duration of a commit. */ + uint32_t whole; +}; +#ifndef __cplusplus +/** \ingroup c_statinfo */ +typedef struct MDBX_commit_latency MDBX_commit_latency; +#endif + +/** \brief Commit all the operations of a transaction into the database and + * collect latency information. + * \see mdbx_txn_commit() + * \ingroup c_statinfo + * \warning This function may be changed in future releases. */ +LIBMDBX_API int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency); + /** \brief Commit all the operations of a transaction into the database. * \ingroup c_transactions * @@ -2849,7 +3015,9 @@ mdbx_txn_id(const MDBX_txn *txn); * \retval MDBX_ENOSPC No more disk space. * \retval MDBX_EIO A system-level I/O error occurred. * \retval MDBX_ENOMEM Out of memory. */ -LIBMDBX_API int mdbx_txn_commit(MDBX_txn *txn); +LIBMDBX_INLINE_API(int, mdbx_txn_commit, (MDBX_txn * txn)) { + return mdbx_txn_commit_ex(txn, NULL); +} /** \brief Abandon all the operations of the transaction instead of saving them. * \ingroup c_transactions @@ -3149,13 +3317,13 @@ mdbx_key_from_float(const float ieee754_32bit); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint32_t mdbx_key_from_ptrfloat(const float *const ieee754_32bit); -MDBX_NOTHROW_CONST_FUNCTION __inline uint64_t -mdbx_key_from_int64(const int64_t i64) { +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(uint64_t, mdbx_key_from_int64, + (const int64_t i64)) { return UINT64_C(0x8000000000000000) + i64; } -MDBX_NOTHROW_CONST_FUNCTION __inline uint32_t -mdbx_key_from_int32(const int32_t i32) { +MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(uint32_t, mdbx_key_from_int32, + (const int32_t i32)) { return UINT32_C(0x80000000) + i32; } /** @} */ @@ -3247,7 +3415,11 @@ LIBMDBX_API int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags, unsigned *state); /** \brief The shortcut to calling \ref mdbx_dbi_flags_ex() with `state=NULL` * for discarding it result. \ingroup c_statinfo */ -LIBMDBX_API int mdbx_dbi_flags(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags); +LIBMDBX_INLINE_API(int, mdbx_dbi_flags, + (MDBX_txn * txn, MDBX_dbi dbi, unsigned *flags)) { + unsigned state; + return mdbx_dbi_flags_ex(txn, dbi, flags, &state); +} /** \brief Close a database handle. Normally unnecessary. * \ingroup c_dbi @@ -3711,6 +3883,18 @@ mdbx_cursor_txn(const MDBX_cursor *cursor); * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */ LIBMDBX_API MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *cursor); +/** \brief Copy cursor position and state. + * \ingroup c_cursors + * + * \param [in] src A source cursor handle returned + * by \ref mdbx_cursor_create() or \ref mdbx_cursor_open(). + * + * \param [in,out] dest A destination cursor handle returned + * by \ref mdbx_cursor_create() or \ref mdbx_cursor_open(). + * + * \returns A non-zero error value on failure and 0 on success. */ +LIBMDBX_API int mdbx_cursor_copy(const MDBX_cursor *src, MDBX_cursor *dest); + /** \brief Retrieve by cursor. * \ingroup c_crud * @@ -4251,7 +4435,7 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env); * \param [in] pid A pid of the reader process. * \param [in] tid A thread_id of the reader thread. * \param [in] laggard An oldest read transaction number on which stalled. - * \param [in] gap A lag from the last commited txn. + * \param [in] gap A lag from the last committed txn. * \param [in] space A space that actually become available for reuse after * this reader finished. The callback function can take * this value into account to evaluate the impact that |