mdbx++: changes after codereview-1 (part 2 of 2).

Change-Id: I8e1ca134bb8c5d447895f116247dfd12fa6871f0
This commit is contained in:
Leonid Yuriev 2020-09-14 16:40:46 +03:00
parent 04b0d258ff
commit cacc4aa829
15 changed files with 631 additions and 628 deletions

277
mdbx.h
View File

@ -226,7 +226,6 @@ typedef mode_t mdbx_mode_t;
#define __has_builtin(x) (0) #define __has_builtin(x) (0)
#endif /* __has_builtin */ #endif /* __has_builtin */
#ifndef __pure_function
/** Many functions have no effects except the return value and their /** Many functions have no effects except the return value and their
* return value depends only on the parameters and/or global variables. * return value depends only on the parameters and/or global variables.
* Such a function can be subject to common subexpression elimination * Such a function can be subject to common subexpression elimination
@ -235,43 +234,39 @@ typedef mode_t mdbx_mode_t;
#if (defined(__GNUC__) || __has_attribute(__pure__)) && \ #if (defined(__GNUC__) || __has_attribute(__pure__)) && \
(!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \ (!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \
|| !defined(__cplusplus) || !__has_feature(cxx_exceptions)) || !defined(__cplusplus) || !__has_feature(cxx_exceptions))
#define __pure_function __attribute__((__pure__)) #define MDBX_PURE_FUNCTION __attribute__((__pure__))
#elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920
#define __pure_function #define MDBX_PURE_FUNCTION
#elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure) && \ #elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure) && \
(!defined(__clang__) || !__has_feature(cxx_exceptions)) (!defined(__clang__) || !__has_feature(cxx_exceptions))
#define __pure_function [[gnu::pure]] #define MDBX_PURE_FUNCTION [[gnu::pure]]
#else #else
#define __pure_function #define MDBX_PURE_FUNCTION
#endif #endif /* MDBX_PURE_FUNCTION */
#endif /* __pure_function */
#ifndef __nothrow_pure_function /** Like \ref MDBX_PURE_FUNCTION with addition `noexcept` restriction
/** Like \ref __pure_function with addition `noexcept` restriction
* that is compatible to CLANG and proposed [[pure]]. */ * that is compatible to CLANG and proposed [[pure]]. */
#if defined(__GNUC__) || \ #if defined(__GNUC__) || \
(__has_attribute(__pure__) && __has_attribute(__nothrow__)) (__has_attribute(__pure__) && __has_attribute(__nothrow__))
#define __nothrow_pure_function __attribute__((__pure__, __nothrow__)) #define MDBX_NOTHROW_PURE_FUNCTION __attribute__((__pure__, __nothrow__))
#elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920
#if __has_cpp_attribute(pure) #if __has_cpp_attribute(pure)
#define __nothrow_pure_function [[pure]] #define MDBX_NOTHROW_PURE_FUNCTION [[pure]]
#else #else
#define __nothrow_pure_function #define MDBX_NOTHROW_PURE_FUNCTION
#endif #endif
#elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure) #elif defined(__cplusplus) && __has_cpp_attribute(gnu::pure)
#if __has_cpp_attribute(gnu::nothrow) #if __has_cpp_attribute(gnu::nothrow)
#define __nothrow_pure_function [[gnu::pure, gnu::nothrow]] #define MDBX_NOTHROW_PURE_FUNCTION [[gnu::pure, gnu::nothrow]]
#else #else
#define __nothrow_pure_function [[gnu::pure]] #define MDBX_NOTHROW_PURE_FUNCTION [[gnu::pure]]
#endif #endif
#elif defined(__cplusplus) && __has_cpp_attribute(pure) #elif defined(__cplusplus) && __has_cpp_attribute(pure)
#define __nothrow_pure_function [[pure]] #define MDBX_NOTHROW_PURE_FUNCTION [[pure]]
#else #else
#define __nothrow_pure_function #define MDBX_NOTHROW_PURE_FUNCTION
#endif #endif /* MDBX_NOTHROW_PURE_FUNCTION */
#endif /* __nothrow_pure_function */
#ifndef __const_function
/** Many functions do not examine any values except their arguments, /** Many functions do not examine any values except their arguments,
* and have no effects except the return value. Basically this is just * and have no effects except the return value. Basically this is just
* slightly more strict class than the PURE attribute, since function * slightly more strict class than the PURE attribute, since function
@ -284,39 +279,36 @@ typedef mode_t mdbx_mode_t;
#if (defined(__GNUC__) || __has_attribute(__pure__)) && \ #if (defined(__GNUC__) || __has_attribute(__pure__)) && \
(!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \ (!defined(__clang__) /* https://bugs.llvm.org/show_bug.cgi?id=43275 */ \
|| !defined(__cplusplus) || !__has_feature(cxx_exceptions)) || !defined(__cplusplus) || !__has_feature(cxx_exceptions))
#define __const_function __attribute__((__const__)) #define MDBX_CONST_FUNCTION __attribute__((__const__))
#elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920
#define __const_function __pure_function #define MDBX_CONST_FUNCTION MDBX_PURE_FUNCTION
#elif defined(__cplusplus) && __has_cpp_attribute(gnu::const) && \ #elif defined(__cplusplus) && __has_cpp_attribute(gnu::const) && \
(!defined(__clang__) || !__has_feature(cxx_exceptions)) (!defined(__clang__) || !__has_feature(cxx_exceptions))
#define __const_function [[gnu::const]] #define MDBX_CONST_FUNCTION [[gnu::const]]
#else #else
#define __const_function __pure_function #define MDBX_CONST_FUNCTION MDBX_PURE_FUNCTION
#endif #endif /* MDBX_CONST_FUNCTION */
#endif /* __const_function */
#ifndef __nothrow_const_function /** Like \ref MDBX_CONST_FUNCTION with addition `noexcept` restriction
/** Like \ref __const_function with addition `noexcept` restriction
* that is compatible to CLANG and future [[const]]. */ * that is compatible to CLANG and future [[const]]. */
#if defined(__GNUC__) || \ #if defined(__GNUC__) || \
(__has_attribute(__const__) && __has_attribute(__nothrow__)) (__has_attribute(__const__) && __has_attribute(__nothrow__))
#define __nothrow_const_function __attribute__((__const__, __nothrow__)) #define MDBX_NOTHROW_CONST_FUNCTION __attribute__((__const__, __nothrow__))
#elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920 #elif defined(_MSC_VER) && !defined(__clang__) && _MSC_VER >= 1920
#define __nothrow_const_function __nothrow_pure_function #define MDBX_NOTHROW_CONST_FUNCTION MDBX_NOTHROW_PURE_FUNCTION
#elif defined(__cplusplus) && __has_cpp_attribute(gnu::const) #elif defined(__cplusplus) && __has_cpp_attribute(gnu::const)
#if __has_cpp_attribute(gnu::nothrow) #if __has_cpp_attribute(gnu::nothrow)
#define __nothrow_pure_function [[gnu::const, gnu::nothrow]] #define MDBX_NOTHROW_PURE_FUNCTION [[gnu::const, gnu::nothrow]]
#else #else
#define __nothrow_pure_function [[gnu::const]] #define MDBX_NOTHROW_PURE_FUNCTION [[gnu::const]]
#endif #endif
#elif defined(__cplusplus) && __has_cpp_attribute(const) #elif defined(__cplusplus) && __has_cpp_attribute(const)
#define __nothrow_const_function [[const]] #define MDBX_NOTHROW_CONST_FUNCTION [[const]]
#else #else
#define __nothrow_const_function __nothrow_pure_function #define MDBX_NOTHROW_CONST_FUNCTION MDBX_NOTHROW_PURE_FUNCTION
#endif #endif /* MDBX_NOTHROW_PURE_FUNCTION */
#endif /* __nothrow_pure_function */
#ifndef MDBX_DEPRECATED #ifndef MDBX_DEPRECATED /* may be predefined to avoid warnings "deprecated" */
#ifdef __deprecated #ifdef __deprecated
#define MDBX_DEPRECATED __deprecated #define MDBX_DEPRECATED __deprecated
#elif defined(__GNUC__) || __has_attribute(__deprecated__) #elif defined(__GNUC__) || __has_attribute(__deprecated__)
@ -372,97 +364,81 @@ typedef mode_t mdbx_mode_t;
#endif #endif
#endif /* bool without __cplusplus */ #endif /* bool without __cplusplus */
#if !defined(cxx11_noexcept)
#if defined(__cplusplus) && __cplusplus >= 201103L
#define cxx11_noexcept noexcept
#else
#define cxx11_noexcept
#endif
#endif /* cxx11_noexcept */
#if !defined(cxx17_noexcept)
#if !defined(__cpp_noexcept_function_type) || \ #if !defined(__cpp_noexcept_function_type) || \
__cpp_noexcept_function_type < 201510L __cpp_noexcept_function_type < 201510L
#define cxx17_noexcept #define MDBX_CXX17_NOEXCEPT
#else #else
#define cxx17_noexcept noexcept #define MDBX_CXX17_NOEXCEPT noexcept
#endif #endif /* MDBX_CXX17_NOEXCEPT */
#endif /* cxx17_noexcept */
/* Workaround for old compilers without properly support for constexpr. */ /* Workaround for old compilers without properly support for constexpr. */
#if !defined(cxx07_constexpr)
#if !defined(__cplusplus) #if !defined(__cplusplus)
#define cxx07_constexpr __inline #define MDBX_CXX01_CONSTEXPR __inline
#define cxx07_constexpr_var const #define MDBX_CXX01_CONSTEXPR_VAR const
#elif !defined(__cpp_constexpr) || __cpp_constexpr < 200704L || \ #elif !defined(__cpp_constexpr) || __cpp_constexpr < 200704L || \
(defined(__LCC__) && __LCC__ < 124) || \ (defined(__LCC__) && __LCC__ < 124) || \
(defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) && \ (defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 407) && \
!defined(__clang__) && !defined(__LCC__)) || \ !defined(__clang__) && !defined(__LCC__)) || \
(defined(_MSC_VER) && _MSC_VER < 1910) || \ (defined(_MSC_VER) && _MSC_VER < 1910) || \
(defined(__clang__) && __clang_major__ < 4) (defined(__clang__) && __clang_major__ < 4)
#define cxx07_constexpr inline #define MDBX_CXX01_CONSTEXPR inline
#define cxx07_constexpr_var const #define MDBX_CXX01_CONSTEXPR_VAR const
#else #else
#define cxx07_constexpr constexpr #define MDBX_CXX01_CONSTEXPR constexpr
#define cxx07_constexpr_var constexpr #define MDBX_CXX01_CONSTEXPR_VAR constexpr
#endif #endif /* MDBX_CXX01_CONSTEXPR */
#endif /* cxx07_constexpr */
#if !defined(cxx11_constexpr)
#if !defined(__cplusplus) #if !defined(__cplusplus)
#define cxx11_constexpr __inline #define MDBX_CXX11_CONSTEXPR __inline
#define cxx11_constexpr_var const #define MDBX_CXX11_CONSTEXPR_VAR const
#elif !defined(__cpp_constexpr) || __cpp_constexpr < 201304 || \ #elif !defined(__cpp_constexpr) || __cpp_constexpr < 201304 || \
(defined(__LCC__) && __LCC__ < 124) || \ (defined(__LCC__) && __LCC__ < 124) || \
(defined(__GNUC__) && __GNUC__ < 6 && !defined(__clang__) && \ (defined(__GNUC__) && __GNUC__ < 6 && !defined(__clang__) && \
!defined(__LCC__)) || \ !defined(__LCC__)) || \
(defined(_MSC_VER) && _MSC_VER < 1910) || \ (defined(_MSC_VER) && _MSC_VER < 1910) || \
(defined(__clang__) && __clang_major__ < 5) (defined(__clang__) && __clang_major__ < 5)
#define cxx11_constexpr inline #define MDBX_CXX11_CONSTEXPR inline
#define cxx11_constexpr_var const #define MDBX_CXX11_CONSTEXPR_VAR const
#else #else
#define cxx11_constexpr constexpr #define MDBX_CXX11_CONSTEXPR constexpr
#define cxx11_constexpr_var constexpr #define MDBX_CXX11_CONSTEXPR_VAR constexpr
#endif #endif /* MDBX_CXX11_CONSTEXPR */
#endif /* cxx11_constexpr */
#if !defined(cxx14_constexpr)
#if !defined(__cplusplus) #if !defined(__cplusplus)
#define cxx14_constexpr __inline #define MDBX_CXX14_CONSTEXPR __inline
#define cxx14_constexpr_var const #define MDBX_CXX14_CONSTEXPR_VAR const
#elif defined(__cpp_constexpr) && __cpp_constexpr >= 201304L && \ #elif defined(__cpp_constexpr) && __cpp_constexpr >= 201304L && \
((defined(_MSC_VER) && _MSC_VER >= 1910) || \ ((defined(_MSC_VER) && _MSC_VER >= 1910) || \
(defined(__clang__) && __clang_major__ > 4) || \ (defined(__clang__) && __clang_major__ > 4) || \
(defined(__GNUC__) && __GNUC__ > 6) || \ (defined(__GNUC__) && __GNUC__ > 6) || \
(!defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER))) (!defined(__GNUC__) && !defined(__clang__) && !defined(_MSC_VER)))
#define cxx14_constexpr constexpr #define MDBX_CXX14_CONSTEXPR constexpr
#define cxx14_constexpr_var constexpr #define MDBX_CXX14_CONSTEXPR_VAR constexpr
#else #else
#define cxx14_constexpr inline #define MDBX_CXX14_CONSTEXPR inline
#define cxx14_constexpr_var const #define MDBX_CXX14_CONSTEXPR_VAR const
#endif #endif /* MDBX_CXX14_CONSTEXPR */
#endif /* cxx14_constexpr */
#ifndef __noreturn #if defined(__noreturn)
#ifdef _Noreturn #define MDBX_NORETURN __noreturn
#define __noreturn _Noreturn #elif defined(_Noreturn)
#define MDBX_NORETURN _Noreturn
#elif defined(__GNUC__) || __has_attribute(__noreturn__) #elif defined(__GNUC__) || __has_attribute(__noreturn__)
#define __noreturn __attribute__((__noreturn__)) #define MDBX_NORETURN __attribute__((__noreturn__))
#elif defined(_MSC_VER) && !defined(__clang__) #elif defined(_MSC_VER) && !defined(__clang__)
#define __noreturn __declspec(noreturn) #define MDBX_NORETURN __declspec(noreturn)
#else #else
#define __noreturn #define MDBX_NORETURN
#endif #endif /* MDBX_NORETURN */
#endif /* __noreturn */
#ifndef mdbx_printf_args #ifndef MDBX_PRINTF_ARGS
#if defined(__GNUC__) || __has_attribute(__format__) #if defined(__GNUC__) || __has_attribute(__format__)
#define mdbx_printf_args(format_index, first_arg) \ #define MDBX_PRINTF_ARGS(format_index, first_arg) \
__attribute__((__format__(__printf__, format_index, first_arg))) __attribute__((__format__(__printf__, format_index, first_arg)))
#else #else
#define mdbx_printf_args(format_index, first_arg) #define MDBX_PRINTF_ARGS(format_index, first_arg)
#endif #endif
#endif /* mdbx_printf_args */ #endif /* MDBX_PRINTF_ARGS */
#ifndef DEFINE_ENUM_FLAG_OPERATORS #ifndef DEFINE_ENUM_FLAG_OPERATORS
#if defined(__cplusplus) #if defined(__cplusplus)
@ -470,19 +446,21 @@ typedef mode_t mdbx_mode_t;
/// used to define flags (based on Microsoft's DEFINE_ENUM_FLAG_OPERATORS). /// used to define flags (based on Microsoft's DEFINE_ENUM_FLAG_OPERATORS).
#define DEFINE_ENUM_FLAG_OPERATORS(ENUM) \ #define DEFINE_ENUM_FLAG_OPERATORS(ENUM) \
extern "C++" { \ extern "C++" { \
cxx07_constexpr ENUM operator|(ENUM a, ENUM b) { \ MDBX_CXX01_CONSTEXPR ENUM operator|(ENUM a, ENUM b) { \
return ENUM(std::size_t(a) | std::size_t(b)); \ return ENUM(std::size_t(a) | std::size_t(b)); \
} \ } \
cxx14_constexpr ENUM &operator|=(ENUM &a, ENUM b) { return a = a | b; } \ MDBX_CXX14_CONSTEXPR ENUM &operator|=(ENUM &a, ENUM b) { return a = a | b; } \
cxx07_constexpr ENUM operator&(ENUM a, ENUM b) { \ MDBX_CXX01_CONSTEXPR ENUM operator&(ENUM a, ENUM b) { \
return ENUM(std::size_t(a) & std::size_t(b)); \ return ENUM(std::size_t(a) & std::size_t(b)); \
} \ } \
cxx14_constexpr ENUM &operator&=(ENUM &a, ENUM b) { return a = a & b; } \ MDBX_CXX14_CONSTEXPR ENUM &operator&=(ENUM &a, ENUM b) { return a = a & b; } \
cxx07_constexpr ENUM operator~(ENUM a) { return ENUM(~std::size_t(a)); } \ MDBX_CXX01_CONSTEXPR ENUM operator~(ENUM a) { \
cxx07_constexpr ENUM operator^(ENUM a, ENUM b) { \ return ENUM(~std::size_t(a)); \
} \
MDBX_CXX01_CONSTEXPR ENUM operator^(ENUM a, ENUM b) { \
return ENUM(std::size_t(a) ^ std::size_t(b)); \ return ENUM(std::size_t(a) ^ std::size_t(b)); \
} \ } \
cxx14_constexpr ENUM &operator^=(ENUM &a, ENUM b) { return a = a ^ b; } \ MDBX_CXX14_CONSTEXPR ENUM &operator^=(ENUM &a, ENUM b) { return a = a ^ b; } \
} }
#else /* __cplusplus */ #else /* __cplusplus */
#define DEFINE_ENUM_FLAG_OPERATORS(ENUM) /* nope, C allows these operators */ #define DEFINE_ENUM_FLAG_OPERATORS(ENUM) /* nope, C allows these operators */
@ -792,7 +770,7 @@ DEFINE_ENUM_FLAG_OPERATORS(MDBX_debug_flags_t)
* \param [in] msg The assertion message, not including newline. */ * \param [in] msg The assertion message, not including newline. */
typedef void MDBX_debug_func(MDBX_log_level_t loglevel, const char *function, typedef void MDBX_debug_func(MDBX_log_level_t loglevel, const char *function,
int line, const char *msg, int line, const char *msg,
va_list args) cxx17_noexcept; va_list args) MDBX_CXX17_NOEXCEPT;
/** \brief The "don't change `logger`" value for mdbx_setup_debug() */ /** \brief The "don't change `logger`" value for mdbx_setup_debug() */
#define MDBX_LOGGER_DONTCHANGE ((MDBX_debug_func *)(intptr_t)-1) #define MDBX_LOGGER_DONTCHANGE ((MDBX_debug_func *)(intptr_t)-1)
@ -812,7 +790,7 @@ LIBMDBX_API int mdbx_setup_debug(MDBX_log_level_t log_level,
* \param [in] msg The assertion message, not including newline. */ * \param [in] msg The assertion message, not including newline. */
typedef void MDBX_assert_func(const MDBX_env *env, const char *msg, typedef void MDBX_assert_func(const MDBX_env *env, const char *msg,
const char *function, const char *function,
unsigned line) cxx17_noexcept; unsigned line) MDBX_CXX17_NOEXCEPT;
/** \brief Set or reset the assert() callback of the environment. /** \brief Set or reset the assert() callback of the environment.
* *
@ -838,7 +816,7 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf,
const size_t bufsize); const size_t bufsize);
/** \brief Panics with message and causes abnormal process termination. */ /** \brief Panics with message and causes abnormal process termination. */
LIBMDBX_API void mdbx_panic(const char *fmt, ...) mdbx_printf_args(1, 2); LIBMDBX_API void mdbx_panic(const char *fmt, ...) MDBX_PRINTF_ARGS(1, 2);
/** @} end of logging & debug */ /** @} end of logging & debug */
@ -1715,7 +1693,7 @@ LIBMDBX_API const char *mdbx_strerror(int errnum);
* *
* \returns "error message" The description of the error. */ * \returns "error message" The description of the error. */
LIBMDBX_API const char *mdbx_strerror_r(int errnum, char *buf, size_t buflen); LIBMDBX_API const char *mdbx_strerror_r(int errnum, char *buf, size_t buflen);
__nothrow_pure_function LIBMDBX_API const char *mdbx_liberr2str(int errnum); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API const char *mdbx_liberr2str(int errnum);
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
/** Bit of Windows' madness. The similar to \ref mdbx_strerror() but returns /** Bit of Windows' madness. The similar to \ref mdbx_strerror() but returns
@ -2430,46 +2408,46 @@ 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 */
__nothrow_const_function __inline intptr_t mdbx_limits_pgsize_min(void) { MDBX_NOTHROW_CONST_FUNCTION __inline 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 */
__nothrow_const_function __inline intptr_t mdbx_limits_pgsize_max(void) { MDBX_NOTHROW_CONST_FUNCTION __inline intptr_t mdbx_limits_pgsize_max(void) {
return MDBX_MAX_PAGESIZE; return MDBX_MAX_PAGESIZE;
} }
/** \brief Returns minimal database size in bytes for given page size, /** \brief Returns minimal database size in bytes for given page size,
* or -1 if pagesize is invalid. * or -1 if pagesize is invalid.
* \ingroup c_statinfo */ * \ingroup c_statinfo */
__nothrow_const_function LIBMDBX_API intptr_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t
mdbx_limits_dbsize_min(intptr_t pagesize); mdbx_limits_dbsize_min(intptr_t pagesize);
/** \brief Returns maximal database size in bytes for given page size, /** \brief Returns maximal database size in bytes for given page size,
* or -1 if pagesize is invalid. * or -1 if pagesize is invalid.
* \ingroup c_statinfo */ * \ingroup c_statinfo */
__nothrow_const_function LIBMDBX_API intptr_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t
mdbx_limits_dbsize_max(intptr_t pagesize); mdbx_limits_dbsize_max(intptr_t pagesize);
/** \brief Returns maximal key size in bytes for given page size /** \brief Returns maximal key size in bytes for given page size
* and database flags, or -1 if pagesize is invalid. * and database flags, or -1 if pagesize is invalid.
* \ingroup c_statinfo * \ingroup c_statinfo
* \see db_flags */ * \see db_flags */
__nothrow_const_function LIBMDBX_API intptr_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t
mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags); mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags);
/** \brief Returns maximal data size in bytes for given page size /** \brief Returns maximal data size in bytes for given page size
* and database flags, or -1 if pagesize is invalid. * and database flags, or -1 if pagesize is invalid.
* \ingroup c_statinfo * \ingroup c_statinfo
* \see db_flags */ * \see db_flags */
__nothrow_const_function LIBMDBX_API intptr_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t
mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags); mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags);
/** \brief Returns maximal write transaction size (i.e. limit for summary volume /** \brief Returns maximal write transaction size (i.e. limit for summary volume
* of dirty pages) in bytes for given page size, or -1 if pagesize is invalid. * of dirty pages) in bytes for given page size, or -1 if pagesize is invalid.
* \ingroup c_statinfo */ * \ingroup c_statinfo */
__nothrow_const_function LIBMDBX_API intptr_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t
mdbx_limits_txnsize_max(intptr_t pagesize); mdbx_limits_txnsize_max(intptr_t pagesize);
/** \brief Set the maximum number of threads/reader slots for the environment. /** \brief Set the maximum number of threads/reader slots for the environment.
@ -2552,7 +2530,7 @@ LIBMDBX_API int mdbx_env_get_maxdbs(MDBX_env *env, MDBX_dbi *dbs);
* *
* \returns The maximum size of a key can write, * \returns The maximum size of a key can write,
* or -1 if something is wrong. */ * or -1 if something is wrong. */
__nothrow_pure_function LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int
mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags); mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags);
/** \brief Get the maximum size of data we can write. /** \brief Get the maximum size of data we can write.
@ -2564,13 +2542,13 @@ mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags);
* *
* \returns The maximum size of a data can write, * \returns The maximum size of a data can write,
* or -1 if something is wrong. */ * or -1 if something is wrong. */
__nothrow_pure_function LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int
mdbx_env_get_maxvalsize_ex(const MDBX_env *env, MDBX_db_flags_t flags); mdbx_env_get_maxvalsize_ex(const MDBX_env *env, MDBX_db_flags_t flags);
/** \deprecated Please use \ref mdbx_env_get_maxkeysize_ex() /** \deprecated Please use \ref mdbx_env_get_maxkeysize_ex()
* and/or \ref mdbx_env_get_maxvalsize_ex() * and/or \ref mdbx_env_get_maxvalsize_ex()
* \ingroup c_statinfo */ * \ingroup c_statinfo */
__nothrow_pure_function MDBX_DEPRECATED LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION MDBX_DEPRECATED LIBMDBX_API int
mdbx_env_get_maxkeysize(const MDBX_env *env); mdbx_env_get_maxkeysize(const MDBX_env *env);
/** \brief Set application information associated with the \ref MDBX_env. /** \brief Set application information associated with the \ref MDBX_env.
@ -2589,7 +2567,7 @@ LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx);
* *
* \param [in] env An environment handle returned by \ref mdbx_env_create() * \param [in] env An environment handle returned by \ref mdbx_env_create()
* \returns The pointer set by \ref mdbx_env_set_userctx(). */ * \returns The pointer set by \ref mdbx_env_set_userctx(). */
__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. /** \brief Create a transaction for use with the environment.
@ -2716,7 +2694,8 @@ LIBMDBX_API int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info,
* \ingroup c_transactions * \ingroup c_transactions
* *
* \param [in] txn A transaction handle returned by \ref mdbx_txn_begin() */ * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin() */
__nothrow_pure_function LIBMDBX_API MDBX_env *mdbx_txn_env(const MDBX_txn *txn); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_env *
mdbx_txn_env(const MDBX_txn *txn);
/** \brief Return the transaction's flags. /** \brief Return the transaction's flags.
* \ingroup c_transactions * \ingroup c_transactions
@ -2727,7 +2706,7 @@ __nothrow_pure_function LIBMDBX_API MDBX_env *mdbx_txn_env(const MDBX_txn *txn);
* *
* \returns A transaction flags, valid if input is an valid transaction, * \returns A transaction flags, valid if input is an valid transaction,
* otherwise -1. */ * otherwise -1. */
__nothrow_pure_function LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn);
/** \brief Return the transaction's ID. /** \brief Return the transaction's ID.
* \ingroup c_statinfo * \ingroup c_statinfo
@ -2740,7 +2719,8 @@ __nothrow_pure_function LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn);
* *
* \returns A transaction ID, valid if input is an active transaction, * \returns A transaction ID, valid if input is an active transaction,
* otherwise 0. */ * otherwise 0. */
__nothrow_pure_function LIBMDBX_API uint64_t mdbx_txn_id(const MDBX_txn *txn); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t
mdbx_txn_id(const MDBX_txn *txn);
/** \brief Commit all the operations of a transaction into the database. /** \brief Commit all the operations of a transaction into the database.
* \ingroup c_transactions * \ingroup c_transactions
@ -2936,7 +2916,8 @@ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary);
* \ingroup c_crud * \ingroup c_crud
* \see mdbx_cmp() \see mdbx_get_keycmp() * \see mdbx_cmp() \see mdbx_get_keycmp()
* \see mdbx_get_datacmp \see mdbx_dcmp() */ * \see mdbx_get_datacmp \see mdbx_dcmp() */
typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b) cxx17_noexcept; typedef int(MDBX_cmp_func)(const MDBX_val *a,
const MDBX_val *b) MDBX_CXX17_NOEXCEPT;
/** \brief Open or Create a database in the environment. /** \brief Open or Create a database in the environment.
* \ingroup c_dbi * \ingroup c_dbi
@ -3063,27 +3044,27 @@ mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags,
* and IEEE754 double values in one index for JSON-numbers with restriction for * and IEEE754 double values in one index for JSON-numbers with restriction for
* integer numbers range corresponding to RFC-7159, i.e. \f$[-2^{53}+1, * integer numbers range corresponding to RFC-7159, i.e. \f$[-2^{53}+1,
* 2^{53}-1]\f$. See bottom of page 6 at https://tools.ietf.org/html/rfc7159 */ * 2^{53}-1]\f$. See bottom of page 6 at https://tools.ietf.org/html/rfc7159 */
__nothrow_const_function LIBMDBX_API uint64_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t
mdbx_key_from_jsonInteger(const int64_t json_integer); mdbx_key_from_jsonInteger(const int64_t json_integer);
__nothrow_const_function LIBMDBX_API uint64_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint64_t
mdbx_key_from_double(const double ieee754_64bit); mdbx_key_from_double(const double ieee754_64bit);
__nothrow_pure_function LIBMDBX_API uint64_t MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API uint64_t
mdbx_key_from_ptrdouble(const double *const ieee754_64bit); mdbx_key_from_ptrdouble(const double *const ieee754_64bit);
__nothrow_const_function LIBMDBX_API uint32_t MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API uint32_t
mdbx_key_from_float(const float ieee754_32bit); mdbx_key_from_float(const float ieee754_32bit);
__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);
__nothrow_const_function __inline uint64_t MDBX_NOTHROW_CONST_FUNCTION __inline uint64_t
mdbx_key_from_int64(const int64_t i64) { mdbx_key_from_int64(const int64_t i64) {
return UINT64_C(0x8000000000000000) + i64; return UINT64_C(0x8000000000000000) + i64;
} }
__nothrow_const_function __inline uint32_t MDBX_NOTHROW_CONST_FUNCTION __inline uint32_t
mdbx_key_from_int32(const int32_t i32) { mdbx_key_from_int32(const int32_t i32) {
return UINT32_C(0x80000000) + i32; return UINT32_C(0x80000000) + i32;
} }
@ -3092,16 +3073,20 @@ mdbx_key_from_int32(const int32_t i32) {
/** \defgroup key2value Key-to-Value functions to avoid custom comparators /** \defgroup key2value Key-to-Value functions to avoid custom comparators
* \see value2key * \see value2key
* @{ */ * @{ */
__nothrow_pure_function LIBMDBX_API int64_t MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t
mdbx_jsonInteger_from_key(const MDBX_val); mdbx_jsonInteger_from_key(const MDBX_val);
__nothrow_pure_function LIBMDBX_API double mdbx_double_from_key(const MDBX_val); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API double
mdbx_double_from_key(const MDBX_val);
__nothrow_pure_function LIBMDBX_API float mdbx_float_from_key(const MDBX_val); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API float
mdbx_float_from_key(const MDBX_val);
__nothrow_pure_function LIBMDBX_API int32_t mdbx_int32_from_key(const MDBX_val); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int32_t
mdbx_int32_from_key(const MDBX_val);
__nothrow_pure_function LIBMDBX_API int64_t mdbx_int64_from_key(const MDBX_val); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t
mdbx_int64_from_key(const MDBX_val);
/** @} */ /** @} */
/** \brief Retrieve statistics for a database. /** \brief Retrieve statistics for a database.
@ -3539,7 +3524,7 @@ LIBMDBX_API int mdbx_cursor_renew(MDBX_txn *txn, MDBX_cursor *cursor);
* \ingroup c_cursors * \ingroup c_cursors
* *
* \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */ * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */
__nothrow_pure_function LIBMDBX_API MDBX_txn * MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_txn *
mdbx_cursor_txn(const MDBX_cursor *cursor); mdbx_cursor_txn(const MDBX_cursor *cursor);
/** \brief Return the cursor's database handle. /** \brief Return the cursor's database handle.
@ -3712,7 +3697,7 @@ LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *pcount);
* positioned * positioned
* \retval MDBX_RESULT_FALSE A data is available * \retval MDBX_RESULT_FALSE A data is available
* \retval Otherwise the error code */ * \retval Otherwise the error code */
__nothrow_pure_function LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int
mdbx_cursor_eof(const MDBX_cursor *cursor); mdbx_cursor_eof(const MDBX_cursor *cursor);
/** \brief Determines whether the cursor is pointed to the first key-value pair /** \brief Determines whether the cursor is pointed to the first key-value pair
@ -3725,7 +3710,7 @@ mdbx_cursor_eof(const MDBX_cursor *cursor);
* \retval MDBX_RESULT_TRUE Cursor positioned to the first key-value pair * \retval MDBX_RESULT_TRUE Cursor positioned to the first key-value pair
* \retval MDBX_RESULT_FALSE Cursor NOT positioned to the first key-value * \retval MDBX_RESULT_FALSE Cursor NOT positioned to the first key-value
* pair \retval Otherwise the error code */ * pair \retval Otherwise the error code */
__nothrow_pure_function LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int
mdbx_cursor_on_first(const MDBX_cursor *cursor); mdbx_cursor_on_first(const MDBX_cursor *cursor);
/** \brief Determines whether the cursor is pointed to the last key-value pair /** \brief Determines whether the cursor is pointed to the last key-value pair
@ -3738,7 +3723,7 @@ mdbx_cursor_on_first(const MDBX_cursor *cursor);
* \retval MDBX_RESULT_TRUE Cursor positioned to the last key-value pair * \retval MDBX_RESULT_TRUE Cursor positioned to the last key-value pair
* \retval MDBX_RESULT_FALSE Cursor NOT positioned to the last key-value pair * \retval MDBX_RESULT_FALSE Cursor NOT positioned to the last key-value pair
* \retval Otherwise the error code */ * \retval Otherwise the error code */
__nothrow_pure_function LIBMDBX_API int MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int
mdbx_cursor_on_last(const MDBX_cursor *cursor); mdbx_cursor_on_last(const MDBX_cursor *cursor);
/** \addtogroup c_rqest /** \addtogroup c_rqest
@ -3878,8 +3863,8 @@ LIBMDBX_API int mdbx_estimate_range(MDBX_txn *txn, MDBX_dbi dbi,
* \retval MDBX_RESULT_TRUE Given address is on the dirty page. * \retval MDBX_RESULT_TRUE Given address is on the dirty page.
* \retval MDBX_RESULT_FALSE Given address is NOT on the dirty page. * \retval MDBX_RESULT_FALSE Given address is NOT on the dirty page.
* \retval Otherwise the error code. */ * \retval Otherwise the error code. */
__nothrow_pure_function LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn,
const void *ptr); const void *ptr);
/** \brief Sequence generation for a database. /** \brief Sequence generation for a database.
* \ingroup c_crud * \ingroup c_crud
@ -3919,14 +3904,14 @@ LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
* \param [in] b The second item to compare. * \param [in] b The second item to compare.
* *
* \returns < 0 if a < b, 0 if a == b, > 0 if a > b */ * \returns < 0 if a < b, 0 if a == b, > 0 if a > b */
__nothrow_pure_function LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn,
MDBX_dbi dbi, MDBX_dbi dbi,
const MDBX_val *a, const MDBX_val *a,
const MDBX_val *b); const MDBX_val *b);
/** \brief Returns default internal key's comparator for given database flags. /** \brief Returns default internal key's comparator for given database flags.
* \ingroup c_extra */ * \ingroup c_extra */
__nothrow_const_function LIBMDBX_API MDBX_cmp_func * MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func *
mdbx_get_keycmp(MDBX_db_flags_t flags); mdbx_get_keycmp(MDBX_db_flags_t flags);
/** \brief Compare two data items according to a particular database. /** \brief Compare two data items according to a particular database.
@ -3943,14 +3928,14 @@ mdbx_get_keycmp(MDBX_db_flags_t flags);
* \param [in] b The second item to compare. * \param [in] b The second item to compare.
* *
* \returns < 0 if a < b, 0 if a == b, > 0 if a > b */ * \returns < 0 if a < b, 0 if a == b, > 0 if a > b */
__nothrow_pure_function LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn,
MDBX_dbi dbi, MDBX_dbi dbi,
const MDBX_val *a, const MDBX_val *a,
const MDBX_val *b); const MDBX_val *b);
/** \brief Returns default internal data's comparator for given database flags /** \brief Returns default internal data's comparator for given database flags
* \ingroup c_extra */ * \ingroup c_extra */
__nothrow_const_function LIBMDBX_API MDBX_cmp_func * MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func *
mdbx_get_datacmp(MDBX_db_flags_t flags); mdbx_get_datacmp(MDBX_db_flags_t flags);
/** \brief A callback function used to enumerate the reader lock table. /** \brief A callback function used to enumerate the reader lock table.
@ -3981,7 +3966,7 @@ mdbx_get_datacmp(MDBX_db_flags_t flags);
typedef int(MDBX_reader_list_func)(void *ctx, int num, int slot, mdbx_pid_t pid, typedef int(MDBX_reader_list_func)(void *ctx, int num, int slot, mdbx_pid_t pid,
mdbx_tid_t thread, uint64_t txnid, mdbx_tid_t thread, uint64_t txnid,
uint64_t lag, size_t bytes_used, uint64_t lag, size_t bytes_used,
size_t bytes_retained) cxx17_noexcept; size_t bytes_retained) MDBX_CXX17_NOEXCEPT;
/** \brief Enumarete the entries in the reader lock table. /** \brief Enumarete the entries in the reader lock table.
* \ingroup c_statinfo * \ingroup c_statinfo
@ -4116,7 +4101,7 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env);
*/ */
typedef int(MDBX_oom_func)(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, typedef int(MDBX_oom_func)(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid,
uint64_t txn, unsigned gap, size_t space, uint64_t txn, unsigned gap, size_t space,
int retry) cxx17_noexcept; int retry) MDBX_CXX17_NOEXCEPT;
/** \brief Set the OOM callback. /** \brief Set the OOM callback.
* \ingroup c_err * \ingroup c_err
@ -4140,7 +4125,7 @@ LIBMDBX_API int mdbx_env_set_oomfunc(MDBX_env *env, MDBX_oom_func *oom_func);
* \param [in] env An environment handle returned by \ref mdbx_env_create(). * \param [in] env An environment handle returned by \ref mdbx_env_create().
* *
* \returns A MDBX_oom_func function or NULL if disabled. */ * \returns A MDBX_oom_func function or NULL if disabled. */
__nothrow_pure_function LIBMDBX_API MDBX_oom_func * MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_oom_func *
mdbx_env_get_oomfunc(const MDBX_env *env); mdbx_env_get_oomfunc(const MDBX_env *env);
/** \defgroup btree_traversal B-tree Traversal /** \defgroup btree_traversal B-tree Traversal
@ -4178,7 +4163,7 @@ typedef int MDBX_pgvisitor_func(
const uint64_t pgno, const unsigned number, void *const ctx, const int deep, const uint64_t pgno, const unsigned number, void *const ctx, const int deep,
const char *const dbi, const size_t page_size, const MDBX_page_type_t type, const char *const dbi, const size_t page_size, const MDBX_page_type_t type,
const MDBX_error_t err, const size_t nentries, const size_t payload_bytes, const MDBX_error_t err, const size_t nentries, const size_t payload_bytes,
const size_t header_bytes, const size_t unused_bytes) cxx17_noexcept; const size_t header_bytes, const size_t unused_bytes) MDBX_CXX17_NOEXCEPT;
/** \brief B-tree traversal function. */ /** \brief B-tree traversal function. */
LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,

