diff --git a/mdbx.h b/mdbx.h index 7fa59a4c..b65d5bdf 100644 --- a/mdbx.h +++ b/mdbx.h @@ -1806,6 +1806,12 @@ enum MDBX_option_t { /** \brief The limit to grow a list of reclaimed pages * for finding a sequence of contiguous pages. */ MDBX_opt_rp_augment_limit, + + /** \brief The limit of dirty pages for a write transaction. */ + MDBX_opt_txn_dp_limit, + /** \brief The initial allocation size for dirty pages list + * of a write transaction. */ + MDBX_opt_txn_dp_initial, }; #ifndef __cplusplus /** \ingroup c_settings */ diff --git a/src/core.c b/src/core.c index a6f89cfa..9a597319 100644 --- a/src/core.c +++ b/src/core.c @@ -19787,6 +19787,47 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option, env->me_options.rp_augment_limit = (unsigned)value; break; + case MDBX_opt_txn_dp_limit: + case MDBX_opt_txn_dp_initial: + if (unlikely(value > MDBX_PGL_LIMIT)) + return MDBX_EINVAL; + if (unlikely(env->me_txn0 == NULL)) + return MDBX_EACCESS; + if (lock_needed) { + err = mdbx_txn_lock(env, false); + if (unlikely(err != MDBX_SUCCESS)) + return err; + should_unlock = true; + } + if (env->me_txn) + err = MDBX_EPERM /* unable change during transaction */; + else { + mdbx_dpl_clear(env->me_txn0->tw.dirtylist); + const unsigned value32 = (unsigned)value; + if (option == MDBX_opt_txn_dp_initial && + env->me_options.dp_initial != value32) { + if (env->me_options.dp_limit < value32) + env->me_options.dp_limit = value32; + if (env->me_txn0->tw.dirtylist->allocated < value32 && + !mdbx_dpl_reserve(env->me_txn0, value32)) + err = MDBX_ENOMEM; + else + env->me_options.dp_initial = value32; + } + if (option == MDBX_opt_txn_dp_limit && + env->me_options.dp_limit != value32) { + if (env->me_txn0->tw.dirtylist->allocated > value32 && + !mdbx_dpl_reserve(env->me_txn0, value32)) + err = MDBX_ENOMEM; + else { + if (env->me_options.dp_initial > value32) + env->me_options.dp_initial = value32; + env->me_options.dp_limit = value32; + } + } + } + break; + default: return MDBX_EINVAL; } @@ -19833,6 +19874,13 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option, *value = env->me_options.rp_augment_limit; break; + case MDBX_opt_txn_dp_limit: + *value = env->me_options.dp_limit; + break; + case MDBX_opt_txn_dp_initial: + *value = env->me_options.dp_initial; + break; + default: return MDBX_EINVAL; }