diff --git a/mdbx.h b/mdbx.h index f7c9ff59..21aa371b 100644 --- a/mdbx.h +++ b/mdbx.h @@ -918,8 +918,7 @@ LIBMDBX_API int mdbx_env_set_maxdbs(MDBX_env *env, MDBX_dbi dbs); * [in] env An environment handle returned by mdbx_env_create() * * Returns The maximum size of a key we can write. */ -LIBMDBX_API int mdbx_env_get_maxkeysize(MDBX_env *env); -LIBMDBX_API int mdbx_get_maxkeysize(size_t pagesize); +LIBMDBX_API intptr_t mdbx_env_get_maxkeysize(MDBX_env *env); /* Set application information associated with the MDBX_env. * @@ -1692,6 +1691,13 @@ LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr); LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, uint64_t increment); +LIBMDBX_API intptr_t mdbx_limits_pgsize_min(void); +LIBMDBX_API intptr_t mdbx_limits_pgsize_max(void); +LIBMDBX_API intptr_t mdbx_limits_dbsize_min(intptr_t pagesize); +LIBMDBX_API intptr_t mdbx_limits_dbsize_max(intptr_t pagesize); +LIBMDBX_API intptr_t mdbx_limits_keysize_max(intptr_t pagesize); +LIBMDBX_API intptr_t mdbx_limits_txnsize_max(intptr_t pagesize); + /*----------------------------------------------------------------------------*/ /* attribute support functions for Nexenta */ typedef uint_fast64_t mdbx_attr_t; diff --git a/src/mdbx.c b/src/mdbx.c index ab41be88..812475b0 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -4921,7 +4921,7 @@ fail: return rc; } -int __cold mdbx_env_get_maxkeysize(MDBX_env *env) { +intptr_t __cold mdbx_env_get_maxkeysize(MDBX_env *env) { if (!env || env->me_signature != MDBX_ME_SIGNATURE || !env->me_maxkey_limit) return -MDBX_EINVAL; return env->me_maxkey_limit; @@ -4935,18 +4935,6 @@ int __cold mdbx_env_get_maxkeysize(MDBX_env *env) { #define mdbx_maxgc_ov1page(pagesize) \ (((pagesize)-PAGEHDRSZ) / sizeof(pgno_t) - 1) -int mdbx_get_maxkeysize(size_t pagesize) { - if (pagesize == 0) - pagesize = mdbx_syspagesize(); - - intptr_t nodemax = mdbx_nodemax(pagesize); - if (nodemax < 0) - return -MDBX_EINVAL; - - intptr_t maxkey = mdbx_maxkey(nodemax); - return (maxkey > 0 && maxkey < INT_MAX) ? (int)maxkey : -MDBX_EINVAL; -} - static void __cold mdbx_setup_pagesize(MDBX_env *env, const size_t pagesize) { STATIC_ASSERT(SSIZE_MAX > MAX_MAPSIZE); STATIC_ASSERT(MIN_PAGESIZE > sizeof(MDBX_page)); @@ -12325,6 +12313,53 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, return MDBX_SUCCESS; } +/*----------------------------------------------------------------------------*/ + +__cold intptr_t mdbx_limits_keysize_max(intptr_t pagesize) { + if (pagesize < 1) + pagesize = (intptr_t)mdbx_syspagesize(); + else if (unlikely(pagesize < MIN_PAGESIZE || pagesize > MAX_PAGESIZE || + !mdbx_is_power2((size_t)pagesize))) + return -MDBX_EINVAL; + + return mdbx_maxkey(mdbx_nodemax(pagesize)); +} + +__cold intptr_t mdbx_limits_pgsize_min(void) { return MIN_PAGESIZE; } + +__cold intptr_t mdbx_limits_pgsize_max(void) { return MAX_PAGESIZE; } + +__cold intptr_t mdbx_limits_dbsize_min(intptr_t pagesize) { + if (pagesize < 1) + pagesize = (intptr_t)mdbx_syspagesize(); + else if (unlikely(pagesize < MIN_PAGESIZE || pagesize > MAX_PAGESIZE || + !mdbx_is_power2((size_t)pagesize))) + return -MDBX_EINVAL; + + return MIN_PAGENO * pagesize; +} + +__cold intptr_t mdbx_limits_dbsize_max(intptr_t pagesize) { + if (pagesize < 1) + pagesize = (intptr_t)mdbx_syspagesize(); + else if (unlikely(pagesize < MIN_PAGESIZE || pagesize > MAX_PAGESIZE || + !mdbx_is_power2((size_t)pagesize))) + return -MDBX_EINVAL; + + const intptr_t limit = MAX_PAGENO * pagesize; + return ((size_t)limit < MAX_MAPSIZE) ? limit : MAX_PAGESIZE; +} + +__cold intptr_t mdbx_limits_txnsize_max(intptr_t pagesize) { + if (pagesize < 1) + pagesize = (intptr_t)mdbx_syspagesize(); + else if (unlikely(pagesize < MIN_PAGESIZE || pagesize > MAX_PAGESIZE || + !mdbx_is_power2((size_t)pagesize))) + return -MDBX_EINVAL; + + return pagesize * (MDBX_LIST_MAX - 1); +} + /*----------------------------------------------------------------------------*/ /* attribute support functions for Nexenta */ diff --git a/test/main.cc b/test/main.cc index e6e0e177..17b3d718 100644 --- a/test/main.cc +++ b/test/main.cc @@ -1,4 +1,4 @@ -/* +/* * Copyright 2017-2018 Leonid Yuriev * and other libmdbx authors: please see AUTHORS file. * All rights reserved. @@ -193,10 +193,10 @@ int main(int argc, char *const argv[]) { params.keylen_max = params.keylen_min; continue; } - if (config::parse_option( - argc, argv, narg, "keylen.max", params.keylen_max, config::no_scale, - 0, std::min(mdbx_get_maxkeysize(0), (int)UINT16_MAX))) { - + if (config::parse_option(argc, argv, narg, "keylen.max", params.keylen_max, + config::no_scale, 0, + std::min((unsigned)mdbx_limits_keysize_max(0), + (unsigned)UINT16_MAX))) { if (params.keylen_min > params.keylen_max) params.keylen_min = params.keylen_max; continue;