From 4ae2a107bf129982d501cf0483bf534039532230 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 22 Jan 2021 23:52:03 +0300 Subject: [PATCH] mdbx: add `MDBX_opt_loose_limit` runtime option. More for https://github.com/erthink/libmdbx/issues/128 Change-Id: I298bf1eef24575df72615ee07e93f5073405e8e0 --- mdbx.h | 25 +++++++++++++++++++------ src/core.c | 22 +++++++++++++++++++--- src/internals.h | 1 + 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/mdbx.h b/mdbx.h index f9ba3418..91b520e3 100644 --- a/mdbx.h +++ b/mdbx.h @@ -1852,18 +1852,31 @@ enum MDBX_option_t { * process. Default is 262144, it is usually enough for most cases. */ MDBX_opt_rp_augment_limit, - /** \brief Controls the in-process limit to grow a list of - * pre-allocated/reserved dirty pages. + /** \brief Controls the in-process limit to grow a cache of dirty + * pages for reuse in the current transaction. + * + * \details A 'dirty page' refers to a page that has been updated in memory + * only, the changes to a dirty page are not yet stored on disk. + * To reduce overhead, it is reasonable to release not all such pages + * immediately, but to leave some ones in cache for reuse in the current + * transaction. + * + * The `MDBX_opt_loose_limit` allows you to set a limit for such cache inside + * the current process. Should be in the range 0..255, default is 64. */ + MDBX_opt_loose_limit, + + /** \brief Controls the in-process limit of a pre-allocated memory items + * for dirty pages. * * \details A 'dirty page' refers to a page that has been updated in memory * only, the changes to a dirty page are not yet stored on disk. * Without \ref MDBX_WRITEMAP dirty pages are allocated from memory and * released when a transaction is committed. To reduce overhead, it is - * reasonable to release not all pages, but to leave some ones in reserve for - * reuse in the next transaction. + * reasonable to release not all ones, but to leave some allocations in + * reserve for reuse in the next transaction(s). * - * The `MDBX_opt_dp_reserve_limit` allows you to set a limit for such a - * reserve inside the current process. Default is 1024. */ + * The `MDBX_opt_dp_reserve_limit` allows you to set a limit for such reserve + * inside the current process. Default is 1024. */ MDBX_opt_dp_reserve_limit, /** \brief Controls the in-process limit of dirty pages diff --git a/src/core.c b/src/core.c index 9bd75c6c..62ee6931 100644 --- a/src/core.c +++ b/src/core.c @@ -4287,9 +4287,14 @@ static int mdbx_page_loose(MDBX_txn *txn, MDBX_page *mp) { goto wrong_dirty; /* If suitable we can reuse it through loose list */ - if (likely(npages == 1 && - txn->tw.loose_count < 9 /* TODO: options.threshold */ - /* && txn->mt_next_pgno > pgno + TODO: txn->tw.loose_gap */)) { + if (likely( + npages == 1 && + txn->tw.loose_count < txn->mt_env->me_options.dp_loose_limit && + (!MDBX_ENABLE_REFUND || + /* skip pages near to the end in favor of compactification */ + txn->mt_next_pgno > + pgno + txn->mt_env->me_options.dp_loose_limit || + txn->mt_next_pgno <= txn->mt_env->me_options.dp_loose_limit))) { mdbx_debug("loosen dirty page %" PRIaPGNO, pgno); mp->mp_flags = P_LOOSE | P_DIRTY; mp->mp_next = txn->tw.loose_pages; @@ -9932,6 +9937,7 @@ __cold int mdbx_env_create(MDBX_env **penv) { env->me_options.spill_max_denominator = 8; env->me_options.spill_min_denominator = 8; env->me_options.spill_parent4child_denominator = 0; + env->me_options.dp_loose_limit = 64; int rc; const size_t os_psize = mdbx_syspagesize(); @@ -20475,6 +20481,12 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option, env->me_options.spill_parent4child_denominator = (uint8_t)value; break; + case MDBX_opt_loose_limit: + if (unlikely(value > 255)) + return MDBX_EINVAL; + env->me_options.dp_loose_limit = (uint8_t)value; + break; + default: return MDBX_EINVAL; } @@ -20538,6 +20550,10 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option, *value = env->me_options.spill_parent4child_denominator; break; + case MDBX_opt_loose_limit: + *value = env->me_options.dp_loose_limit; + break; + default: return MDBX_EINVAL; } diff --git a/src/internals.h b/src/internals.h index ecdab895..9a283269 100644 --- a/src/internals.h +++ b/src/internals.h @@ -983,6 +983,7 @@ struct MDBX_env { unsigned rp_augment_limit; unsigned dp_limit; unsigned dp_initial; + uint8_t dp_loose_limit; uint8_t spill_max_denominator; uint8_t spill_min_denominator; uint8_t spill_parent4child_denominator;