mdbx: add LIBMDBX_INLINE_API (both inline and non-inline of some API functions).

Change-Id: I00c2b6d3d2a0467080791ea0c1c2242742a20c78
This commit is contained in:
Leonid Yuriev 2020-10-14 18:15:50 +03:00
parent 38485c9f30
commit 7cf92b66cf
3 changed files with 183 additions and 135 deletions

177
mdbx.h
View File

@ -350,6 +350,17 @@ typedef mode_t mdbx_mode_t;
#endif #endif
#endif /* __dll_import */ #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) || defined(DOXYGEN)
#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 #ifndef __cplusplus
@ -1971,11 +1982,15 @@ typedef struct MDBX_stat MDBX_stat;
* \returns A non-zero error value on failure and 0 on success. */ * \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, LIBMDBX_API int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_stat *stat, size_t bytes); MDBX_stat *stat, size_t bytes);
/** \brief Return statistics about the MDBX environment. /** \brief Return statistics about the MDBX environment.
* \ingroup c_statinfo * \ingroup c_statinfo
* \deprecated Please use mdbx_env_stat_ex() instead. */ * \deprecated Please use mdbx_env_stat_ex() instead. */
MDBX_DEPRECATED LIBMDBX_API int mdbx_env_stat(MDBX_env *env, MDBX_stat *stat, MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_stat,
size_t bytes); (const MDBX_env *env, MDBX_stat *stat,
size_t bytes)) {
return mdbx_env_stat_ex(env, NULL, stat, bytes);
}
/** \brief Information about the environment /** \brief Information about the environment
* \ingroup c_statinfo * \ingroup c_statinfo
@ -2061,8 +2076,11 @@ LIBMDBX_API int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
/** \brief Return information about the MDBX environment. /** \brief Return information about the MDBX environment.
* \ingroup c_statinfo * \ingroup c_statinfo
* \deprecated Please use mdbx_env_info_ex() instead. */ * \deprecated Please use mdbx_env_info_ex() instead. */
MDBX_DEPRECATED LIBMDBX_API int mdbx_env_info(MDBX_env *env, MDBX_envinfo *info, MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_info,
size_t bytes); (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. /** \brief Flush the environment data buffers to disk.
* \ingroup c_extra * \ingroup c_extra
@ -2104,12 +2122,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 /** \brief The shortcut to calling \ref mdbx_env_sync_ex() with
* the `force=true` and `nonblock=false` arguments. * the `force=true` and `nonblock=false` arguments.
* \ingroup c_extra */ * \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 /** \brief The shortcut to calling \ref mdbx_env_sync_ex() with
* the `force=false` and `nonblock=true` arguments. * the `force=false` and `nonblock=true` arguments.
* \ingroup c_extra */ * \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 /** \brief Sets threshold to force flush the data buffers to disk, even any of
* \ref MDBX_SAFE_NOSYNC flag in the environment. * \ref MDBX_SAFE_NOSYNC flag in the environment.
@ -2211,7 +2233,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 /** \brief The shortcut to calling \ref mdbx_env_close_ex() with
* the `dont_sync=false` argument. * the `dont_sync=false` argument.
* \ingroup c_opening */ * \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. /** \brief Set environment flags.
* \ingroup c_settings * \ingroup c_settings
@ -2465,8 +2489,10 @@ LIBMDBX_API int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
/** \deprecated Please use \ref mdbx_env_set_geometry() instead. /** \deprecated Please use \ref mdbx_env_set_geometry() instead.
* \ingroup c_settings */ * \ingroup c_settings */
MDBX_DEPRECATED LIBMDBX_API int mdbx_env_set_mapsize(MDBX_env *env, MDBX_DEPRECATED LIBMDBX_INLINE_API(int, mdbx_env_set_mapsize,
size_t size); (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 /** \brief Find out whether to use readahead or not, based on the given database
* size and the amount of available memory. \ingroup c_extra * size and the amount of available memory. \ingroup c_extra
@ -2487,13 +2513,15 @@ LIBMDBX_API int mdbx_is_readahead_reasonable(size_t volume,
/** \brief Returns the minimal database page size in bytes. /** \brief Returns the minimal database page size in bytes.
* \ingroup c_statinfo */ * \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; return MDBX_MIN_PAGESIZE;
} }
/** \brief Returns the maximal database page size in bytes. /** \brief Returns the maximal database page size in bytes.
* \ingroup c_statinfo */ * \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; return MDBX_MAX_PAGESIZE;
} }
@ -2650,60 +2678,6 @@ LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx);
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API void * MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API void *
mdbx_env_get_userctx(const MDBX_env *env); mdbx_env_get_userctx(const MDBX_env *env);
/** \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_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
* is in use, this does not apply to read-only transactions.
*
* \note Cursors may not span transactions.
*
* \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
* to any level. A parent transaction and its cursors may
* 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:
* - \ref MDBX_RDONLY This transaction will not perform
* any write operations.
*
* - \ref MDBX_TXN_TRY Do not block when starting
* a write transaction.
*
* - \ref MDBX_SAFE_NOSYNC, \ref MDBX_NOMETASYNC.
* Do not sync data to disk corresponding
* to \ref MDBX_NOMETASYNC or \ref MDBX_SAFE_NOSYNC
* description. \see sync_modes
*
* \param [out] txn Address where the new MDBX_txn handle will be stored.
*
* \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
* environment must be shut down.
* \retval MDBX_UNABLE_EXTEND_MAPSIZE Another process wrote data beyond
* this MDBX_env's mapsize and this
* environment map must be resized as well.
* See \ref mdbx_env_set_mapsize().
* \retval MDBX_READERS_FULL A read-only transaction was requested and
* the reader lock table is full.
* See \ref mdbx_env_set_maxreaders().
* \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);
/** \brief Create a transaction with a user provided context pointer /** \brief Create a transaction with a user provided context pointer
* for use with the environment. * for use with the environment.
* \ingroup c_transactions * \ingroup c_transactions
@ -2766,6 +2740,65 @@ LIBMDBX_API int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent,
MDBX_txn_flags_t flags, MDBX_txn **txn, MDBX_txn_flags_t flags, MDBX_txn **txn,
void *context); void *context);
/** \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_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
* is in use, this does not apply to read-only transactions.
*
* \note Cursors may not span transactions.
*
* \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
* to any level. A parent transaction and its cursors may
* 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:
* - \ref MDBX_RDONLY This transaction will not perform
* any write operations.
*
* - \ref MDBX_TXN_TRY Do not block when starting
* a write transaction.
*
* - \ref MDBX_SAFE_NOSYNC, \ref MDBX_NOMETASYNC.
* Do not sync data to disk corresponding
* to \ref MDBX_NOMETASYNC or \ref MDBX_SAFE_NOSYNC
* description. \see sync_modes
*
* \param [out] txn Address where the new MDBX_txn handle will be stored.
*
* \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
* environment must be shut down.
* \retval MDBX_UNABLE_EXTEND_MAPSIZE Another process wrote data beyond
* this MDBX_env's mapsize and this
* environment map must be resized as well.
* See \ref mdbx_env_set_mapsize().
* \retval MDBX_READERS_FULL A read-only transaction was requested and
* the reader lock table is full.
* See \ref mdbx_env_set_maxreaders().
* \retval MDBX_ENOMEM Out of memory.
* \retval MDBX_BUSY The write transaction is already started by the
* current thread. */
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. /** \brief Set application information associated with the \ref MDBX_txn.
* \ingroup c_transactions * \ingroup c_transactions
* \see mdbx_txn_get_userctx() * \see mdbx_txn_get_userctx()
@ -3225,13 +3258,13 @@ mdbx_key_from_float(const float ieee754_32bit);
MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint32_t MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint32_t
mdbx_key_from_ptrfloat(const float *const ieee754_32bit); mdbx_key_from_ptrfloat(const float *const ieee754_32bit);
MDBX_NOTHROW_CONST_FUNCTION __inline uint64_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(uint64_t, mdbx_key_from_int64,
mdbx_key_from_int64(const int64_t i64) { (const int64_t i64)) {
return UINT64_C(0x8000000000000000) + i64; return UINT64_C(0x8000000000000000) + i64;
} }
MDBX_NOTHROW_CONST_FUNCTION __inline uint32_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_INLINE_API(uint32_t, mdbx_key_from_int32,
mdbx_key_from_int32(const int32_t i32) { (const int32_t i32)) {
return UINT32_C(0x80000000) + i32; return UINT32_C(0x80000000) + i32;
} }
/** @} */ /** @} */
@ -3323,7 +3356,11 @@ LIBMDBX_API int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags,
unsigned *state); unsigned *state);
/** \brief The shortcut to calling \ref mdbx_dbi_flags_ex() with `state=NULL` /** \brief The shortcut to calling \ref mdbx_dbi_flags_ex() with `state=NULL`
* for discarding it result. \ingroup c_statinfo */ * 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. /** \brief Close a database handle. Normally unnecessary.
* \ingroup c_dbi * \ingroup c_dbi

View File

@ -4663,7 +4663,7 @@ static __always_inline __maybe_unused int ignore_enosys(int err) {
#endif /* defined(_WIN32) || defined(_WIN64) */ #endif /* defined(_WIN32) || defined(_WIN64) */
/* Turn on/off readahead. It's harmful when the DB is larger than RAM. */ /* Turn on/off readahead. It's harmful when the DB is larger than RAM. */
static int __cold mdbx_set_readahead(MDBX_env *env, const size_t offset, static __cold int mdbx_set_readahead(MDBX_env *env, const size_t offset,
const size_t length, const bool enable) { const size_t length, const bool enable) {
assert(length > 0); assert(length > 0);
mdbx_notice("readahead %s %u..%u", enable ? "ON" : "OFF", mdbx_notice("readahead %s %u..%u", enable ? "ON" : "OFF",
@ -5830,12 +5830,10 @@ __cold int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock) {
return mdbx_env_sync_internal(env, force, nonblock); return mdbx_env_sync_internal(env, force, nonblock);
} }
__cold int mdbx_env_sync(MDBX_env *env) { __cold int mdbx_env_sync(MDBX_env *env) { return __inline_mdbx_env_sync(env); }
return mdbx_env_sync_ex(env, true, false);
}
__cold int mdbx_env_sync_poll(MDBX_env *env) { __cold int mdbx_env_sync_poll(MDBX_env *env) {
return mdbx_env_sync_ex(env, false, true); return __inline_mdbx_env_sync_poll(env);
} }
/* Back up parent txn's cursors, then grab the originals for tracking */ /* Back up parent txn's cursors, then grab the originals for tracking */
@ -6483,7 +6481,7 @@ int mdbx_txn_renew(MDBX_txn *txn) {
int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags, int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
MDBX_txn **ret) { MDBX_txn **ret) {
return mdbx_txn_begin_ex(env, parent, flags, ret, nullptr); return __inline_mdbx_txn_begin(env, parent, flags, ret);
} }
int mdbx_txn_set_userctx(MDBX_txn *txn, void *ctx) { int mdbx_txn_set_userctx(MDBX_txn *txn, void *ctx) {
@ -8409,12 +8407,10 @@ fail:
return rc; return rc;
} }
static int __cold mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta, static __cold int
uint64_t *filesize, mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta, uint64_t *filesize,
const MDBX_page *const page, const MDBX_page *const page, const unsigned meta_number,
const unsigned meta_number, MDBX_meta *dest, const unsigned guess_pagesize) {
MDBX_meta *dest,
const unsigned guess_pagesize) {
if (meta->mm_magic_and_version != MDBX_DATA_MAGIC && if (meta->mm_magic_and_version != MDBX_DATA_MAGIC &&
meta->mm_magic_and_version != MDBX_DATA_MAGIC_DEVEL) { meta->mm_magic_and_version != MDBX_DATA_MAGIC_DEVEL) {
mdbx_error("meta[%u] has invalid magic/version %" PRIx64, meta_number, mdbx_error("meta[%u] has invalid magic/version %" PRIx64, meta_number,
@ -8606,7 +8602,7 @@ static int __cold mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta,
/* Read the environment parameters of a DB environment /* Read the environment parameters of a DB environment
* before mapping it into memory. */ * before mapping it into memory. */
static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *dest, static __cold int mdbx_read_header(MDBX_env *env, MDBX_meta *dest,
uint64_t *filesize, uint64_t *filesize,
const int lck_exclusive) { const int lck_exclusive) {
int rc = mdbx_filesize(env->me_lazy_fd, filesize); int rc = mdbx_filesize(env->me_lazy_fd, filesize);
@ -9096,7 +9092,7 @@ static void __cold mdbx_setup_pagesize(MDBX_env *env, const size_t pagesize) {
mdbx_assert(env, bytes2pgno(env, pagesize + pagesize) == 2); mdbx_assert(env, bytes2pgno(env, pagesize + pagesize) == 2);
} }
int __cold mdbx_env_create(MDBX_env **penv) { __cold int mdbx_env_create(MDBX_env **penv) {
MDBX_env *env = mdbx_calloc(1, sizeof(MDBX_env)); MDBX_env *env = mdbx_calloc(1, sizeof(MDBX_env));
if (unlikely(!env)) if (unlikely(!env))
return MDBX_ENOMEM; return MDBX_ENOMEM;
@ -9497,11 +9493,11 @@ bailout:
return rc; return rc;
} }
int __cold mdbx_env_set_mapsize(MDBX_env *env, size_t size) { __cold int mdbx_env_set_mapsize(MDBX_env *env, size_t size) {
return mdbx_env_set_geometry(env, size, size, size, -1, -1, -1); return __inline_mdbx_env_set_mapsize(env, size);
} }
int __cold mdbx_env_set_maxdbs(MDBX_env *env, MDBX_dbi dbs) { __cold int mdbx_env_set_maxdbs(MDBX_env *env, MDBX_dbi dbs) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -9516,7 +9512,7 @@ int __cold mdbx_env_set_maxdbs(MDBX_env *env, MDBX_dbi dbs) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_get_maxdbs(MDBX_env *env, MDBX_dbi *dbs) { __cold int mdbx_env_get_maxdbs(MDBX_env *env, MDBX_dbi *dbs) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -9528,7 +9524,7 @@ int __cold mdbx_env_get_maxdbs(MDBX_env *env, MDBX_dbi *dbs) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_set_maxreaders(MDBX_env *env, unsigned readers) { __cold int mdbx_env_set_maxreaders(MDBX_env *env, unsigned readers) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -9543,7 +9539,7 @@ int __cold mdbx_env_set_maxreaders(MDBX_env *env, unsigned readers) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) { __cold int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -9556,7 +9552,7 @@ int __cold mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) {
} }
/* Further setup required for opening an MDBX environment */ /* Further setup required for opening an MDBX environment */
static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) { static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
uint64_t filesize_before; uint64_t filesize_before;
MDBX_meta meta; MDBX_meta meta;
int rc = MDBX_RESULT_FALSE; int rc = MDBX_RESULT_FALSE;
@ -10004,7 +10000,7 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
/******************************************************************************/ /******************************************************************************/
/* Open and/or initialize the lock region for the environment. */ /* Open and/or initialize the lock region for the environment. */
static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, static __cold int mdbx_setup_lck(MDBX_env *env, char *lck_pathname,
mdbx_mode_t mode) { mdbx_mode_t mode) {
mdbx_assert(env, env->me_lazy_fd != INVALID_HANDLE_VALUE); mdbx_assert(env, env->me_lazy_fd != INVALID_HANDLE_VALUE);
mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE); mdbx_assert(env, env->me_lfd == INVALID_HANDLE_VALUE);
@ -10840,7 +10836,7 @@ bailout:
} }
/* Destroy resources from mdbx_env_open(), clear our readers & DBIs */ /* Destroy resources from mdbx_env_open(), clear our readers & DBIs */
static int __cold mdbx_env_close0(MDBX_env *env) { static __cold int mdbx_env_close0(MDBX_env *env) {
env->me_stuck_meta = -1; env->me_stuck_meta = -1;
if (!(env->me_flags & MDBX_ENV_ACTIVE)) { if (!(env->me_flags & MDBX_ENV_ACTIVE)) {
mdbx_ensure(env, env->me_lcklist_next == nullptr); mdbx_ensure(env, env->me_lcklist_next == nullptr);
@ -10909,7 +10905,7 @@ static int __cold mdbx_env_close0(MDBX_env *env) {
return rc; return rc;
} }
int __cold mdbx_env_close_ex(MDBX_env *env, bool dont_sync) { __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
MDBX_page *dp; MDBX_page *dp;
int rc = MDBX_SUCCESS; int rc = MDBX_SUCCESS;
@ -10989,7 +10985,7 @@ int __cold mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
} }
__cold int mdbx_env_close(MDBX_env *env) { __cold int mdbx_env_close(MDBX_env *env) {
return mdbx_env_close_ex(env, false); return __inline_mdbx_env_close(env);
} }
/* Compare two items pointing at aligned unsigned int's. */ /* Compare two items pointing at aligned unsigned int's. */
@ -16202,7 +16198,7 @@ bailout:
* *
* [in] my control structure. * [in] my control structure.
* [in] adjust (1 to hand off 1 buffer) | (MDBX_EOF when ending). */ * [in] adjust (1 to hand off 1 buffer) | (MDBX_EOF when ending). */
static int __cold mdbx_env_cthr_toggle(mdbx_copy *my, int adjust) { static __cold int mdbx_env_cthr_toggle(mdbx_copy *my, int adjust) {
mdbx_condpair_lock(&my->mc_condpair); mdbx_condpair_lock(&my->mc_condpair);
my->mc_new += (short)adjust; my->mc_new += (short)adjust;
mdbx_condpair_signal(&my->mc_condpair, true); mdbx_condpair_signal(&my->mc_condpair, true);
@ -16223,7 +16219,7 @@ static int __cold mdbx_env_cthr_toggle(mdbx_copy *my, int adjust) {
* [in] my control structure. * [in] my control structure.
* [in,out] pg database root. * [in,out] pg database root.
* [in] flags includes F_DUPDATA if it is a sorted-duplicate sub-DB. */ * [in] flags includes F_DUPDATA if it is a sorted-duplicate sub-DB. */
static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) { static __cold int mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
MDBX_cursor_couple couple; MDBX_cursor_couple couple;
MDBX_page *mo, *mp, *leaf; MDBX_page *mo, *mp, *leaf;
char *buf, *ptr; char *buf, *ptr;
@ -16422,7 +16418,7 @@ static __cold void make_sizeable(MDBX_meta *meta) {
} }
/* Copy environment with compaction. */ /* Copy environment with compaction. */
static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn, static __cold int mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
mdbx_filehandle_t fd, uint8_t *buffer, mdbx_filehandle_t fd, uint8_t *buffer,
const bool dest_is_pipe, const int flags) { const bool dest_is_pipe, const int flags) {
const size_t meta_bytes = pgno2bytes(env, NUM_METAS); const size_t meta_bytes = pgno2bytes(env, NUM_METAS);
@ -16559,7 +16555,7 @@ static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
} }
/* Copy environment as-is. */ /* Copy environment as-is. */
static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn, static __cold int mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
mdbx_filehandle_t fd, uint8_t *buffer, mdbx_filehandle_t fd, uint8_t *buffer,
const bool dest_is_pipe, const int flags) { const bool dest_is_pipe, const int flags) {
/* We must start the actual read txn after blocking writers */ /* We must start the actual read txn after blocking writers */
@ -16666,7 +16662,7 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
return rc; return rc;
} }
int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, __cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
unsigned flags) { unsigned flags) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -16731,7 +16727,7 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
return rc; return rc;
} }
int __cold mdbx_env_copy(MDBX_env *env, const char *dest_path, __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
MDBX_copy_flags_t flags) { MDBX_copy_flags_t flags) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -16793,7 +16789,7 @@ int __cold mdbx_env_copy(MDBX_env *env, const char *dest_path,
/******************************************************************************/ /******************************************************************************/
int __cold mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags, __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
bool onoff) { bool onoff) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -16821,7 +16817,7 @@ int __cold mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) { __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16833,7 +16829,7 @@ int __cold mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_set_userctx(MDBX_env *env, void *ctx) { __cold int mdbx_env_set_userctx(MDBX_env *env, void *ctx) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16846,7 +16842,7 @@ void *__cold mdbx_env_get_userctx(const MDBX_env *env) {
return env ? env->me_userctx : NULL; return env ? env->me_userctx : NULL;
} }
int __cold mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) { __cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16860,7 +16856,7 @@ int __cold mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) {
#endif #endif
} }
int __cold mdbx_env_get_path(const MDBX_env *env, const char **arg) { __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16872,7 +16868,7 @@ int __cold mdbx_env_get_path(const MDBX_env *env, const char **arg) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) { __cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -16902,11 +16898,11 @@ static void mdbx_stat0(const MDBX_env *env, const MDBX_db *db, MDBX_stat *dest,
dest->ms_mod_txnid = db->md_mod_txnid; dest->ms_mod_txnid = db->md_mod_txnid;
} }
int __cold mdbx_env_stat(MDBX_env *env, MDBX_stat *dest, size_t bytes) { __cold int mdbx_env_stat(const MDBX_env *env, MDBX_stat *stat, size_t bytes) {
return mdbx_env_stat_ex(env, NULL, dest, bytes); return __inline_mdbx_env_stat(env, stat, bytes);
} }
int __cold mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, __cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_stat *dest, size_t bytes) { MDBX_stat *dest, size_t bytes) {
if (unlikely((env == NULL && txn == NULL) || dest == NULL)) if (unlikely((env == NULL && txn == NULL) || dest == NULL))
return MDBX_EINVAL; return MDBX_EINVAL;
@ -16944,7 +16940,7 @@ int __cold mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
} }
} }
int __cold mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi, __cold int mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi,
uint32_t *mask) { uint32_t *mask) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED); int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -16995,11 +16991,12 @@ int __cold mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi,
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc; return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
} }
int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) { __cold int mdbx_env_info(const MDBX_env *env, MDBX_envinfo *info,
return mdbx_env_info_ex(env, NULL, arg, bytes); size_t bytes) {
return __inline_mdbx_env_info(env, info, bytes);
} }
int __cold mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn, __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
MDBX_envinfo *arg, size_t bytes) { MDBX_envinfo *arg, size_t bytes) {
if (unlikely((env == NULL && txn == NULL) || arg == NULL)) if (unlikely((env == NULL && txn == NULL) || arg == NULL))
return MDBX_EINVAL; return MDBX_EINVAL;
@ -17418,7 +17415,7 @@ int mdbx_dbi_open_ex(MDBX_txn *txn, const char *table_name,
return dbi_open(txn, table_name, table_flags, dbi, keycmp, datacmp); return dbi_open(txn, table_name, table_flags, dbi, keycmp, datacmp);
} }
int __cold mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest, __cold int mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest,
size_t bytes) { size_t bytes) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED); int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -17500,8 +17497,7 @@ int mdbx_dbi_flags_ex(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags,
} }
int mdbx_dbi_flags(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags) { int mdbx_dbi_flags(MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags) {
unsigned state; return __inline_mdbx_dbi_flags(txn, dbi, flags);
return mdbx_dbi_flags_ex(txn, dbi, flags, &state);
} }
/* Add all the DB's pages to the free list. /* Add all the DB's pages to the free list.
@ -17690,7 +17686,7 @@ int mdbx_set_dupsort(MDBX_txn *txn, MDBX_dbi dbi, MDBX_cmp_func *cmp) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func, __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func,
void *ctx) { void *ctx) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -17790,7 +17786,7 @@ static bool __cold mdbx_pid_insert(uint32_t *ids, uint32_t pid) {
return true; return true;
} }
int __cold mdbx_reader_check(MDBX_env *env, int *dead) { __cold int mdbx_reader_check(MDBX_env *env, int *dead) {
if (dead) if (dead)
*dead = 0; *dead = 0;
return mdbx_cleanup_dead_readers(env, false, dead); return mdbx_cleanup_dead_readers(env, false, dead);
@ -17800,9 +17796,8 @@ int __cold mdbx_reader_check(MDBX_env *env, int *dead) {
* MDBX_RESULT_TRUE - done and mutex recovered * MDBX_RESULT_TRUE - done and mutex recovered
* MDBX_SUCCESS - done * MDBX_SUCCESS - done
* Otherwise errcode. */ * Otherwise errcode. */
MDBX_INTERNAL_FUNC int __cold mdbx_cleanup_dead_readers(MDBX_env *env, MDBX_INTERNAL_FUNC __cold int
int rdt_locked, mdbx_cleanup_dead_readers(MDBX_env *env, int rdt_locked, int *dead) {
int *dead) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -17899,7 +17894,7 @@ MDBX_INTERNAL_FUNC int __cold mdbx_cleanup_dead_readers(MDBX_env *env,
return rc; return rc;
} }
int __cold mdbx_setup_debug(int loglevel, int flags, MDBX_debug_func *logger) { __cold int mdbx_setup_debug(int loglevel, int flags, MDBX_debug_func *logger) {
const int rc = mdbx_runtime_flags | (mdbx_loglevel << 16); const int rc = mdbx_runtime_flags | (mdbx_loglevel << 16);
if (loglevel != MDBX_LOG_DONTCHANGE) if (loglevel != MDBX_LOG_DONTCHANGE)
@ -18017,7 +18012,7 @@ static txnid_t __cold mdbx_kick_longlived_readers(MDBX_env *env,
return mdbx_find_oldest(env->me_txn); return mdbx_find_oldest(env->me_txn);
} }
int __cold mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold) { __cold int mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -18037,7 +18032,7 @@ int __cold mdbx_env_set_syncbytes(MDBX_env *env, size_t threshold) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_set_syncperiod(MDBX_env *env, unsigned seconds_16dot16) { __cold int mdbx_env_set_syncperiod(MDBX_env *env, unsigned seconds_16dot16) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -18057,7 +18052,7 @@ int __cold mdbx_env_set_syncperiod(MDBX_env *env, unsigned seconds_16dot16) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
int __cold mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr) { __cold int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr) {
int rc = check_env(env); int rc = check_env(env);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -18114,7 +18109,7 @@ typedef struct mdbx_walk_ctx {
bool mw_dont_check_keys_ordering; bool mw_dont_check_keys_ordering;
} mdbx_walk_ctx_t; } mdbx_walk_ctx_t;
static int __cold mdbx_walk_sdb(mdbx_walk_ctx_t *ctx, MDBX_db *const db, static __cold int mdbx_walk_sdb(mdbx_walk_ctx_t *ctx, MDBX_db *const db,
const char *name, int deep); const char *name, int deep);
static MDBX_page_type_t walk_page_type(const MDBX_page *mp) { static MDBX_page_type_t walk_page_type(const MDBX_page *mp) {
@ -18135,7 +18130,7 @@ static MDBX_page_type_t walk_page_type(const MDBX_page *mp) {
} }
/* Depth-first tree traversal. */ /* Depth-first tree traversal. */
static int __cold mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno, static __cold int mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno,
const char *name, int deep, const char *name, int deep,
txnid_t parent_txnid) { txnid_t parent_txnid) {
assert(pgno != P_INVALID); assert(pgno != P_INVALID);
@ -18373,7 +18368,7 @@ static int __cold mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno,
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
static int __cold mdbx_walk_sdb(mdbx_walk_ctx_t *ctx, MDBX_db *const db, static __cold int mdbx_walk_sdb(mdbx_walk_ctx_t *ctx, MDBX_db *const db,
const char *name, int deep) { const char *name, int deep) {
if (unlikely(db->md_root == P_INVALID)) if (unlikely(db->md_root == P_INVALID))
return MDBX_SUCCESS; /* empty db */ return MDBX_SUCCESS; /* empty db */
@ -18396,7 +18391,7 @@ static int __cold mdbx_walk_sdb(mdbx_walk_ctx_t *ctx, MDBX_db *const db,
return rc; return rc;
} }
int __cold mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, __cold int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
void *user, bool dont_check_keys_ordering) { void *user, bool dont_check_keys_ordering) {
int rc = check_txn(txn, MDBX_TXN_BLOCKED); int rc = check_txn(txn, MDBX_TXN_BLOCKED);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
@ -19164,6 +19159,14 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
__cold MDBX_NOTHROW_CONST_FUNCTION intptr_t mdbx_limits_pgsize_min(void) {
return __inline_mdbx_limits_pgsize_min();
}
__cold MDBX_NOTHROW_CONST_FUNCTION intptr_t mdbx_limits_pgsize_max(void) {
return __inline_mdbx_limits_pgsize_max();
}
__cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) { __cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) {
if (pagesize < 1) if (pagesize < 1)
pagesize = (intptr_t)mdbx_syspagesize(); pagesize = (intptr_t)mdbx_syspagesize();
@ -19267,6 +19270,14 @@ uint32_t mdbx_key_from_ptrfloat(const float *const ieee754_32bit) {
return float2key(ieee754_32bit); return float2key(ieee754_32bit);
} }
MDBX_NOTHROW_CONST_FUNCTION uint64_t mdbx_key_from_int64(const int64_t i64) {
return __inline_mdbx_key_from_int64(i64);
}
MDBX_NOTHROW_CONST_FUNCTION uint32_t mdbx_key_from_int32(const int32_t i32) {
return __inline_mdbx_key_from_int32(i32);
}
#define IEEE754_DOUBLE_MANTISSA_SIZE 52 #define IEEE754_DOUBLE_MANTISSA_SIZE 52
#define IEEE754_DOUBLE_EXPONENTA_BIAS 0x3FF #define IEEE754_DOUBLE_EXPONENTA_BIAS 0x3FF
#define IEEE754_DOUBLE_EXPONENTA_MAX 0x7FF #define IEEE754_DOUBLE_EXPONENTA_MAX 0x7FF

View File

@ -16,6 +16,11 @@
#include MDBX_CONFIG_H #include MDBX_CONFIG_H
#endif #endif
#define LIBMDBX_INTERNALS
#ifdef MDBX_TOOLS
#define MDBX_DEPRECATED
#endif /* MDBX_TOOLS */
/* *INDENT-OFF* */ /* *INDENT-OFF* */
/* clang-format off */ /* clang-format off */
@ -96,11 +101,6 @@
#pragma warning(disable : 4505) /* unreferenced local function has been removed */ #pragma warning(disable : 4505) /* unreferenced local function has been removed */
#endif /* _MSC_VER (warnings) */ #endif /* _MSC_VER (warnings) */
#if defined(MDBX_TOOLS)
#undef MDBX_DEPRECATED
#define MDBX_DEPRECATED
#endif /* MDBX_TOOLS */
#include "../mdbx.h" #include "../mdbx.h"
#include "defs.h" #include "defs.h"