From 673570ec2aae4353cdbf71aba1a82eefc8d5a7d7 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Thu, 23 Apr 2020 17:15:55 +0300 Subject: [PATCH] mdbx: auto-choose pagesize for a large databases. Change-Id: I3f8279ba077a8c31c70504d32fb619b6601cc5c4 --- src/core.c | 47 ++++++++++++++++++++++++++++++++++------------- src/lck-windows.c | 11 +---------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/core.c b/src/core.c index 1e9afc6d..dee3687f 100644 --- a/src/core.c +++ b/src/core.c @@ -8837,7 +8837,7 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, } /* get untouched params from DB */ - if (pagesize < 0) + if (pagesize <= 0 || pagesize >= INT_MAX) pagesize = env->me_psize; if (size_lower < 0) size_lower = pgno2bytes(env, head->mm_geo.lower); @@ -8867,19 +8867,34 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, if (unlikely(inside_txn)) return MDBX_PANIC; - if (pagesize < 0) { - pagesize = env->me_os_psize; - if ((uintptr_t)pagesize > MAX_PAGESIZE) - pagesize = MAX_PAGESIZE; - mdbx_assert(env, (uintptr_t)pagesize >= MIN_PAGESIZE); + /* is requested some auto-value for pagesize ? */ + if (pagesize >= INT_MAX /* maximal */) + pagesize = MAX_PAGESIZE; + else if (pagesize <= 0) { + if (pagesize < 0 /* default */) { + pagesize = env->me_os_psize; + if ((uintptr_t)pagesize > MAX_PAGESIZE) + pagesize = MAX_PAGESIZE; + mdbx_assert(env, (uintptr_t)pagesize >= MIN_PAGESIZE); + } else if (pagesize == 0 /* minimal */) + pagesize = MIN_PAGESIZE; + + /* choose pagesize */ + intptr_t max_size = (size_now > size_lower) ? size_now : size_lower; + max_size = (size_upper > max_size) ? size_upper : max_size; + if (max_size < 0 /* default */) + max_size = DEFAULT_MAPSIZE; + else if (max_size == 0 /* minimal */) + max_size = MIN_MAPSIZE; + else if (max_size >= (intptr_t)MAX_MAPSIZE /* maximal */) + max_size = MAX_MAPSIZE; + + while (max_size > pagesize * (int64_t)MAX_PAGENO && + pagesize < MAX_PAGESIZE) + pagesize <<= 1; } } - if (pagesize == 0) - pagesize = MIN_PAGESIZE; - else if (pagesize == INTPTR_MAX) - pagesize = MAX_PAGESIZE; - if (pagesize < (intptr_t)MIN_PAGESIZE || pagesize > (intptr_t)MAX_PAGESIZE || !is_powerof2(pagesize)) { rc = MDBX_EINVAL; @@ -8891,6 +8906,8 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, if (MIN_MAPSIZE / pagesize < MIN_PAGENO) size_lower = MIN_PAGENO * pagesize; } + if (size_lower == INTPTR_MAX) + size_lower = MAX_MAPSIZE; if (size_now <= 0) { size_now = DEFAULT_MAPSIZE; @@ -8899,6 +8916,8 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, if (size_upper >= size_lower && size_now > size_upper) size_now = size_upper; } + if (size_now == INTPTR_MAX) + size_now = MAX_MAPSIZE; if (size_upper <= 0) { if ((size_t)size_now >= MAX_MAPSIZE / 2) @@ -8932,8 +8951,8 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, goto bailout; } - const size_t unit = - (env->me_os_psize > (size_t)pagesize) ? env->me_os_psize : pagesize; + const size_t unit = (env->me_os_psize > (size_t)pagesize) ? env->me_os_psize + : (size_t)pagesize; size_lower = ceil_powerof2(size_lower, unit); size_upper = ceil_powerof2(size_upper, unit); size_now = ceil_powerof2(size_now, unit); @@ -17830,6 +17849,7 @@ __cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) { !is_powerof2((size_t)pagesize))) return -1; + STATIC_ASSERT(MAX_MAPSIZE < INTPTR_MAX); const uint64_t limit = MAX_PAGENO * (uint64_t)pagesize; return (limit < (intptr_t)MAX_MAPSIZE) ? (intptr_t)limit : (intptr_t)MAX_MAPSIZE; @@ -17843,6 +17863,7 @@ __cold intptr_t mdbx_limits_txnsize_max(intptr_t pagesize) { !is_powerof2((size_t)pagesize))) return -1; + STATIC_ASSERT(MAX_MAPSIZE < INTPTR_MAX); const uint64_t limit = pagesize * (uint64_t)(MDBX_DPL_TXNFULL - 1); return (limit < (intptr_t)MAX_MAPSIZE) ? (intptr_t)limit : (intptr_t)MAX_MAPSIZE; diff --git a/src/lck-windows.c b/src/lck-windows.c index 19a71cc3..19870396 100644 --- a/src/lck-windows.c +++ b/src/lck-windows.c @@ -133,10 +133,9 @@ static __inline BOOL funlock(mdbx_filehandle_t fd, uint64_t offset, #define LCK_MAXLEN (1u + (size_t)(MAXSSIZE_T)) #define LCK_META_OFFSET 0 -#define LCK_META_LEN 0x10000u +#define LCK_META_LEN (MAX_PAGESIZE * NUM_METAS) #define LCK_BODY_OFFSET LCK_META_LEN #define LCK_BODY_LEN (LCK_MAXLEN - LCK_BODY_OFFSET) -#define LCK_META LCK_META_OFFSET, LCK_META_LEN #define LCK_BODY LCK_BODY_OFFSET, LCK_BODY_LEN #define LCK_WHOLE 0, LCK_MAXLEN @@ -397,14 +396,6 @@ static void lck_unlock(MDBX_env *env) { (void)err; SetLastError(ERROR_SUCCESS); - while (funlock(env->me_lazy_fd, LCK_META)) - ; - err = GetLastError(); - assert(err == ERROR_NOT_LOCKED || - (mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION)); - (void)err; - SetLastError(ERROR_SUCCESS); - while (funlock(env->me_lazy_fd, LCK_WHOLE)) ; err = GetLastError();