mdbx: add MDBX_opt_loose_limit runtime option.

More for https://github.com/erthink/libmdbx/issues/128

Change-Id: I298bf1eef24575df72615ee07e93f5073405e8e0
This commit is contained in:
Leonid Yuriev 2021-01-22 23:52:03 +03:00
parent dc34041600
commit 4ae2a107bf
3 changed files with 39 additions and 9 deletions

25
mdbx.h
View File

@ -1852,18 +1852,31 @@ enum MDBX_option_t {
* process. Default is 262144, it is usually enough for most cases. */ * process. Default is 262144, it is usually enough for most cases. */
MDBX_opt_rp_augment_limit, MDBX_opt_rp_augment_limit,
/** \brief Controls the in-process limit to grow a list of /** \brief Controls the in-process limit to grow a cache of dirty
* pre-allocated/reserved dirty pages. * 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 * \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. * only, the changes to a dirty page are not yet stored on disk.
* Without \ref MDBX_WRITEMAP dirty pages are allocated from memory and * Without \ref MDBX_WRITEMAP dirty pages are allocated from memory and
* released when a transaction is committed. To reduce overhead, it is * 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 * reasonable to release not all ones, but to leave some allocations in
* reuse in the next transaction. * reserve for reuse in the next transaction(s).
* *
* The `MDBX_opt_dp_reserve_limit` allows you to set a limit for such a * The `MDBX_opt_dp_reserve_limit` allows you to set a limit for such reserve
* reserve inside the current process. Default is 1024. */ * inside the current process. Default is 1024. */
MDBX_opt_dp_reserve_limit, MDBX_opt_dp_reserve_limit,
/** \brief Controls the in-process limit of dirty pages /** \brief Controls the in-process limit of dirty pages

View File

@ -4287,9 +4287,14 @@ static int mdbx_page_loose(MDBX_txn *txn, MDBX_page *mp) {
goto wrong_dirty; goto wrong_dirty;
/* If suitable we can reuse it through loose list */ /* If suitable we can reuse it through loose list */
if (likely(npages == 1 && if (likely(
txn->tw.loose_count < 9 /* TODO: options.threshold */ npages == 1 &&
/* && txn->mt_next_pgno > pgno + TODO: txn->tw.loose_gap */)) { 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); mdbx_debug("loosen dirty page %" PRIaPGNO, pgno);
mp->mp_flags = P_LOOSE | P_DIRTY; mp->mp_flags = P_LOOSE | P_DIRTY;
mp->mp_next = txn->tw.loose_pages; 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_max_denominator = 8;
env->me_options.spill_min_denominator = 8; env->me_options.spill_min_denominator = 8;
env->me_options.spill_parent4child_denominator = 0; env->me_options.spill_parent4child_denominator = 0;
env->me_options.dp_loose_limit = 64;
int rc; int rc;
const size_t os_psize = mdbx_syspagesize(); 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; env->me_options.spill_parent4child_denominator = (uint8_t)value;
break; break;
case MDBX_opt_loose_limit:
if (unlikely(value > 255))
return MDBX_EINVAL;
env->me_options.dp_loose_limit = (uint8_t)value;
break;
default: default:
return MDBX_EINVAL; 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; *value = env->me_options.spill_parent4child_denominator;
break; break;
case MDBX_opt_loose_limit:
*value = env->me_options.dp_loose_limit;
break;
default: default:
return MDBX_EINVAL; return MDBX_EINVAL;
} }

View File

@ -983,6 +983,7 @@ struct MDBX_env {
unsigned rp_augment_limit; unsigned rp_augment_limit;
unsigned dp_limit; unsigned dp_limit;
unsigned dp_initial; unsigned dp_initial;
uint8_t dp_loose_limit;
uint8_t spill_max_denominator; uint8_t spill_max_denominator;
uint8_t spill_min_denominator; uint8_t spill_min_denominator;
uint8_t spill_parent4child_denominator; uint8_t spill_parent4child_denominator;