704
mdbx.h++

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Internal inlines */ * Internal inlines */
__nothrow_const_function static unsigned log2n(size_t value) { MDBX_NOTHROW_CONST_FUNCTION static unsigned log2n(size_t value) {
assert(value > 0 && value < INT32_MAX && is_powerof2(value)); assert(value > 0 && value < INT32_MAX && is_powerof2(value));
assert((value & -(int32_t)value) == value); assert((value & -(int32_t)value) == value);
#if __GNUC_PREREQ(4, 1) || __has_builtin(__builtin_ctzl) #if __GNUC_PREREQ(4, 1) || __has_builtin(__builtin_ctzl)
@ -60,14 +60,14 @@ __nothrow_const_function static unsigned log2n(size_t value) {
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* Unaligned access */ * Unaligned access */
__nothrow_const_function static __maybe_unused __always_inline unsigned MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __always_inline unsigned
field_alignment(unsigned alignment_baseline, size_t field_offset) { field_alignment(unsigned alignment_baseline, size_t field_offset) {
unsigned merge = alignment_baseline | (unsigned)field_offset; unsigned merge = alignment_baseline | (unsigned)field_offset;
return merge & -(int)merge; return merge & -(int)merge;
} }
/* read-thunk for UB-sanitizer */ /* read-thunk for UB-sanitizer */
__nothrow_pure_function static __always_inline uint8_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint8_t
peek_u8(const uint8_t *const __restrict ptr) { peek_u8(const uint8_t *const __restrict ptr) {
return *ptr; return *ptr;
} }
@ -78,7 +78,7 @@ static __always_inline void poke_u8(uint8_t *const __restrict ptr,
*ptr = v; *ptr = v;
} }
__nothrow_pure_function static __always_inline uint16_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint16_t
unaligned_peek_u16(const unsigned expected_alignment, const void *const ptr) { unaligned_peek_u16(const unsigned expected_alignment, const void *const ptr) {
assert((uintptr_t)ptr % expected_alignment == 0); assert((uintptr_t)ptr % expected_alignment == 0);
if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint16_t)) == 0) if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint16_t)) == 0)
@ -100,7 +100,7 @@ unaligned_poke_u16(const unsigned expected_alignment,
memcpy(ptr, &v, sizeof(v)); memcpy(ptr, &v, sizeof(v));
} }
__nothrow_pure_function static __always_inline uint32_t unaligned_peek_u32( MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint32_t unaligned_peek_u32(
const unsigned expected_alignment, const void *const __restrict ptr) { const unsigned expected_alignment, const void *const __restrict ptr) {
assert((uintptr_t)ptr % expected_alignment == 0); assert((uintptr_t)ptr % expected_alignment == 0);
if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint32_t)) == 0) if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint32_t)) == 0)
@ -132,7 +132,7 @@ unaligned_poke_u32(const unsigned expected_alignment,
memcpy(ptr, &v, sizeof(v)); memcpy(ptr, &v, sizeof(v));
} }
__nothrow_pure_function static __always_inline uint64_t unaligned_peek_u64( MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint64_t unaligned_peek_u64(
const unsigned expected_alignment, const void *const __restrict ptr) { const unsigned expected_alignment, const void *const __restrict ptr) {
assert((uintptr_t)ptr % expected_alignment == 0); assert((uintptr_t)ptr % expected_alignment == 0);
if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint64_t)) == 0) if (MDBX_UNALIGNED_OK || (expected_alignment % sizeof(uint64_t)) == 0)
@ -185,7 +185,7 @@ unaligned_poke_u64(const unsigned expected_alignment,
unaligned_poke_u64(1, (char *)(ptr) + offsetof(struct, field), value) unaligned_poke_u64(1, (char *)(ptr) + offsetof(struct, field), value)
/* Get the page number pointed to by a branch node */ /* Get the page number pointed to by a branch node */
__nothrow_pure_function static __always_inline pgno_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t
node_pgno(const MDBX_node *const __restrict node) { node_pgno(const MDBX_node *const __restrict node) {
pgno_t pgno = UNALIGNED_PEEK_32(node, MDBX_node, mn_pgno32); pgno_t pgno = UNALIGNED_PEEK_32(node, MDBX_node, mn_pgno32);
if (sizeof(pgno) > 4) if (sizeof(pgno) > 4)
@ -205,7 +205,7 @@ static __always_inline void node_set_pgno(MDBX_node *const __restrict node,
} }
/* Get the size of the data in a leaf node */ /* Get the size of the data in a leaf node */
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
node_ds(const MDBX_node *const __restrict node) { node_ds(const MDBX_node *const __restrict node) {
return UNALIGNED_PEEK_32(node, MDBX_node, mn_dsize); return UNALIGNED_PEEK_32(node, MDBX_node, mn_dsize);
} }
@ -218,7 +218,7 @@ static __always_inline void node_set_ds(MDBX_node *const __restrict node,
} }
/* The size of a key in a node */ /* The size of a key in a node */
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
node_ks(const MDBX_node *const __restrict node) { node_ks(const MDBX_node *const __restrict node) {
return UNALIGNED_PEEK_16(node, MDBX_node, mn_ksize); return UNALIGNED_PEEK_16(node, MDBX_node, mn_ksize);
} }
@ -230,7 +230,7 @@ static __always_inline void node_set_ks(MDBX_node *const __restrict node,
UNALIGNED_POKE_16(node, MDBX_node, mn_ksize, (uint16_t)size); UNALIGNED_POKE_16(node, MDBX_node, mn_ksize, (uint16_t)size);
} }
__nothrow_pure_function static __always_inline uint8_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline uint8_t
node_flags(const MDBX_node *const __restrict node) { node_flags(const MDBX_node *const __restrict node) {
return UNALIGNED_PEEK_8(node, MDBX_node, mn_flags); return UNALIGNED_PEEK_8(node, MDBX_node, mn_flags);
} }
@ -244,29 +244,29 @@ static __always_inline void node_set_flags(MDBX_node *const __restrict node,
#define NODESIZE offsetof(MDBX_node, mn_data) #define NODESIZE offsetof(MDBX_node, mn_data)
/* Address of the key for the node */ /* Address of the key for the node */
__nothrow_pure_function static __always_inline void * MDBX_NOTHROW_PURE_FUNCTION static __always_inline void *
node_key(const MDBX_node *const __restrict node) { node_key(const MDBX_node *const __restrict node) {
return (char *)node + NODESIZE; return (char *)node + NODESIZE;
} }
/* Address of the data for a node */ /* Address of the data for a node */
__nothrow_pure_function static __always_inline void * MDBX_NOTHROW_PURE_FUNCTION static __always_inline void *
node_data(const MDBX_node *const __restrict node) { node_data(const MDBX_node *const __restrict node) {
return (char *)node_key(node) + node_ks(node); return (char *)node_key(node) + node_ks(node);
} }
/* Size of a node in a leaf page with a given key and data. /* Size of a node in a leaf page with a given key and data.
* This is node header plus key plus data size. */ * This is node header plus key plus data size. */
__nothrow_const_function static __always_inline size_t MDBX_NOTHROW_CONST_FUNCTION static __always_inline size_t
node_size_len(const size_t key_len, const size_t value_len) { node_size_len(const size_t key_len, const size_t value_len) {
return NODESIZE + EVEN(key_len + value_len); return NODESIZE + EVEN(key_len + value_len);
} }
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
node_size(const MDBX_val *key, const MDBX_val *value) { node_size(const MDBX_val *key, const MDBX_val *value) {
return node_size_len(key ? key->iov_len : 0, value ? value->iov_len : 0); return node_size_len(key ? key->iov_len : 0, value ? value->iov_len : 0);
} }
__nothrow_pure_function static __always_inline pgno_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t
peek_pgno(const void *const __restrict ptr) { peek_pgno(const void *const __restrict ptr) {
if (sizeof(pgno_t) == sizeof(uint32_t)) if (sizeof(pgno_t) == sizeof(uint32_t))
return (pgno_t)unaligned_peek_u32(1, ptr); return (pgno_t)unaligned_peek_u32(1, ptr);
@ -289,7 +289,7 @@ static __always_inline void poke_pgno(void *const __restrict ptr,
memcpy(ptr, &pgno, sizeof(pgno)); memcpy(ptr, &pgno, sizeof(pgno));
} }
__nothrow_pure_function static __always_inline pgno_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t
node_largedata_pgno(const MDBX_node *const __restrict node) { node_largedata_pgno(const MDBX_node *const __restrict node) {
assert(node_flags(node) & F_BIGDATA); assert(node_flags(node) & F_BIGDATA);
return peek_pgno(node_data(node)); return peek_pgno(node_data(node));
@ -411,7 +411,7 @@ __cold intptr_t mdbx_limits_valsize_max(intptr_t pagesize,
* size will only include the key and not the data. Sizes are always * size will only include the key and not the data. Sizes are always
* rounded up to an even number of bytes, to guarantee 2-byte alignment * rounded up to an even number of bytes, to guarantee 2-byte alignment
* of the MDBX_node headers. */ * of the MDBX_node headers. */
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) { leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) {
size_t node_bytes = node_size(key, data); size_t node_bytes = node_size(key, data);
/* NOTE: The actual limit is LEAF_NODEMAX(env->me_psize), but it reasonable to /* NOTE: The actual limit is LEAF_NODEMAX(env->me_psize), but it reasonable to
@ -454,7 +454,7 @@ leaf_size(const MDBX_env *env, const MDBX_val *key, const MDBX_val *data) {
* [in] key The key for the node. * [in] key The key for the node.
* *
* Returns The number of bytes needed to store the node. */ * Returns The number of bytes needed to store the node. */
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
branch_size(const MDBX_env *env, const MDBX_val *key) { branch_size(const MDBX_env *env, const MDBX_val *key) {
/* Size of a node in a branch page with a given key. /* Size of a node in a branch page with a given key.
* This is just the node header plus the key, there is no data. */ * This is just the node header plus the key, there is no data. */
@ -470,7 +470,7 @@ branch_size(const MDBX_env *env, const MDBX_val *key) {
return node_bytes + sizeof(indx_t); return node_bytes + sizeof(indx_t);
} }
__nothrow_const_function static __always_inline uint16_t MDBX_NOTHROW_CONST_FUNCTION static __always_inline uint16_t
flags_db2sub(uint16_t db_flags) { flags_db2sub(uint16_t db_flags) {
uint16_t sub_flags = db_flags & MDBX_DUPFIXED; uint16_t sub_flags = db_flags & MDBX_DUPFIXED;
@ -491,84 +491,84 @@ flags_db2sub(uint16_t db_flags) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
__nothrow_pure_function static __always_inline size_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline size_t
pgno2bytes(const MDBX_env *env, pgno_t pgno) { pgno2bytes(const MDBX_env *env, pgno_t pgno) {
mdbx_assert(env, (1u << env->me_psize2log) == env->me_psize); mdbx_assert(env, (1u << env->me_psize2log) == env->me_psize);
return ((size_t)pgno) << env->me_psize2log; return ((size_t)pgno) << env->me_psize2log;
} }
__nothrow_pure_function static __always_inline MDBX_page * MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_page *
pgno2page(const MDBX_env *env, pgno_t pgno) { pgno2page(const MDBX_env *env, pgno_t pgno) {
return (MDBX_page *)(env->me_map + pgno2bytes(env, pgno)); return (MDBX_page *)(env->me_map + pgno2bytes(env, pgno));
} }
__nothrow_pure_function static __always_inline pgno_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t
bytes2pgno(const MDBX_env *env, size_t bytes) { bytes2pgno(const MDBX_env *env, size_t bytes) {
mdbx_assert(env, (env->me_psize >> env->me_psize2log) == 1); mdbx_assert(env, (env->me_psize >> env->me_psize2log) == 1);
return (pgno_t)(bytes >> env->me_psize2log); return (pgno_t)(bytes >> env->me_psize2log);
} }
__nothrow_pure_function static size_t pgno_align2os_bytes(const MDBX_env *env, MDBX_NOTHROW_PURE_FUNCTION static size_t
pgno_t pgno) { pgno_align2os_bytes(const MDBX_env *env, pgno_t pgno) {
return ceil_powerof2(pgno2bytes(env, pgno), env->me_os_psize); return ceil_powerof2(pgno2bytes(env, pgno), env->me_os_psize);
} }
__nothrow_pure_function static pgno_t pgno_align2os_pgno(const MDBX_env *env, MDBX_NOTHROW_PURE_FUNCTION static pgno_t pgno_align2os_pgno(const MDBX_env *env,
pgno_t pgno) { pgno_t pgno) {
return bytes2pgno(env, pgno_align2os_bytes(env, pgno)); return bytes2pgno(env, pgno_align2os_bytes(env, pgno));
} }
__nothrow_pure_function static size_t bytes_align2os_bytes(const MDBX_env *env, MDBX_NOTHROW_PURE_FUNCTION static size_t
size_t bytes) { bytes_align2os_bytes(const MDBX_env *env, size_t bytes) {
return ceil_powerof2(ceil_powerof2(bytes, env->me_psize), env->me_os_psize); return ceil_powerof2(ceil_powerof2(bytes, env->me_psize), env->me_os_psize);
} }
/* Address of first usable data byte in a page, after the header */ /* Address of first usable data byte in a page, after the header */
__nothrow_pure_function static __always_inline void * MDBX_NOTHROW_PURE_FUNCTION static __always_inline void *
page_data(const MDBX_page *mp) { page_data(const MDBX_page *mp) {
return (char *)mp + PAGEHDRSZ; return (char *)mp + PAGEHDRSZ;
} }
__nothrow_pure_function static __always_inline const MDBX_page * MDBX_NOTHROW_PURE_FUNCTION static __always_inline const MDBX_page *
data_page(const void *data) { data_page(const void *data) {
return container_of(data, MDBX_page, mp_ptrs); return container_of(data, MDBX_page, mp_ptrs);
} }
__nothrow_pure_function static __always_inline MDBX_meta * MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_meta *
page_meta(MDBX_page *mp) { page_meta(MDBX_page *mp) {
return (MDBX_meta *)page_data(mp); return (MDBX_meta *)page_data(mp);
} }
/* Number of nodes on a page */ /* Number of nodes on a page */
__nothrow_pure_function static __always_inline unsigned MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned
page_numkeys(const MDBX_page *mp) { page_numkeys(const MDBX_page *mp) {
return mp->mp_lower >> 1; return mp->mp_lower >> 1;
} }
/* The amount of space remaining in the page */ /* The amount of space remaining in the page */
__nothrow_pure_function static __always_inline unsigned MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned
page_room(const MDBX_page *mp) { page_room(const MDBX_page *mp) {
return mp->mp_upper - mp->mp_lower; return mp->mp_upper - mp->mp_lower;
} }
__nothrow_pure_function static __always_inline unsigned MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned
page_space(const MDBX_env *env) { page_space(const MDBX_env *env) {
STATIC_ASSERT(PAGEHDRSZ % 2 == 0); STATIC_ASSERT(PAGEHDRSZ % 2 == 0);
return env->me_psize - PAGEHDRSZ; return env->me_psize - PAGEHDRSZ;
} }
__nothrow_pure_function static __always_inline unsigned MDBX_NOTHROW_PURE_FUNCTION static __always_inline unsigned
page_used(const MDBX_env *env, const MDBX_page *mp) { page_used(const MDBX_env *env, const MDBX_page *mp) {
return page_space(env) - page_room(mp); return page_space(env) - page_room(mp);
} }
/* The percentage of space used in the page, in a percents. */ /* The percentage of space used in the page, in a percents. */
__nothrow_pure_function static __maybe_unused __inline double MDBX_NOTHROW_PURE_FUNCTION static __maybe_unused __inline double
page_fill(const MDBX_env *env, const MDBX_page *mp) { page_fill(const MDBX_env *env, const MDBX_page *mp) {
return page_used(env, mp) * 100.0 / page_space(env); return page_used(env, mp) * 100.0 / page_space(env);
} }
__nothrow_pure_function static __inline bool MDBX_NOTHROW_PURE_FUNCTION static __inline bool
page_fill_enough(const MDBX_page *mp, unsigned spaceleft_threshold, page_fill_enough(const MDBX_page *mp, unsigned spaceleft_threshold,
unsigned minkeys_threshold) { unsigned minkeys_threshold) {
return page_room(mp) < spaceleft_threshold && return page_room(mp) < spaceleft_threshold &&
@ -576,12 +576,12 @@ page_fill_enough(const MDBX_page *mp, unsigned spaceleft_threshold,
} }
/* The number of overflow pages needed to store the given size. */ /* The number of overflow pages needed to store the given size. */
__nothrow_pure_function static __always_inline pgno_t MDBX_NOTHROW_PURE_FUNCTION static __always_inline pgno_t
number_of_ovpages(const MDBX_env *env, size_t bytes) { number_of_ovpages(const MDBX_env *env, size_t bytes) {
return bytes2pgno(env, PAGEHDRSZ - 1 + bytes) + 1; return bytes2pgno(env, PAGEHDRSZ - 1 + bytes) + 1;
} }
__cold static int mdbx_printf_args(2, 3) __cold static int MDBX_PRINTF_ARGS(2, 3)
bad_page(const MDBX_page *mp, const char *fmt, ...) { bad_page(const MDBX_page *mp, const char *fmt, ...) {
if (mdbx_log_enabled(MDBX_LOG_ERROR)) { if (mdbx_log_enabled(MDBX_LOG_ERROR)) {
static const MDBX_page *prev; static const MDBX_page *prev;
@ -601,7 +601,7 @@ __cold static int mdbx_printf_args(2, 3)
} }
/* Address of node i in page p */ /* Address of node i in page p */
__nothrow_pure_function static __always_inline MDBX_node * MDBX_NOTHROW_PURE_FUNCTION static __always_inline MDBX_node *
page_node(const MDBX_page *mp, unsigned i) { page_node(const MDBX_page *mp, unsigned i) {
assert((mp->mp_flags & (P_LEAF2 | P_OVERFLOW | P_META)) == 0); assert((mp->mp_flags & (P_LEAF2 | P_OVERFLOW | P_META)) == 0);
assert(page_numkeys(mp) > (unsigned)(i)); assert(page_numkeys(mp) > (unsigned)(i));
@ -612,7 +612,7 @@ page_node(const MDBX_page *mp, unsigned i) {
/* The address of a key in a LEAF2 page. /* The address of a key in a LEAF2 page.
* LEAF2 pages are used for MDBX_DUPFIXED sorted-duplicate sub-DBs. * LEAF2 pages are used for MDBX_DUPFIXED sorted-duplicate sub-DBs.
* There are no node headers, keys are stored contiguously. */ * There are no node headers, keys are stored contiguously. */
__nothrow_pure_function static __always_inline void * MDBX_NOTHROW_PURE_FUNCTION static __always_inline void *
page_leaf2key(const MDBX_page *mp, unsigned i, size_t keysize) { page_leaf2key(const MDBX_page *mp, unsigned i, size_t keysize) {
assert((mp->mp_flags & (P_BRANCH | P_LEAF | P_LEAF2 | P_OVERFLOW | P_META)) == assert((mp->mp_flags & (P_BRANCH | P_LEAF | P_LEAF2 | P_OVERFLOW | P_META)) ==
(P_LEAF | P_LEAF2)); (P_LEAF | P_LEAF2));
@ -1383,7 +1383,7 @@ static __inline void lcklist_unlock(void) {
#endif #endif
} }
__nothrow_const_function static uint64_t rrxmrrxmsx_0(uint64_t v) { MDBX_NOTHROW_CONST_FUNCTION static uint64_t rrxmrrxmsx_0(uint64_t v) {
/* Pelle Evensen's mixer, https://bit.ly/2HOfynt */ /* Pelle Evensen's mixer, https://bit.ly/2HOfynt */
v ^= (v << 39 | v >> 25) ^ (v << 14 | v >> 50); v ^= (v << 39 | v >> 25) ^ (v << 14 | v >> 50);
v *= UINT64_C(0xA24BAED4963EE407); v *= UINT64_C(0xA24BAED4963EE407);

View File

@ -151,18 +151,6 @@
# endif # endif
#endif /* __prefetch */ #endif /* __prefetch */
#ifndef __noreturn
# ifdef _Noreturn
# define __noreturn _Noreturn
# elif defined(__GNUC__) || __has_attribute(__noreturn__)
# define __noreturn __attribute__((__noreturn__))
# elif defined(_MSC_VER)
# define __noreturn __declspec(noreturn)
# else
# define __noreturn
# endif
#endif /* __noreturn */
#ifndef __nothrow #ifndef __nothrow
# if defined(__cplusplus) # if defined(__cplusplus)
# if __cplusplus < 201703L # if __cplusplus < 201703L
@ -268,7 +256,7 @@
#endif /* __anonymous_struct_extension__ */ #endif /* __anonymous_struct_extension__ */
#ifndef __Wpedantic_format_voidptr #ifndef __Wpedantic_format_voidptr
static __inline __maybe_unused const void* __pure_function static __inline __maybe_unused const void* MDBX_PURE_FUNCTION
__Wpedantic_format_voidptr(const void* ptr) {return ptr;} __Wpedantic_format_voidptr(const void* ptr) {return ptr;}
# define __Wpedantic_format_voidptr(ARG) __Wpedantic_format_voidptr(ARG) # define __Wpedantic_format_voidptr(ARG) __Wpedantic_format_voidptr(ARG)
#endif /* __Wpedantic_format_voidptr */ #endif /* __Wpedantic_format_voidptr */

View File

@ -1038,9 +1038,9 @@ extern uint8_t mdbx_runtime_flags;
extern uint8_t mdbx_loglevel; extern uint8_t mdbx_loglevel;
extern MDBX_debug_func *mdbx_debug_logger; extern MDBX_debug_func *mdbx_debug_logger;
MDBX_INTERNAL_FUNC void mdbx_printf_args(4, 5) MDBX_INTERNAL_FUNC void MDBX_PRINTF_ARGS(4, 5)
mdbx_debug_log(int level, const char *function, int line, const char *fmt, mdbx_debug_log(int level, const char *function, int line, const char *fmt,
...) mdbx_printf_args(4, 5); ...) MDBX_PRINTF_ARGS(4, 5);
MDBX_INTERNAL_FUNC void mdbx_debug_log_va(int level, const char *function, MDBX_INTERNAL_FUNC void mdbx_debug_log_va(int level, const char *function,
int line, const char *fmt, int line, const char *fmt,
va_list args); va_list args);
@ -1360,30 +1360,30 @@ typedef struct MDBX_node {
/* Do not spill pages to disk if txn is getting full, may fail instead */ /* Do not spill pages to disk if txn is getting full, may fail instead */
#define MDBX_NOSPILL 0x8000 #define MDBX_NOSPILL 0x8000
__nothrow_const_function static __maybe_unused __inline pgno_t MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline pgno_t
pgno_add(pgno_t base, pgno_t augend) { pgno_add(pgno_t base, pgno_t augend) {
assert(base <= MAX_PAGENO); assert(base <= MAX_PAGENO);
return (augend < MAX_PAGENO - base) ? base + augend : MAX_PAGENO; return (augend < MAX_PAGENO - base) ? base + augend : MAX_PAGENO;
} }
__nothrow_const_function static __maybe_unused __inline pgno_t MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline pgno_t
pgno_sub(pgno_t base, pgno_t subtrahend) { pgno_sub(pgno_t base, pgno_t subtrahend) {
assert(base >= MIN_PAGENO); assert(base >= MIN_PAGENO);
return (subtrahend < base - MIN_PAGENO) ? base - subtrahend : MIN_PAGENO; return (subtrahend < base - MIN_PAGENO) ? base - subtrahend : MIN_PAGENO;
} }
__nothrow_const_function static __always_inline __maybe_unused bool MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused bool
is_powerof2(size_t x) { is_powerof2(size_t x) {
return (x & (x - 1)) == 0; return (x & (x - 1)) == 0;
} }
__nothrow_const_function static __always_inline __maybe_unused size_t MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused size_t
floor_powerof2(size_t value, size_t granularity) { floor_powerof2(size_t value, size_t granularity) {
assert(is_powerof2(granularity)); assert(is_powerof2(granularity));
return value & ~(granularity - 1); return value & ~(granularity - 1);
} }
__nothrow_const_function static __always_inline __maybe_unused size_t MDBX_NOTHROW_CONST_FUNCTION static __always_inline __maybe_unused size_t
ceil_powerof2(size_t value, size_t granularity) { ceil_powerof2(size_t value, size_t granularity) {
return floor_powerof2(value + granularity - 1, granularity); return floor_powerof2(value + granularity - 1, granularity);
} }

View File

@ -28,14 +28,6 @@
#include <cctype> // for isxdigit(), etc #include <cctype> // for isxdigit(), etc
#include <system_error> #include <system_error>
#if defined(__has_include) && __has_include(<version>)
#include <version>
#endif
#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L
#include <filesystem>
#endif /* __cpp_lib_filesystem >= 201703L */
namespace { namespace {
#if 0 /* Unused for now */ #if 0 /* Unused for now */
@ -72,7 +64,7 @@ class trouble_location {
#endif #endif
public: public:
cxx11_constexpr trouble_location(unsigned line, const char *condition, MDBX_CXX11_CONSTEXPR trouble_location(unsigned line, const char *condition,
const char *function, const char *filename) const char *function, const char *filename)
: :
#if TROUBLE_PROVIDE_LINENO #if TROUBLE_PROVIDE_LINENO
@ -198,14 +190,14 @@ __cold bug::~bug() noexcept {}
#define RAISE_BUG(line, condition, function, file) \ #define RAISE_BUG(line, condition, function, file) \
do { \ do { \
static cxx11_constexpr_var trouble_location bug(line, condition, function, \ static MDBX_CXX11_CONSTEXPR_VAR trouble_location bug(line, condition, \
file); \ function, file); \
raise_bug(bug); \ raise_bug(bug); \
} while (0) } while (0)
#define ENSURE(condition) \ #define ENSURE(condition) \
do \ do \
if (mdbx_unlikely(!(condition))) \ if (MDBX_UNLIKELY(!(condition))) \
RAISE_BUG(__LINE__, #condition, __func__, __FILE__); \ RAISE_BUG(__LINE__, #condition, __func__, __FILE__); \
while (0) while (0)
@ -488,9 +480,9 @@ bool slice::is_printable(bool disable_utf8) const noexcept {
auto src = byte_ptr(); auto src = byte_ptr();
const auto end = src + length(); const auto end = src + length();
if (mdbx_unlikely(disable_utf8)) { if (MDBX_UNLIKELY(disable_utf8)) {
do do
if (mdbx_unlikely((P_ & map[*src]) == 0)) if (MDBX_UNLIKELY((P_ & map[*src]) == 0))
return false; return false;
while (++src < end); while (++src < end);
return true; return true;
@ -543,7 +535,7 @@ bool slice::is_printable(bool disable_utf8) const noexcept {
char *slice::to_hex(char *__restrict dest, size_t dest_size, bool uppercase, char *slice::to_hex(char *__restrict dest, size_t dest_size, bool uppercase,
unsigned wrap_width) const { unsigned wrap_width) const {
if (mdbx_unlikely(to_hex_bytes(wrap_width) > dest_size)) if (MDBX_UNLIKELY(to_hex_bytes(wrap_width) > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
@ -565,22 +557,22 @@ char *slice::to_hex(char *__restrict dest, size_t dest_size, bool uppercase,
byte *slice::from_hex(byte *__restrict dest, size_t dest_size, byte *slice::from_hex(byte *__restrict dest, size_t dest_size,
bool ignore_spaces) const { bool ignore_spaces) const {
if (mdbx_unlikely(length() % 2 && !ignore_spaces)) if (MDBX_UNLIKELY(length() % 2 && !ignore_spaces))
throw std::domain_error( throw std::domain_error(
"mdbx::from_hex:: odd length of hexadecimal string"); "mdbx::from_hex:: odd length of hexadecimal string");
if (mdbx_unlikely(from_hex_bytes() > dest_size)) if (MDBX_UNLIKELY(from_hex_bytes() > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(*src <= ' ') && if (MDBX_UNLIKELY(*src <= ' ') &&
mdbx_likely(ignore_spaces && isspace(*src))) { MDBX_LIKELY(ignore_spaces && isspace(*src))) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_unlikely(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) if (MDBX_UNLIKELY(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1])))
throw std::domain_error("mdbx::from_hex:: invalid hexadecimal string"); throw std::domain_error("mdbx::from_hex:: invalid hexadecimal string");
int8_t hi = src[0]; int8_t hi = src[0];
@ -599,20 +591,20 @@ byte *slice::from_hex(byte *__restrict dest, size_t dest_size,
} }
bool slice::is_hex(bool ignore_spaces) const noexcept { bool slice::is_hex(bool ignore_spaces) const noexcept {
if (mdbx_unlikely(length() % 2 && !ignore_spaces)) if (MDBX_UNLIKELY(length() % 2 && !ignore_spaces))
return false; return false;
bool got = false; bool got = false;
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(*src <= ' ') && if (MDBX_UNLIKELY(*src <= ' ') &&
mdbx_likely(ignore_spaces && isspace(*src))) { MDBX_LIKELY(ignore_spaces && isspace(*src))) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_unlikely(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1]))) if (MDBX_UNLIKELY(left < 1 || !isxdigit(src[0]) || !isxdigit(src[1])))
return false; return false;
got = true; got = true;
@ -669,13 +661,13 @@ static inline char b58_8to11(uint64_t &v) noexcept {
char *slice::to_base58(char *__restrict dest, size_t dest_size, char *slice::to_base58(char *__restrict dest, size_t dest_size,
unsigned wrap_width) const { unsigned wrap_width) const {
if (mdbx_unlikely(to_base58_bytes(wrap_width) > dest_size)) if (MDBX_UNLIKELY(to_base58_bytes(wrap_width) > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
size_t left = length(); size_t left = length();
auto line = dest; auto line = dest;
while (mdbx_likely(left > 7)) { while (MDBX_LIKELY(left > 7)) {
left -= 8; left -= 8;
uint64_t v; uint64_t v;
std::memcpy(&v, src, 8); std::memcpy(&v, src, 8);
@ -752,20 +744,20 @@ static inline signed char b58_11to8(uint64_t &v, const byte c) noexcept {
byte *slice::from_base58(byte *__restrict dest, size_t dest_size, byte *slice::from_base58(byte *__restrict dest, size_t dest_size,
bool ignore_spaces) const { bool ignore_spaces) const {
if (mdbx_unlikely(from_base58_bytes() > dest_size)) if (MDBX_UNLIKELY(from_base58_bytes() > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(isspace(*src)) && ignore_spaces) { if (MDBX_UNLIKELY(isspace(*src)) && ignore_spaces) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_likely(left > 10)) { if (MDBX_LIKELY(left > 10)) {
uint64_t v = 0; uint64_t v = 0;
if (mdbx_unlikely((b58_11to8(v, src[0]) | b58_11to8(v, src[1]) | if (MDBX_UNLIKELY((b58_11to8(v, src[0]) | b58_11to8(v, src[1]) |
b58_11to8(v, src[2]) | b58_11to8(v, src[3]) | b58_11to8(v, src[2]) | b58_11to8(v, src[3]) |
b58_11to8(v, src[4]) | b58_11to8(v, src[5]) | b58_11to8(v, src[4]) | b58_11to8(v, src[5]) |
b58_11to8(v, src[6]) | b58_11to8(v, src[7]) | b58_11to8(v, src[6]) | b58_11to8(v, src[7]) |
@ -792,7 +784,7 @@ byte *slice::from_base58(byte *__restrict dest, size_t dest_size,
uint64_t v = 1; uint64_t v = 1;
unsigned parrots = 0; unsigned parrots = 0;
do { do {
if (mdbx_unlikely(b58_11to8(v, *src++) < 0)) if (MDBX_UNLIKELY(b58_11to8(v, *src++) < 0))
goto bailout; goto bailout;
parrots += 32; parrots += 32;
} while (--left); } while (--left);
@ -814,15 +806,15 @@ bool slice::is_base58(bool ignore_spaces) const noexcept {
bool got = false; bool got = false;
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(*src <= ' ') && if (MDBX_UNLIKELY(*src <= ' ') &&
mdbx_likely(ignore_spaces && isspace(*src))) { MDBX_LIKELY(ignore_spaces && isspace(*src))) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_likely(left > 10)) { if (MDBX_LIKELY(left > 10)) {
if (mdbx_unlikely((b58_map[src[0]] | b58_map[src[1]] | b58_map[src[2]] | if (MDBX_UNLIKELY((b58_map[src[0]] | b58_map[src[1]] | b58_map[src[2]] |
b58_map[src[3]] | b58_map[src[4]] | b58_map[src[5]] | b58_map[src[3]] | b58_map[src[4]] | b58_map[src[5]] |
b58_map[src[6]] | b58_map[src[7]] | b58_map[src[8]] | b58_map[src[6]] | b58_map[src[7]] | b58_map[src[8]] |
b58_map[src[9]] | b58_map[src[10]]) < 0)) b58_map[src[9]] | b58_map[src[10]]) < 0))
@ -838,7 +830,7 @@ bool slice::is_base58(bool ignore_spaces) const noexcept {
return false; return false;
do do
if (mdbx_unlikely(b58_map[*src++] < 0)) if (MDBX_UNLIKELY(b58_map[*src++] < 0))
return false; return false;
while (--left); while (--left);
got = true; got = true;
@ -865,7 +857,7 @@ static inline void b64_3to4(const byte x, const byte y, const byte z,
char *slice::to_base64(char *__restrict dest, size_t dest_size, char *slice::to_base64(char *__restrict dest, size_t dest_size,
unsigned wrap_width) const { unsigned wrap_width) const {
if (mdbx_unlikely(to_base64_bytes(wrap_width) > dest_size)) if (MDBX_UNLIKELY(to_base64_bytes(wrap_width) > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
@ -874,7 +866,7 @@ char *slice::to_base64(char *__restrict dest, size_t dest_size,
while (true) { while (true) {
switch (left) { switch (left) {
default: default:
cxx20_attribute_likely left -= 3; MDBX_CXX20_LIKELY left -= 3;
b64_3to4(src[0], src[1], src[2], dest); b64_3to4(src[0], src[1], src[2], dest);
dest += 4; dest += 4;
src += 3; src += 3;
@ -928,27 +920,27 @@ static inline signed char b64_4to3(signed char a, signed char b, signed char c,
byte *slice::from_base64(byte *__restrict dest, size_t dest_size, byte *slice::from_base64(byte *__restrict dest, size_t dest_size,
bool ignore_spaces) const { bool ignore_spaces) const {
if (mdbx_unlikely(length() % 4 && !ignore_spaces)) if (MDBX_UNLIKELY(length() % 4 && !ignore_spaces))
throw std::domain_error("mdbx::from_base64:: odd length of base64 string"); throw std::domain_error("mdbx::from_base64:: odd length of base64 string");
if (mdbx_unlikely(from_base64_bytes() > dest_size)) if (MDBX_UNLIKELY(from_base64_bytes() > dest_size))
throw_too_small_target_buffer(); throw_too_small_target_buffer();
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(*src <= ' ') && if (MDBX_UNLIKELY(*src <= ' ') &&
mdbx_likely(ignore_spaces && isspace(*src))) { MDBX_LIKELY(ignore_spaces && isspace(*src))) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_unlikely(left < 3)) { if (MDBX_UNLIKELY(left < 3)) {
bailout: bailout:
throw std::domain_error("mdbx::from_base64:: invalid base64 string"); throw std::domain_error("mdbx::from_base64:: invalid base64 string");
} }
const signed char a = b64_map[src[0]], b = b64_map[src[1]], const signed char a = b64_map[src[0]], b = b64_map[src[1]],
c = b64_map[src[2]], d = b64_map[src[3]]; c = b64_map[src[2]], d = b64_map[src[3]];
if (mdbx_unlikely(b64_4to3(a, b, c, d, dest) < 0)) { if (MDBX_UNLIKELY(b64_4to3(a, b, c, d, dest) < 0)) {
if (left == 4 && (a | b) >= 0 && d == EQ) { if (left == 4 && (a | b) >= 0 && d == EQ) {
if (c >= 0) if (c >= 0)
return dest + 2; return dest + 2;
@ -964,24 +956,24 @@ byte *slice::from_base64(byte *__restrict dest, size_t dest_size,
} }
bool slice::is_base64(bool ignore_spaces) const noexcept { bool slice::is_base64(bool ignore_spaces) const noexcept {
if (mdbx_unlikely(length() % 4 && !ignore_spaces)) if (MDBX_UNLIKELY(length() % 4 && !ignore_spaces))
return false; return false;
bool got = false; bool got = false;
auto src = byte_ptr(); auto src = byte_ptr();
for (auto left = length(); left > 0;) { for (auto left = length(); left > 0;) {
if (mdbx_unlikely(*src <= ' ') && if (MDBX_UNLIKELY(*src <= ' ') &&
mdbx_likely(ignore_spaces && isspace(*src))) { MDBX_LIKELY(ignore_spaces && isspace(*src))) {
++src; ++src;
--left; --left;
continue; continue;
} }
if (mdbx_unlikely(left < 3)) if (MDBX_UNLIKELY(left < 3))
return false; return false;
const signed char a = b64_map[src[0]], b = b64_map[src[1]], const signed char a = b64_map[src[0]], b = b64_map[src[1]],
c = b64_map[src[2]], d = b64_map[src[3]]; c = b64_map[src[2]], d = b64_map[src[3]];
if (mdbx_unlikely((a | b | c | d) < 0)) { if (MDBX_UNLIKELY((a | b | c | d) < 0)) {
if (left == 4 && (a | b) >= 0 && d == EQ && (c >= 0 || c == d)) if (left == 4 && (a | b) >= 0 && d == EQ && (c >= 0 || c == d))
return true; return true;
return false; return false;
@ -1008,7 +1000,7 @@ size_t env::default_pagesize() noexcept { return ::mdbx_syspagesize(); }
static inline MDBX_env_flags_t mode2flags(env::mode mode) { static inline MDBX_env_flags_t mode2flags(env::mode mode) {
switch (mode) { switch (mode) {
default: default:
cxx20_attribute_unlikely throw std::invalid_argument("db::mode is invalid"); MDBX_CXX20_UNLIKELY throw std::invalid_argument("db::mode is invalid");
case env::mode::readonly: case env::mode::readonly:
return MDBX_RDONLY; return MDBX_RDONLY;
case env::mode::write_file_io: case env::mode::write_file_io:
@ -1043,7 +1035,7 @@ env::operate_parameters::make_flags(bool accede, bool use_subdirectory) const {
flags |= MDBX_LIFORECLAIM; flags |= MDBX_LIFORECLAIM;
switch (durability) { switch (durability) {
default: default:
cxx20_attribute_unlikely throw std::invalid_argument( MDBX_CXX20_UNLIKELY throw std::invalid_argument(
"db::durability is invalid"); "db::durability is invalid");
case env::durability::robust_synchronous: case env::durability::robust_synchronous:
break; break;
@ -1221,7 +1213,7 @@ txn_managed::~txn_managed() noexcept {
void txn_managed::abort() { void txn_managed::abort() {
const error err = static_cast<MDBX_error_t>(::mdbx_txn_abort(handle_)); const error err = static_cast<MDBX_error_t>(::mdbx_txn_abort(handle_));
if (mdbx_unlikely(err.code() != MDBX_SUCCESS)) { if (MDBX_UNLIKELY(err.code() != MDBX_SUCCESS)) {
if (err.code() != MDBX_THREAD_MISMATCH) if (err.code() != MDBX_THREAD_MISMATCH)
handle_ = nullptr; handle_ = nullptr;
err.throw_exception(); err.throw_exception();
@ -1230,7 +1222,7 @@ void txn_managed::abort() {
void txn_managed::commit() { void txn_managed::commit() {
const error err = static_cast<MDBX_error_t>(::mdbx_txn_commit(handle_)); const error err = static_cast<MDBX_error_t>(::mdbx_txn_commit(handle_));
if (mdbx_unlikely(err.code() != MDBX_SUCCESS)) { if (MDBX_UNLIKELY(err.code() != MDBX_SUCCESS)) {
if (err.code() != MDBX_THREAD_MISMATCH) if (err.code() != MDBX_THREAD_MISMATCH)
handle_ = nullptr; handle_ = nullptr;
err.throw_exception(); err.throw_exception();
@ -1250,9 +1242,9 @@ bool txn::drop_map(const char *name, bool throw_if_absent) {
case MDBX_BAD_DBI: case MDBX_BAD_DBI:
if (!throw_if_absent) if (!throw_if_absent)
return false; return false;
cxx17_attribute_fallthrough /* fallthrough */; MDBX_CXX17_FALLTHROUGH /* fallthrough */;
default: default:
cxx20_attribute_unlikely error::throw_exception(err); MDBX_CXX20_UNLIKELY error::throw_exception(err);
} }
} }
@ -1267,17 +1259,17 @@ bool txn::clear_map(const char *name, bool throw_if_absent) {
case MDBX_BAD_DBI: case MDBX_BAD_DBI:
if (!throw_if_absent) if (!throw_if_absent)
return false; return false;
cxx17_attribute_fallthrough /* fallthrough */; MDBX_CXX17_FALLTHROUGH /* fallthrough */;
default: default:
cxx20_attribute_unlikely error::throw_exception(err); MDBX_CXX20_UNLIKELY error::throw_exception(err);
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void cursor_managed::close() { void cursor_managed::close() {
if (mdbx_unlikely(!handle_)) if (MDBX_UNLIKELY(!handle_))
cxx20_attribute_unlikely error::throw_exception(MDBX_EINVAL); MDBX_CXX20_UNLIKELY error::throw_exception(MDBX_EINVAL);
::mdbx_cursor_close(handle_); ::mdbx_cursor_close(handle_);
handle_ = nullptr; handle_ = nullptr;
} }

View File

@ -106,7 +106,7 @@ struct problem {
struct problem *problems_list; struct problem *problems_list;
uint64_t total_problems; uint64_t total_problems;
static void mdbx_printf_args(1, 2) print(const char *msg, ...) { static void MDBX_PRINTF_ARGS(1, 2) print(const char *msg, ...) {
if (!quiet) { if (!quiet) {
va_list args; va_list args;
@ -145,7 +145,7 @@ static void va_log(MDBX_log_level_t level, const char *msg, va_list args) {
} }
} }
static void mdbx_printf_args(1, 2) error(const char *msg, ...) { static void MDBX_PRINTF_ARGS(1, 2) error(const char *msg, ...) {
va_list args; va_list args;
va_start(args, msg); va_start(args, msg);
va_log(MDBX_LOG_ERROR, msg, args); va_log(MDBX_LOG_ERROR, msg, args);
@ -216,7 +216,7 @@ static walk_dbi_t *pagemap_lookup_dbi(const char *dbi_name, bool silent) {
return last = dbi; return last = dbi;
} }
static void mdbx_printf_args(4, 5) static void MDBX_PRINTF_ARGS(4, 5)
problem_add(const char *object, uint64_t entry_number, const char *msg, problem_add(const char *object, uint64_t entry_number, const char *msg,
const char *extra, ...) { const char *extra, ...) {

View File

@ -145,7 +145,7 @@ __extern_C void __assert_fail(const char *assertion, const char *file,
#else #else
__nothrow __nothrow
#endif /* __THROW */ #endif /* __THROW */
__noreturn; MDBX_NORETURN;
#elif defined(__APPLE__) || defined(__MACH__) #elif defined(__APPLE__) || defined(__MACH__)
__extern_C void __assert_rtn(const char *function, const char *file, int line, __extern_C void __assert_rtn(const char *function, const char *file, int line,
@ -153,7 +153,7 @@ __extern_C void __assert_rtn(const char *function, const char *file, int line,
#ifdef __dead2 #ifdef __dead2
__dead2 __dead2
#else #else
__noreturn MDBX_NORETURN
#endif /* __dead2 */ #endif /* __dead2 */
#ifdef __disable_tail_calls #ifdef __disable_tail_calls
__disable_tail_calls __disable_tail_calls
@ -164,7 +164,7 @@ __extern_C void __assert_rtn(const char *function, const char *file, int line,
__assert_rtn(function, file, line, assertion) __assert_rtn(function, file, line, assertion)
#elif defined(__sun) || defined(__SVR4) || defined(__svr4__) #elif defined(__sun) || defined(__SVR4) || defined(__svr4__)
__extern_C void __assert_c99(const char *assection, const char *file, int line, __extern_C void __assert_c99(const char *assection, const char *file, int line,
const char *function) __noreturn; const char *function) MDBX_NORETURN;
#define __assert_fail(assertion, file, line, function) \ #define __assert_fail(assertion, file, line, function) \
__assert_c99(assertion, file, line, function) __assert_c99(assertion, file, line, function)
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
@ -186,7 +186,7 @@ __extern_C void __assert(const char *function, const char *file, int line,
#ifdef __dead2 #ifdef __dead2
__dead2 __dead2
#else #else
__noreturn MDBX_NORETURN
#endif /* __dead2 */ #endif /* __dead2 */
#ifdef __disable_tail_calls #ifdef __disable_tail_calls
__disable_tail_calls __disable_tail_calls

View File

@ -412,7 +412,7 @@ typedef pthread_mutex_t mdbx_fastmutex_t;
/* Get the size of a memory page for the system. /* Get the size of a memory page for the system.
* This is the basic size that the platform's memory manager uses, and is * This is the basic size that the platform's memory manager uses, and is
* fundamental to the use of memory-mapped files. */ * fundamental to the use of memory-mapped files. */
__nothrow_const_function static __maybe_unused __inline size_t MDBX_NOTHROW_CONST_FUNCTION static __maybe_unused __inline size_t
mdbx_syspagesize(void) { mdbx_syspagesize(void) {
#if defined(_WIN32) || defined(_WIN64) #if defined(_WIN32) || defined(_WIN64)
SYSTEM_INFO si; SYSTEM_INFO si;
@ -536,7 +536,7 @@ static __maybe_unused __inline void mdbx_memory_barrier(void) {
#define mdbx_asprintf asprintf #define mdbx_asprintf asprintf
#define mdbx_vasprintf vasprintf #define mdbx_vasprintf vasprintf
#else #else
MDBX_INTERNAL_FUNC mdbx_printf_args(2, 3) int __maybe_unused MDBX_INTERNAL_FUNC MDBX_PRINTF_ARGS(2, 3) int __maybe_unused
mdbx_asprintf(char **strp, const char *fmt, ...); mdbx_asprintf(char **strp, const char *fmt, ...);
MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap); MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap);
#endif #endif

View File

@ -16,7 +16,7 @@
namespace keygen { namespace keygen {
static inline __pure_function serial_t mask(unsigned bits) { static inline MDBX_PURE_FUNCTION serial_t mask(unsigned bits) {
assert(bits > 0 && bits <= serial_maxwith); assert(bits > 0 && bits <= serial_maxwith);
return serial_allones >> (serial_maxwith - bits); return serial_allones >> (serial_maxwith - bits);
} }

View File

@ -31,7 +31,7 @@ const char *test_strerror(int errnum) {
return mdbx_strerror_r(errnum, buf, sizeof(buf)); return mdbx_strerror_r(errnum, buf, sizeof(buf));
} }
__noreturn void failure_perror(const char *what, int errnum) { MDBX_NORETURN void failure_perror(const char *what, int errnum) {
failure("%s failed: %s (%d)\n", what, test_strerror(errnum), errnum); failure("%s failed: %s (%d)\n", what, test_strerror(errnum), errnum);
} }
@ -39,7 +39,7 @@ __noreturn void failure_perror(const char *what, int errnum) {
static void mdbx_logger(MDBX_log_level_t priority, const char *function, static void mdbx_logger(MDBX_log_level_t priority, const char *function,
int line, const char *msg, int line, const char *msg,
va_list args) cxx17_noexcept { va_list args) MDBX_CXX17_NOEXCEPT {
if (!function) if (!function)
function = "unknown"; function = "unknown";

View File

@ -17,9 +17,9 @@
#include "base.h" #include "base.h"
#include "chrono.h" #include "chrono.h"
__noreturn void usage(void); MDBX_NORETURN void usage(void);
__noreturn void mdbx_printf_args(1, 2) failure(const char *fmt, ...); MDBX_NORETURN void MDBX_PRINTF_ARGS(1, 2) failure(const char *fmt, ...);
__noreturn void failure_perror(const char *what, int errnum); MDBX_NORETURN void failure_perror(const char *what, int errnum);
const char *test_strerror(int errnum); const char *test_strerror(int errnum);
namespace logging { namespace logging {
@ -51,12 +51,12 @@ void setlevel(loglevel priority);
void output_nocheckloglevel_ap(const loglevel priority, const char *format, void output_nocheckloglevel_ap(const loglevel priority, const char *format,
va_list ap); va_list ap);
bool mdbx_printf_args(2, 3) bool MDBX_PRINTF_ARGS(2, 3)
output(const loglevel priority, const char *format, ...); output(const loglevel priority, const char *format, ...);
bool feed_ap(const char *format, va_list ap); bool feed_ap(const char *format, va_list ap);
bool mdbx_printf_args(1, 2) feed(const char *format, ...); bool MDBX_PRINTF_ARGS(1, 2) feed(const char *format, ...);
void inline mdbx_printf_args(2, 3) void inline MDBX_PRINTF_ARGS(2, 3)
output_nocheckloglevel(const loglevel priority, const char *format, ...) { output_nocheckloglevel(const loglevel priority, const char *format, ...) {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
@ -85,13 +85,13 @@ public:
} // namespace logging } // namespace logging
void mdbx_printf_args(1, 2) log_extra(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_extra(const char *msg, ...);
void mdbx_printf_args(1, 2) log_trace(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_trace(const char *msg, ...);
void mdbx_printf_args(1, 2) log_debug(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_debug(const char *msg, ...);
void mdbx_printf_args(1, 2) log_verbose(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_verbose(const char *msg, ...);
void mdbx_printf_args(1, 2) log_notice(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_notice(const char *msg, ...);
void mdbx_printf_args(1, 2) log_warning(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_warning(const char *msg, ...);
void mdbx_printf_args(1, 2) log_error(const char *msg, ...); void MDBX_PRINTF_ARGS(1, 2) log_error(const char *msg, ...);
void log_trouble(const char *where, const char *what, int errnum); void log_trouble(const char *where, const char *what, int errnum);
void log_flush(void); void log_flush(void);

View File

@ -19,7 +19,7 @@
#include <sys/time.h> #include <sys/time.h>
#endif /* !Windows */ #endif /* !Windows */
__noreturn void usage(void) { MDBX_NORETURN void usage(void) {
puts( puts(
"usage:\n" "usage:\n"
" --help or -h Show this text\n" " --help or -h Show this text\n"

View File

@ -80,7 +80,7 @@ const char *keygencase2str(const keygen_case keycase) {
int testcase::oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, int testcase::oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid,
uint64_t txn, unsigned gap, size_t space, uint64_t txn, unsigned gap, size_t space,
int retry) cxx17_noexcept { int retry) MDBX_CXX17_NOEXCEPT {
testcase *self = (testcase *)mdbx_env_get_userctx(env); testcase *self = (testcase *)mdbx_env_get_userctx(env);

View File

@ -168,7 +168,7 @@ protected:
static int oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid, static int oom_callback(MDBX_env *env, mdbx_pid_t pid, mdbx_tid_t tid,
uint64_t txn, unsigned gap, size_t space, uint64_t txn, unsigned gap, size_t space,
int retry) cxx17_noexcept; int retry) MDBX_CXX17_NOEXCEPT;
MDBX_env_flags_t actual_env_mode{MDBX_ENV_DEFAULTS}; MDBX_env_flags_t actual_env_mode{MDBX_ENV_DEFAULTS};
bool is_nested_txn_available() const { bool is_nested_txn_available() const {