summaryrefslogtreecommitdiff
path: root/libs/libmdbx/src/mdbx.h
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-12-04 16:00:34 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-12-04 16:00:34 +0300
commit85370ab3a02ba4e167f20424d547d5e17f240352 (patch)
tree80ae78814db3425562d7e343597cc06f498bb157 /libs/libmdbx/src/mdbx.h
parente81c72fefdc67622976c0444cba59ba4d77fee70 (diff)
libmdbx: promoting to 0.9.2.0 release
Diffstat (limited to 'libs/libmdbx/src/mdbx.h')
-rw-r--r--libs/libmdbx/src/mdbx.h300
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