mdbx: fix size_t/unsigned/int warnings.

Change-Id: Ic5a8684aed232b8b732d6e7a87a6757f3f7afcec
This commit is contained in:
Leonid Yuriev 2017-06-05 20:48:05 +03:00 committed by Leo Yuriev
parent 7e85ad82f1
commit bfa6dea784
6 changed files with 233 additions and 186 deletions

View File

@ -27,7 +27,7 @@
- [x] Добавить мета-страницы в coredump, проверить lck - [x] Добавить мета-страницы в coredump, проверить lck
- [x] Сделать список для txnid_t, кода sizeof(txnid_t) > sizeof(pgno_t) и вернуть размер pgno_t - [x] Сделать список для txnid_t, кода sizeof(txnid_t) > sizeof(pgno_t) и вернуть размер pgno_t
- [x] Избавиться от умножения на размер страницы (заменить на сдвиг). - [x] Избавиться от умножения на размер страницы (заменить на сдвиг).
- [ ] Устранение всех предупреждений (в том числе под Windows). - [x] Устранение всех предупреждений (в том числе под Windows).
- [ ] Перевод mdbx-tools на С++ и сборка для Windows - [ ] Перевод mdbx-tools на С++ и сборка для Windows
- [ ] Заменить заглушки mdbx_version и mdbx_build - [ ] Заменить заглушки mdbx_version и mdbx_build
- [ ] Актуализация README.md - [ ] Актуализация README.md

8
mdbx.h
View File

@ -1562,9 +1562,9 @@ typedef void MDBX_debug_func(int type, const char *function, int line,
LIBMDBX_API int mdbx_setup_debug(int flags, MDBX_debug_func *logger); LIBMDBX_API int mdbx_setup_debug(int flags, MDBX_debug_func *logger);
typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned pgnumber, void *ctx, typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned pgnumber, void *ctx,
const char *dbi, const char *type, int nentries, const char *dbi, const char *type,
int payload_bytes, int header_bytes, size_t nentries, size_t payload_bytes,
int unused_bytes); size_t header_bytes, size_t unused_bytes);
LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
void *ctx); void *ctx);
@ -1595,7 +1595,7 @@ LIBMDBX_API int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
* of multi-values/duplicates for a given key. * of multi-values/duplicates for a given key.
* 2) updates the key for pointing to the actual key's data inside DB. */ * 2) updates the key for pointing to the actual key's data inside DB. */
LIBMDBX_API int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, LIBMDBX_API int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
MDBX_val *data, int *values_count); MDBX_val *data, size_t *values_count);
LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr); LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr);

View File

@ -660,9 +660,9 @@ struct MDBX_env {
unsigned me_maxfree_1pg; unsigned me_maxfree_1pg;
/* Max size of a node on a page */ /* Max size of a node on a page */
unsigned me_nodemax; unsigned me_nodemax;
unsigned me_maxkey_limit; /* max size of a key */ unsigned me_maxkey_limit; /* max size of a key */
int me_live_reader; /* have liveness lock in reader table */ mdbx_pid_t me_live_reader; /* have liveness lock in reader table */
void *me_userctx; /* User-settable context */ void *me_userctx; /* User-settable context */
#if MDBX_DEBUG #if MDBX_DEBUG
MDBX_assert_func *me_assert_func; /* Callback for assertion failures */ MDBX_assert_func *me_assert_func; /* Callback for assertion failures */
#endif #endif
@ -896,7 +896,7 @@ static __inline size_t roundup2(size_t value, size_t granularity) {
#define PAGEDATA(p) ((void *)((char *)(p) + PAGEHDRSZ)) #define PAGEDATA(p) ((void *)((char *)(p) + PAGEHDRSZ))
/* Number of nodes on a page */ /* Number of nodes on a page */
#define NUMKEYS(p) ((p)->mp_lower >> 1) #define NUMKEYS(p) ((unsigned)(p)->mp_lower >> 1)
/* The amount of space remaining in the page */ /* The amount of space remaining in the page */
#define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower) #define SIZELEFT(p) (indx_t)((p)->mp_upper - (p)->mp_lower)
@ -1045,9 +1045,10 @@ static __inline size_t NODEDSZ(const MDBX_node *node) {
} }
/* Set the size of the data for a leaf node */ /* Set the size of the data for a leaf node */
static __inline void SETDSZ(MDBX_node *node, unsigned size) { static __inline void SETDSZ(MDBX_node *node, size_t size) {
assert(size < INT_MAX);
if (UNALIGNED_OK) { if (UNALIGNED_OK) {
node->mn_dsize = size; node->mn_dsize = (uint32_t)size;
} else { } else {
node->mn_lo = (uint16_t)size; node->mn_lo = (uint16_t)size;
node->mn_hi = (uint16_t)(size >> 16); node->mn_hi = (uint16_t)(size >> 16);

View File

@ -159,16 +159,16 @@ __cold void mdbx_rthc_remove(mdbx_thread_key_t key) {
/* Allocate an IDL. /* Allocate an IDL.
* Allocates memory for an IDL of the given size. * Allocates memory for an IDL of the given size.
* Returns IDL on success, NULL on failure. */ * Returns IDL on success, NULL on failure. */
static MDBX_IDL mdbx_midl_alloc(unsigned size) { static MDBX_IDL mdbx_midl_alloc(size_t size) {
MDBX_IDL ids = malloc((size + 2) * sizeof(pgno_t)); MDBX_IDL ids = malloc((size + 2) * sizeof(pgno_t));
if (likely(ids)) { if (likely(ids)) {
*ids++ = size; *ids++ = (pgno_t)size;
*ids = 0; *ids = 0;
} }
return ids; return ids;
} }
static MDBX_TXL mdbx_txl_alloc(unsigned size) { static MDBX_TXL mdbx_txl_alloc(size_t size) {
MDBX_TXL ptr = malloc((size + 2) * sizeof(txnid_t)); MDBX_TXL ptr = malloc((size + 2) * sizeof(txnid_t));
if (likely(ptr)) { if (likely(ptr)) {
*ptr++ = size; *ptr++ = size;
@ -247,21 +247,21 @@ static void mdbx_midl_shrink(MDBX_IDL *idp) {
/* Grow an IDL. /* Grow an IDL.
* Return the IDL to the size growed by given number. * Return the IDL to the size growed by given number.
* [in,out] idp Address of the IDL to grow. */ * [in,out] idp Address of the IDL to grow. */
static int mdbx_midl_grow(MDBX_IDL *idp, unsigned num) { static int mdbx_midl_grow(MDBX_IDL *idp, size_t num) {
MDBX_IDL idn = *idp - 1; MDBX_IDL idn = *idp - 1;
/* grow it */ /* grow it */
idn = realloc(idn, (*idn + num + 2) * sizeof(pgno_t)); idn = realloc(idn, (*idn + num + 2) * sizeof(pgno_t));
if (unlikely(!idn)) if (unlikely(!idn))
return MDBX_ENOMEM; return MDBX_ENOMEM;
*idn++ += num; *idn++ += (pgno_t)num;
*idp = idn; *idp = idn;
return 0; return 0;
} }
static int mdbx_txl_grow(MDBX_TXL *ptr, unsigned num) { static int mdbx_txl_grow(MDBX_TXL *ptr, size_t num) {
MDBX_TXL list = *ptr - 1; MDBX_TXL list = *ptr - 1;
/* grow it */ /* grow it */
list = realloc(list, (*list + num + 2) * sizeof(txnid_t)); list = realloc(list, ((size_t)*list + num + 2) * sizeof(txnid_t));
if (unlikely(!list)) if (unlikely(!list))
return MDBX_ENOMEM; return MDBX_ENOMEM;
*list++ += num; *list++ += num;
@ -273,7 +273,7 @@ static int mdbx_txl_grow(MDBX_TXL *ptr, unsigned num) {
* [in,out] idp Address of the IDL. * [in,out] idp Address of the IDL.
* [in] num Number of elements to make room for. * [in] num Number of elements to make room for.
* Returns 0 on success, MDBX_ENOMEM on failure. */ * Returns 0 on success, MDBX_ENOMEM on failure. */
static int mdbx_midl_need(MDBX_IDL *idp, unsigned num) { static int mdbx_midl_need(MDBX_IDL *idp, size_t num) {
MDBX_IDL ids = *idp; MDBX_IDL ids = *idp;
num += ids[0]; num += ids[0];
if (unlikely(num > ids[-1])) { if (unlikely(num > ids[-1])) {
@ -281,7 +281,7 @@ static int mdbx_midl_need(MDBX_IDL *idp, unsigned num) {
ids = realloc(ids - 1, num * sizeof(pgno_t)); ids = realloc(ids - 1, num * sizeof(pgno_t));
if (unlikely(!ids)) if (unlikely(!ids))
return MDBX_ENOMEM; return MDBX_ENOMEM;
*ids++ = num - 2; *ids++ = (pgno_t)num - 2;
*idp = ids; *idp = ids;
} }
return 0; return 0;
@ -308,7 +308,7 @@ static int mdbx_txl_append(MDBX_TXL *ptr, txnid_t id) {
MDBX_TXL list = *ptr; MDBX_TXL list = *ptr;
/* Too big? */ /* Too big? */
if (unlikely(list[0] >= list[-1])) { if (unlikely(list[0] >= list[-1])) {
if (mdbx_txl_grow(ptr, list[0])) if (mdbx_txl_grow(ptr, (size_t)list[0]))
return MDBX_ENOMEM; return MDBX_ENOMEM;
list = *ptr; list = *ptr;
} }
@ -338,11 +338,11 @@ static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) {
MDBX_TXL list = *ptr; MDBX_TXL list = *ptr;
/* Too big? */ /* Too big? */
if (unlikely(list[0] + append[0] >= list[-1])) { if (unlikely(list[0] + append[0] >= list[-1])) {
if (mdbx_txl_grow(ptr, append[0])) if (mdbx_txl_grow(ptr, (size_t)append[0]))
return MDBX_ENOMEM; return MDBX_ENOMEM;
list = *ptr; list = *ptr;
} }
memcpy(&list[list[0] + 1], &append[1], append[0] * sizeof(txnid_t)); memcpy(&list[list[0] + 1], &append[1], (size_t)append[0] * sizeof(txnid_t));
list[0] += append[0]; list[0] += append[0];
return 0; return 0;
} }
@ -352,7 +352,7 @@ static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) {
* [in] id The lowest ID to append. * [in] id The lowest ID to append.
* [in] n Number of IDs to append. * [in] n Number of IDs to append.
* Returns 0 on success, MDBX_ENOMEM if the IDL is too large. */ * Returns 0 on success, MDBX_ENOMEM if the IDL is too large. */
static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, unsigned n) { static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, size_t n) {
pgno_t *ids = *idp, len = ids[0]; pgno_t *ids = *idp, len = ids[0];
/* Too big? */ /* Too big? */
if (unlikely(len + n > ids[-1])) { if (unlikely(len + n > ids[-1])) {
@ -360,7 +360,7 @@ static int mdbx_midl_append_range(MDBX_IDL *idp, pgno_t id, unsigned n) {
return MDBX_ENOMEM; return MDBX_ENOMEM;
ids = *idp; ids = *idp;
} }
ids[0] = len + n; ids[0] = len + (pgno_t)n;
ids += len; ids += len;
while (n) while (n)
ids[n--] = id++; ids[n--] = id++;
@ -605,7 +605,7 @@ static void mdbx_env_close0(MDBX_env *env);
static MDBX_node *mdbx_node_search(MDBX_cursor *mc, MDBX_val *key, int *exactp); static MDBX_node *mdbx_node_search(MDBX_cursor *mc, MDBX_val *key, int *exactp);
static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key, static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key,
MDBX_val *data, pgno_t pgno, unsigned flags); MDBX_val *data, pgno_t pgno, unsigned flags);
static void mdbx_node_del(MDBX_cursor *mc, int ksize); static void mdbx_node_del(MDBX_cursor *mc, size_t ksize);
static void mdbx_node_shrink(MDBX_page *mp, indx_t indx); static void mdbx_node_shrink(MDBX_page *mp, indx_t indx);
static int mdbx_node_move(MDBX_cursor *csrc, MDBX_cursor *cdst, int fromleft); static int mdbx_node_move(MDBX_cursor *csrc, MDBX_cursor *cdst, int fromleft);
static int mdbx_node_read(MDBX_cursor *mc, MDBX_node *leaf, MDBX_val *data); static int mdbx_node_read(MDBX_cursor *mc, MDBX_node *leaf, MDBX_val *data);
@ -923,18 +923,16 @@ static void mdbx_cursor_chk(MDBX_cursor *mc) {
static void mdbx_audit(MDBX_txn *txn) { static void mdbx_audit(MDBX_txn *txn) {
MDBX_cursor mc; MDBX_cursor mc;
MDBX_val key, data; MDBX_val key, data;
pgno_t freecount, count;
MDBX_dbi i;
int rc; int rc;
freecount = 0; pgno_t freecount = 0;
mdbx_cursor_init(&mc, txn, FREE_DBI, NULL); mdbx_cursor_init(&mc, txn, FREE_DBI, NULL);
while ((rc = mdbx_cursor_get(&mc, &key, &data, MDBX_NEXT)) == 0) while ((rc = mdbx_cursor_get(&mc, &key, &data, MDBX_NEXT)) == 0)
freecount += *(pgno_t *)data.iov_base; freecount += *(pgno_t *)data.iov_base;
mdbx_tassert(txn, rc == MDBX_NOTFOUND); mdbx_tassert(txn, rc == MDBX_NOTFOUND);
count = 0; pgno_t count = 0;
for (i = 0; i < txn->mt_numdbs; i++) { for (MDBX_dbi i = 0; i < txn->mt_numdbs; i++) {
MDBX_xcursor mx; MDBX_xcursor mx;
if (!(txn->mt_dbflags[i] & DB_VALID)) if (!(txn->mt_dbflags[i] & DB_VALID))
continue; continue;
@ -946,10 +944,8 @@ static void mdbx_audit(MDBX_txn *txn) {
if (txn->mt_dbs[i].md_flags & MDBX_DUPSORT) { if (txn->mt_dbs[i].md_flags & MDBX_DUPSORT) {
rc = mdbx_page_search(&mc, NULL, MDBX_PS_FIRST); rc = mdbx_page_search(&mc, NULL, MDBX_PS_FIRST);
for (; rc == MDBX_SUCCESS; rc = mdbx_cursor_sibling(&mc, 1)) { for (; rc == MDBX_SUCCESS; rc = mdbx_cursor_sibling(&mc, 1)) {
unsigned j; MDBX_page *mp = mc.mc_pg[mc.mc_top];
MDBX_page *mp; for (unsigned j = 0; j < NUMKEYS(mp); j++) {
mp = mc.mc_pg[mc.mc_top];
for (j = 0; j < NUMKEYS(mp); j++) {
MDBX_node *leaf = NODEPTR(mp, j); MDBX_node *leaf = NODEPTR(mp, j);
if (leaf->mn_flags & F_SUBDATA) { if (leaf->mn_flags & F_SUBDATA) {
MDBX_db db; MDBX_db db;
@ -1195,7 +1191,7 @@ mark_done:
return rc; return rc;
} }
static int mdbx_page_flush(MDBX_txn *txn, size_t keep); static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep);
/* Spill pages from the dirty list back to disk. /* Spill pages from the dirty list back to disk.
* This is intended to prevent running into MDBX_TXN_FULL situations, * This is intended to prevent running into MDBX_TXN_FULL situations,
@ -1239,7 +1235,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
/* Estimate how much space this op will take */ /* Estimate how much space this op will take */
size_t i = m0->mc_db->md_depth; pgno_t i = m0->mc_db->md_depth;
/* Named DBs also dirty the main DB */ /* Named DBs also dirty the main DB */
if (m0->mc_dbi >= CORE_DBS) if (m0->mc_dbi >= CORE_DBS)
i += txn->mt_dbs[MAIN_DBI].md_depth; i += txn->mt_dbs[MAIN_DBI].md_depth;
@ -1247,7 +1243,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) {
if (key) if (key)
i += bytes2pgno(txn->mt_env, LEAFSIZE(key, data) + txn->mt_env->me_psize); i += bytes2pgno(txn->mt_env, LEAFSIZE(key, data) + txn->mt_env->me_psize);
i += i; /* double it for good measure */ i += i; /* double it for good measure */
size_t need = i; pgno_t need = i;
if (txn->mt_dirtyroom > i) if (txn->mt_dirtyroom > i)
return MDBX_SUCCESS; return MDBX_SUCCESS;
@ -1259,7 +1255,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) {
} else { } else {
/* purge deleted slots */ /* purge deleted slots */
MDBX_IDL sl = txn->mt_spill_pages; MDBX_IDL sl = txn->mt_spill_pages;
unsigned num = sl[0], j = 0; pgno_t num = sl[0], j = 0;
for (i = 1; i <= num; i++) { for (i = 1; i <= num; i++) {
if (!(sl[i] & 1)) if (!(sl[i] & 1))
sl[++j] = sl[i]; sl[++j] = sl[i];
@ -1268,7 +1264,7 @@ static int mdbx_page_spill(MDBX_cursor *m0, MDBX_val *key, MDBX_val *data) {
} }
/* Preserve pages which may soon be dirtied again */ /* Preserve pages which may soon be dirtied again */
int rc = mdbx_pages_xkeep(m0, P_DIRTY, 1); int rc = mdbx_pages_xkeep(m0, P_DIRTY, true);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto bailout; goto bailout;
@ -1684,7 +1680,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
if (flags & MDBX_LIFORECLAIM) { if (flags & MDBX_LIFORECLAIM) {
if (txn->mt_lifo_reclaimed) { if (txn->mt_lifo_reclaimed) {
for (j = txn->mt_lifo_reclaimed[0]; j > 0; --j) for (j = (unsigned)txn->mt_lifo_reclaimed[0]; j > 0; --j)
if (txn->mt_lifo_reclaimed[j] == last) if (txn->mt_lifo_reclaimed[j] == last)
break; break;
if (j) if (j)
@ -2896,7 +2892,8 @@ again:
head_room = mop_len - total_room; head_room = mop_len - total_room;
if (head_room > maxfree_1pg && head_id > 1) { if (head_room > maxfree_1pg && head_id > 1) {
/* Overflow multi-page for part of me_pghead */ /* Overflow multi-page for part of me_pghead */
head_room /= head_id; /* amortize page sizes */ head_room /= (head_id < INT16_MAX) ? (pgno_t)head_id
: INT16_MAX; /* amortize page sizes */
head_room += maxfree_1pg - head_room % (maxfree_1pg + 1); head_room += maxfree_1pg - head_room % (maxfree_1pg + 1);
} else if (head_room < 0) { } else if (head_room < 0) {
/* Rare case, not bothering to delete this record */ /* Rare case, not bothering to delete this record */
@ -2989,7 +2986,7 @@ again:
data.iov_base = mop -= len; data.iov_base = mop -= len;
save = mop[0]; save = mop[0];
mop[0] = len; mop[0] = (pgno_t)len;
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT); rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT);
mdbx_tassert( mdbx_tassert(
txn, cleanup_idx == txn, cleanup_idx ==
@ -3015,7 +3012,7 @@ bailout:
* records. */ * records. */
cleanup_idx = 0; cleanup_idx = 0;
/* LY: restart filling */ /* LY: restart filling */
refill_idx = total_room = head_room = 0; total_room = head_room = refill_idx = 0;
more = 1; more = 1;
goto again; goto again;
} }
@ -3033,11 +3030,11 @@ bailout:
* [in] txn the transaction that's being committed * [in] txn the transaction that's being committed
* [in] keep number of initial pages in dirtylist to keep dirty. * [in] keep number of initial pages in dirtylist to keep dirty.
* Returns 0 on success, non-zero on failure. */ * Returns 0 on success, non-zero on failure. */
static int mdbx_page_flush(MDBX_txn *txn, size_t keep) { static int mdbx_page_flush(MDBX_txn *txn, pgno_t keep) {
MDBX_env *env = txn->mt_env; MDBX_env *env = txn->mt_env;
MDBX_ID2L dl = txn->mt_rw_dirtylist; MDBX_ID2L dl = txn->mt_rw_dirtylist;
unsigned j; unsigned i, j, pagecount = dl[0].mid;
int i, pagecount = dl[0].mid, rc; int rc;
size_t size = 0, pos = 0; size_t size = 0, pos = 0;
pgno_t pgno = 0; pgno_t pgno = 0;
MDBX_page *dp = NULL; MDBX_page *dp = NULL;
@ -3609,7 +3606,10 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
MDBX_meta *const meta2 = METAPAGE(env, 2); MDBX_meta *const meta2 = METAPAGE(env, 2);
MDBX_meta *const head = mdbx_meta_head(env); MDBX_meta *const head = mdbx_meta_head(env);
const size_t prev_mapsize = head->mm_mapsize; mdbx_assert(env, head->mm_mapsize < MAX_MAPSIZE);
STATIC_ASSERT(SSIZE_MAX > MAX_MAPSIZE);
const size_t prev_mapsize = (size_t)head->mm_mapsize;
const size_t used_size = pgno2bytes(env, pending->mm_last_pg + 1); const size_t used_size = pgno2bytes(env, pending->mm_last_pg + 1);
mdbx_assert(env, mdbx_meta_eq_mask(env) == 0); mdbx_assert(env, mdbx_meta_eq_mask(env) == 0);
@ -3806,11 +3806,17 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
mdbx_assert(env, ((env->me_flags ^ flags) & MDBX_WRITEMAP) == 0); mdbx_assert(env, ((env->me_flags ^ flags) & MDBX_WRITEMAP) == 0);
if (unlikely(pending->mm_mapsize < prev_mapsize)) { if (unlikely(pending->mm_mapsize < prev_mapsize)) {
mdbx_assert(env, pending->mm_mapsize == env->me_mapsize); mdbx_assert(env, pending->mm_mapsize == env->me_mapsize);
rc = mdbx_ftruncate(env->me_fd, pending->mm_mapsize); if (pending->mm_mapsize > MAX_MAPSIZE) {
rc = MDBX_PROBLEM;
goto fail;
}
const size_t mapsize = (size_t)pending->mm_mapsize;
mdbx_assert(env, pending->mm_mapsize == mapsize);
rc = mdbx_ftruncate(env->me_fd, mapsize);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto fail; goto fail;
rc = mdbx_mremap_size((void **)&env->me_map, prev_mapsize, rc = mdbx_mremap_size((void **)&env->me_map, prev_mapsize, mapsize);
pending->mm_mapsize);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto fail; goto fail;
} }
@ -3828,26 +3834,22 @@ int __cold mdbx_env_get_maxkeysize(MDBX_env *env) {
return env->me_maxkey_limit; return env->me_maxkey_limit;
} }
static __inline ssize_t mdbx_calc_nodemax(ssize_t pagesize) { #define mdbx_nodemax(pagesize) \
assert(pagesize > 0); (((((pagesize)-PAGEHDRSZ) / MDBX_MINKEYS) & -(ssize_t)2) - sizeof(indx_t))
return (((pagesize - PAGEHDRSZ) / MDBX_MINKEYS) & -(ssize_t)2) -
sizeof(indx_t);
}
static __inline ssize_t mdbx_calc_maxkey(ssize_t nodemax) { #define mdbx_maxkey(nodemax) ((nodemax) - (NODESIZE + sizeof(MDBX_db)))
assert(nodemax > 0);
return nodemax - (NODESIZE + sizeof(MDBX_db)); #define mdbx_maxfree1pg(pagesize) (((pagesize)-PAGEHDRSZ) / sizeof(pgno_t) - 1)
}
int mdbx_get_maxkeysize(size_t pagesize) { int mdbx_get_maxkeysize(size_t pagesize) {
if (pagesize == 0) if (pagesize == 0)
pagesize = mdbx_syspagesize(); pagesize = mdbx_syspagesize();
ssize_t nodemax = mdbx_calc_nodemax(pagesize); ssize_t nodemax = mdbx_nodemax(pagesize);
if (nodemax < 0) if (nodemax < 0)
return -MDBX_EINVAL; return -MDBX_EINVAL;
ssize_t maxkey = mdbx_calc_maxkey(nodemax); ssize_t maxkey = mdbx_maxkey(nodemax);
return (maxkey > 0 && maxkey < INT_MAX) ? (int)maxkey : -MDBX_EINVAL; return (maxkey > 0 && maxkey < INT_MAX) ? (int)maxkey : -MDBX_EINVAL;
} }
@ -3856,12 +3858,27 @@ static void __cold mdbx_setup_pagesize(MDBX_env *env, size_t pagesize) {
mdbx_ensure(env, pagesize >= MIN_PAGESIZE); mdbx_ensure(env, pagesize >= MIN_PAGESIZE);
mdbx_ensure(env, pagesize <= MAX_PAGESIZE); mdbx_ensure(env, pagesize <= MAX_PAGESIZE);
env->me_psize = pagesize; env->me_psize = (unsigned)pagesize;
env->me_maxfree_1pg = (pagesize - PAGEHDRSZ) / sizeof(pgno_t) - 1;
env->me_nodemax = mdbx_calc_nodemax(pagesize); STATIC_ASSERT(mdbx_maxfree1pg(MIN_PAGESIZE) > 42);
env->me_maxkey_limit = mdbx_calc_maxkey(env->me_nodemax); STATIC_ASSERT(mdbx_maxfree1pg(MAX_PAGESIZE) < MDBX_IDL_DB_MAX);
mdbx_assert(env, const ssize_t maxfree_1pg = (pagesize - PAGEHDRSZ) / sizeof(pgno_t) - 1;
env->me_maxkey_limit > 42 && env->me_maxkey_limit < pagesize); mdbx_ensure(env, maxfree_1pg > 42 && maxfree_1pg < MDBX_IDL_DB_MAX);
env->me_maxfree_1pg = (unsigned)maxfree_1pg;
STATIC_ASSERT(mdbx_nodemax(MIN_PAGESIZE) > 42);
STATIC_ASSERT(mdbx_nodemax(MAX_PAGESIZE) < UINT16_MAX);
const ssize_t nodemax = mdbx_nodemax(pagesize);
mdbx_ensure(env, nodemax > 42 && nodemax < UINT16_MAX);
env->me_nodemax = (unsigned)nodemax;
STATIC_ASSERT(mdbx_maxkey(MIN_PAGESIZE) > 42);
STATIC_ASSERT(mdbx_maxkey(MIN_PAGESIZE) < MIN_PAGESIZE);
STATIC_ASSERT(mdbx_maxkey(MAX_PAGESIZE) > 42);
STATIC_ASSERT(mdbx_maxkey(MAX_PAGESIZE) < MAX_PAGESIZE);
const ssize_t maxkey_limit = mdbx_maxkey(env->me_nodemax);
mdbx_ensure(env, maxkey_limit > 42 && (size_t)maxkey_limit < pagesize);
env->me_maxkey_limit = (unsigned)maxkey_limit;
env->me_psize2log = 0; env->me_psize2log = 0;
while (pagesize > 1) { while (pagesize > 1) {
@ -3884,12 +3901,13 @@ int __cold mdbx_env_create(MDBX_env **penv) {
env->me_pid = mdbx_getpid(); env->me_pid = mdbx_getpid();
int rc; int rc;
env->me_os_psize = mdbx_syspagesize(); const size_t os_psize = mdbx_syspagesize();
if (!is_power2(env->me_os_psize) || env->me_os_psize < MIN_PAGESIZE) { if (!is_power2(os_psize) || os_psize < MIN_PAGESIZE) {
mdbx_error("unsuitable system pageize %u", env->me_os_psize); mdbx_error("unsuitable system pageize %" PRIuPTR, os_psize);
rc = MDBX_INCOMPATIBLE; rc = MDBX_INCOMPATIBLE;
goto bailout; goto bailout;
} }
env->me_os_psize = (unsigned)os_psize;
mdbx_setup_pagesize(env, env->me_os_psize); mdbx_setup_pagesize(env, env->me_os_psize);
rc = mdbx_fastmutex_init(&env->me_dbi_lock); rc = mdbx_fastmutex_init(&env->me_dbi_lock);
@ -4261,23 +4279,22 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) {
return err; return err;
size = wanna; size = wanna;
} }
} } else if (size > SSIZE_MAX || (size & (env->me_os_psize - 1)) ||
size < env->me_os_psize) {
if ((size & (env->me_os_psize - 1)) || size < env->me_os_psize) {
mdbx_notice("lck-file has invalid size %" PRIu64 " bytes", size); mdbx_notice("lck-file has invalid size %" PRIu64 " bytes", size);
return MDBX_PROBLEM; return MDBX_PROBLEM;
} }
const uint64_t maxreaders = const size_t maxreaders =
(size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader) + 1; ((size_t)size - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader) + 1;
if (maxreaders > UINT16_MAX) { if (maxreaders > UINT16_MAX) {
mdbx_error("lck-size too big (up to %" PRIu64 " readers)", maxreaders); mdbx_error("lck-size too big (up to %" PRIuPTR " readers)", maxreaders);
return MDBX_PROBLEM; return MDBX_PROBLEM;
} }
env->me_maxreaders = (unsigned)maxreaders; env->me_maxreaders = (unsigned)maxreaders;
void *addr = NULL; void *addr = NULL;
err = mdbx_mmap(&addr, size, true, env->me_lfd); err = mdbx_mmap(&addr, (size_t)size, true, env->me_lfd);
if (unlikely(err != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
return err; return err;
assert(addr != nullptr); assert(addr != nullptr);
@ -4304,7 +4321,7 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) {
if (rc == MDBX_RESULT_TRUE) { if (rc == MDBX_RESULT_TRUE) {
/* LY: exlcusive mode, init lck */ /* LY: exlcusive mode, init lck */
memset(env->me_lck, 0, size); memset(env->me_lck, 0, (size_t)size);
err = mdbx_lck_init(env); err = mdbx_lck_init(env);
if (err) if (err)
return err; return err;
@ -4344,9 +4361,6 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, int mode) {
int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags, int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags,
mode_t mode, int *exclusive) { mode_t mode, int *exclusive) {
int oflags, rc, len;
char *lck_pathname, *dxb_pathname;
if (unlikely(!env || !path)) if (unlikely(!env || !path))
return MDBX_EINVAL; return MDBX_EINVAL;
@ -4357,16 +4371,17 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags,
(flags & ~(CHANGEABLE | CHANGELESS))) (flags & ~(CHANGEABLE | CHANGELESS)))
return MDBX_EINVAL; return MDBX_EINVAL;
len = strlen(path); size_t len_full, len = strlen(path);
if (flags & MDBX_NOSUBDIR) { if (flags & MDBX_NOSUBDIR) {
rc = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1; len_full = len + sizeof(MDBX_LOCK_SUFFIX) + len + 1;
} else { } else {
rc = len + sizeof(MDBX_LOCKNAME) + len + sizeof(MDBX_DATANAME); len_full = len + sizeof(MDBX_LOCKNAME) + len + sizeof(MDBX_DATANAME);
} }
lck_pathname = malloc(rc); char *lck_pathname = malloc(len_full);
if (!lck_pathname) if (!lck_pathname)
return MDBX_ENOMEM; return MDBX_ENOMEM;
char *dxb_pathname;
if (flags & MDBX_NOSUBDIR) { if (flags & MDBX_NOSUBDIR) {
dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCK_SUFFIX); dxb_pathname = lck_pathname + len + sizeof(MDBX_LOCK_SUFFIX);
sprintf(lck_pathname, "%s" MDBX_LOCK_SUFFIX, path); sprintf(lck_pathname, "%s" MDBX_LOCK_SUFFIX, path);
@ -4377,7 +4392,7 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags,
sprintf(dxb_pathname, "%s" MDBX_DATANAME, path); sprintf(dxb_pathname, "%s" MDBX_DATANAME, path);
} }
rc = MDBX_SUCCESS; int rc = MDBX_SUCCESS;
flags |= env->me_flags; flags |= env->me_flags;
if (flags & MDBX_RDONLY) { if (flags & MDBX_RDONLY) {
/* LY: silently ignore irrelevant flags when /* LY: silently ignore irrelevant flags when
@ -4403,6 +4418,7 @@ int __cold mdbx_env_open_ex(MDBX_env *env, const char *path, unsigned flags,
} }
env->me_dbxs[FREE_DBI].md_cmp = mdbx_cmp_int_ai; /* aligned MDBX_INTEGERKEY */ env->me_dbxs[FREE_DBI].md_cmp = mdbx_cmp_int_ai; /* aligned MDBX_INTEGERKEY */
int oflags;
if (F_ISSET(flags, MDBX_RDONLY)) if (F_ISSET(flags, MDBX_RDONLY))
oflags = O_RDONLY; oflags = O_RDONLY;
else else
@ -5970,7 +5986,6 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
uint16_t fp_flags; uint16_t fp_flags;
MDBX_val xdata, *rdata, dkey, olddata; MDBX_val xdata, *rdata, dkey, olddata;
MDBX_db dummy; MDBX_db dummy;
int do_sub = 0, insert_key, insert_data;
unsigned mcount = 0, dcount = 0, nospill; unsigned mcount = 0, dcount = 0, nospill;
size_t nsize; size_t nsize;
int rc = MDBX_SUCCESS, rc2; int rc = MDBX_SUCCESS, rc2;
@ -5987,10 +6002,12 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
/* Check this first so counter will always be zero on any early failures. */ /* Check this first so counter will always be zero on any early failures. */
if (flags & MDBX_MULTIPLE) { if (flags & MDBX_MULTIPLE) {
dcount = data[1].iov_len;
data[1].iov_len = 0;
if (unlikely(!F_ISSET(mc->mc_db->md_flags, MDBX_DUPFIXED))) if (unlikely(!F_ISSET(mc->mc_db->md_flags, MDBX_DUPFIXED)))
return MDBX_INCOMPATIBLE; return MDBX_INCOMPATIBLE;
if (unlikely(data[1].iov_len >= INT_MAX))
return MDBX_EINVAL;
dcount = (unsigned)data[1].iov_len;
data[1].iov_len = 0;
} }
if (flags & MDBX_RESERVE) { if (flags & MDBX_RESERVE) {
@ -6137,7 +6154,8 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
return rc2; return rc2;
} }
insert_key = insert_data = rc; bool insert_key, insert_data, do_sub = false;
insert_key = insert_data = (rc != MDBX_SUCCESS);
if (insert_key) { if (insert_key) {
/* The key does not exist */ /* The key does not exist */
mdbx_debug("inserting key at index %i", mc->mc_ki[mc->mc_top]); mdbx_debug("inserting key at index %i", mc->mc_ki[mc->mc_top]);
@ -6285,7 +6303,8 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
xdata.iov_base = &dummy; xdata.iov_base = &dummy;
if ((rc = mdbx_page_alloc(mc, 1, &mp, MDBX_ALLOC_ALL))) if ((rc = mdbx_page_alloc(mc, 1, &mp, MDBX_ALLOC_ALL)))
return rc; return rc;
offset = env->me_psize - olddata.iov_len; mdbx_cassert(mc, env->me_psize > olddata.iov_len);
offset = env->me_psize - (unsigned)olddata.iov_len;
flags |= F_DUPDATA | F_SUBDATA; flags |= F_DUPDATA | F_SUBDATA;
dummy.md_root = mp->mp_pgno; dummy.md_root = mp->mp_pgno;
sub_root = mp; sub_root = mp;
@ -6308,7 +6327,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
rdata = &xdata; rdata = &xdata;
flags |= F_DUPDATA; flags |= F_DUPDATA;
do_sub = 1; do_sub = true;
if (!insert_key) if (!insert_key)
mdbx_node_del(mc, 0); mdbx_node_del(mc, 0);
goto new_sub; goto new_sub;
@ -6388,14 +6407,16 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
else if (!(mc->mc_flags & C_SUB)) else if (!(mc->mc_flags & C_SUB))
memcpy(olddata.iov_base, data->iov_base, data->iov_len); memcpy(olddata.iov_base, data->iov_base, data->iov_len);
else { else {
assert(NUMKEYS(mc->mc_pg[mc->mc_top]) == 1); mdbx_cassert(mc, NUMKEYS(mc->mc_pg[mc->mc_top]) == 1);
assert(mc->mc_pg[mc->mc_top]->mp_upper == mdbx_cassert(mc, mc->mc_pg[mc->mc_top]->mp_upper ==
mc->mc_pg[mc->mc_top]->mp_lower); mc->mc_pg[mc->mc_top]->mp_lower);
assert(IS_LEAF(mc->mc_pg[mc->mc_top]) && mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]) &&
!IS_LEAF2(mc->mc_pg[mc->mc_top])); !IS_LEAF2(mc->mc_pg[mc->mc_top]));
assert(NODEDSZ(leaf) == 0); mdbx_cassert(mc, NODEDSZ(leaf) == 0);
assert(leaf->mn_flags == 0); mdbx_cassert(mc, leaf->mn_flags == 0);
memcpy(NODEKEY(leaf), key->iov_base, leaf->mn_ksize = key->iov_len); mdbx_cassert(mc, key->iov_len < UINT16_MAX);
leaf->mn_ksize = (uint16_t)key->iov_len;
memcpy(NODEKEY(leaf), key->iov_base, key->iov_len);
assert((char *)NODEDATA(leaf) + NODEDSZ(leaf) < assert((char *)NODEDATA(leaf) + NODEDSZ(leaf) <
(char *)(mc->mc_pg[mc->mc_top]) + env->me_psize); (char *)(mc->mc_pg[mc->mc_top]) + env->me_psize);
goto fix_parent; goto fix_parent;
@ -6496,7 +6517,8 @@ new_sub:
} }
} }
} }
ecount = mc->mc_xcursor->mx_db.md_entries; mdbx_cassert(mc, mc->mc_xcursor->mx_db.md_entries < SIZE_MAX);
ecount = (size_t)mc->mc_xcursor->mx_db.md_entries;
if (flags & MDBX_APPENDDUP) if (flags & MDBX_APPENDDUP)
xflags |= MDBX_APPEND; xflags |= MDBX_APPEND;
rc = mdbx_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags); rc = mdbx_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags);
@ -6504,7 +6526,7 @@ new_sub:
void *db = NODEDATA(leaf); void *db = NODEDATA(leaf);
memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDBX_db)); memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDBX_db));
} }
insert_data = mc->mc_xcursor->mx_db.md_entries - ecount; insert_data = (ecount != (size_t)mc->mc_xcursor->mx_db.md_entries);
} }
/* Increment count unless we just replaced an existing item. */ /* Increment count unless we just replaced an existing item. */
if (insert_data) if (insert_data)
@ -6524,7 +6546,7 @@ new_sub:
data[1].iov_len = mcount; data[1].iov_len = mcount;
if (mcount < dcount) { if (mcount < dcount) {
data[0].iov_base = (char *)data[0].iov_base + data[0].iov_len; data[0].iov_base = (char *)data[0].iov_base + data[0].iov_len;
insert_key = insert_data = 0; insert_key = insert_data = false;
goto more; goto more;
} }
} }
@ -6765,7 +6787,6 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key,
unsigned i; unsigned i;
size_t node_size = NODESIZE; size_t node_size = NODESIZE;
ssize_t room; ssize_t room;
unsigned ofs;
MDBX_node *node; MDBX_node *node;
MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
MDBX_page *ofp = NULL; /* overflow page */ MDBX_page *ofp = NULL; /* overflow page */
@ -6783,17 +6804,19 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key,
if (IS_LEAF2(mp)) { if (IS_LEAF2(mp)) {
mdbx_cassert(mc, key); mdbx_cassert(mc, key);
/* Move higher keys up one slot. */ /* Move higher keys up one slot. */
int ksize = mc->mc_db->md_xsize, dif; const int ksize = mc->mc_db->md_xsize;
char *ptr = LEAF2KEY(mp, indx, ksize); char *const ptr = LEAF2KEY(mp, indx, ksize);
dif = NUMKEYS(mp) - indx; const int diff = NUMKEYS(mp) - indx;
if (dif > 0) if (diff > 0)
memmove(ptr + ksize, ptr, dif * ksize); memmove(ptr + ksize, ptr, diff * ksize);
/* insert new key */ /* insert new key */
memcpy(ptr, key->iov_base, ksize); memcpy(ptr, key->iov_base, ksize);
/* Just using these for counting */ /* Just using these for counting */
mdbx_cassert(mc, UINT16_MAX - mp->mp_lower >= (int)sizeof(indx_t));
mp->mp_lower += sizeof(indx_t); mp->mp_lower += sizeof(indx_t);
mp->mp_upper -= ksize - sizeof(indx_t); mdbx_cassert(mc, mp->mp_upper >= ksize - sizeof(indx_t));
mp->mp_upper -= (indx_t)(ksize - sizeof(indx_t));
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
@ -6807,7 +6830,7 @@ static int mdbx_node_add(MDBX_cursor *mc, indx_t indx, MDBX_val *key,
node_size += sizeof(pgno_t); node_size += sizeof(pgno_t);
} else if (unlikely(node_size + data->iov_len > } else if (unlikely(node_size + data->iov_len >
mc->mc_txn->mt_env->me_nodemax)) { mc->mc_txn->mt_env->me_nodemax)) {
unsigned ovpages = OVPAGES(mc->mc_txn->mt_env, data->iov_len); pgno_t ovpages = OVPAGES(mc->mc_txn->mt_env, data->iov_len);
int rc; int rc;
/* Put data on overflow page. */ /* Put data on overflow page. */
mdbx_debug("data size is %" PRIuPTR ", node would be %" PRIuPTR mdbx_debug("data size is %" PRIuPTR ", node would be %" PRIuPTR
@ -6835,8 +6858,9 @@ update:
mp->mp_ptrs[i] = mp->mp_ptrs[i - 1]; mp->mp_ptrs[i] = mp->mp_ptrs[i - 1];
/* Adjust free space offsets. */ /* Adjust free space offsets. */
ofs = mp->mp_upper - node_size; size_t ofs = mp->mp_upper - node_size;
mdbx_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t)); mdbx_cassert(mc, ofs >= mp->mp_lower + sizeof(indx_t));
mdbx_cassert(mc, ofs <= UINT16_MAX);
mp->mp_ptrs[indx] = (uint16_t)ofs; mp->mp_ptrs[indx] = (uint16_t)ofs;
mp->mp_upper = (uint16_t)ofs; mp->mp_upper = (uint16_t)ofs;
mp->mp_lower += sizeof(indx_t); mp->mp_lower += sizeof(indx_t);
@ -6888,10 +6912,9 @@ full:
* [in] mc Cursor pointing to the node to delete. * [in] mc Cursor pointing to the node to delete.
* [in] ksize The size of a node. Only used if the page is * [in] ksize The size of a node. Only used if the page is
* part of a MDBX_DUPFIXED database. */ * part of a MDBX_DUPFIXED database. */
static void mdbx_node_del(MDBX_cursor *mc, int ksize) { static void mdbx_node_del(MDBX_cursor *mc, size_t ksize) {
MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
indx_t indx = mc->mc_ki[mc->mc_top]; indx_t indx = mc->mc_ki[mc->mc_top];
unsigned sz;
indx_t i, j, numkeys, ptr; indx_t i, j, numkeys, ptr;
MDBX_node *node; MDBX_node *node;
char *base; char *base;
@ -6902,17 +6925,21 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) {
mdbx_cassert(mc, indx < numkeys); mdbx_cassert(mc, indx < numkeys);
if (IS_LEAF2(mp)) { if (IS_LEAF2(mp)) {
int x = numkeys - 1 - indx; mdbx_cassert(mc, ksize >= sizeof(indx_t));
unsigned diff = numkeys - 1 - indx;
base = LEAF2KEY(mp, indx, ksize); base = LEAF2KEY(mp, indx, ksize);
if (x) if (diff)
memmove(base, base + ksize, x * ksize); memmove(base, base + ksize, diff * ksize);
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
mp->mp_lower -= sizeof(indx_t); mp->mp_lower -= sizeof(indx_t);
mp->mp_upper += ksize - sizeof(indx_t); mdbx_cassert(mc,
(size_t)UINT16_MAX - mp->mp_upper >= ksize - sizeof(indx_t));
mp->mp_upper += (indx_t)(ksize - sizeof(indx_t));
return; return;
} }
node = NODEPTR(mp, indx); node = NODEPTR(mp, indx);
sz = NODESIZE + node->mn_ksize; size_t sz = NODESIZE + node->mn_ksize;
if (IS_LEAF(mp)) { if (IS_LEAF(mp)) {
if (F_ISSET(node->mn_flags, F_BIGDATA)) if (F_ISSET(node->mn_flags, F_BIGDATA))
sz += sizeof(pgno_t); sz += sizeof(pgno_t);
@ -6925,8 +6952,10 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) {
for (i = j = 0; i < numkeys; i++) { for (i = j = 0; i < numkeys; i++) {
if (i != indx) { if (i != indx) {
mp->mp_ptrs[j] = mp->mp_ptrs[i]; mp->mp_ptrs[j] = mp->mp_ptrs[i];
if (mp->mp_ptrs[i] < ptr) if (mp->mp_ptrs[i] < ptr) {
mp->mp_ptrs[j] += sz; mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_ptrs[j] >= sz);
mp->mp_ptrs[j] += (indx_t)sz;
}
j++; j++;
} }
} }
@ -6934,8 +6963,10 @@ static void mdbx_node_del(MDBX_cursor *mc, int ksize) {
base = (char *)mp + mp->mp_upper + PAGEHDRSZ; base = (char *)mp + mp->mp_upper + PAGEHDRSZ;
memmove(base + sz, base, ptr - mp->mp_upper); memmove(base + sz, base, ptr - mp->mp_upper);
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
mp->mp_lower -= sizeof(indx_t); mp->mp_lower -= sizeof(indx_t);
mp->mp_upper += sz; mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_upper >= sz);
mp->mp_upper += (indx_t)sz;
} }
/* Compact the main page after deleting a node on a subpage. /* Compact the main page after deleting a node on a subpage.
@ -6945,7 +6976,7 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) {
MDBX_node *node; MDBX_node *node;
MDBX_page *sp, *xp; MDBX_page *sp, *xp;
char *base; char *base;
unsigned nsize, delta, len, ptr; size_t nsize, delta, len, ptr;
int i; int i;
node = NODEPTR(mp, indx); node = NODEPTR(mp, indx);
@ -6960,8 +6991,10 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) {
return; /* do not make the node uneven-sized */ return; /* do not make the node uneven-sized */
} else { } else {
xp = (MDBX_page *)((char *)sp + delta); /* destination subpage */ xp = (MDBX_page *)((char *)sp + delta); /* destination subpage */
for (i = NUMKEYS(sp); --i >= 0;) for (i = NUMKEYS(sp); --i >= 0;) {
xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta; assert(sp->mp_ptrs[i] >= delta);
xp->mp_ptrs[i] = (indx_t)(sp->mp_ptrs[i] - delta);
}
len = PAGEHDRSZ; len = PAGEHDRSZ;
} }
sp->mp_upper = sp->mp_lower; sp->mp_upper = sp->mp_lower;
@ -6974,10 +7007,13 @@ static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) {
ptr = mp->mp_ptrs[indx]; ptr = mp->mp_ptrs[indx];
for (i = NUMKEYS(mp); --i >= 0;) { for (i = NUMKEYS(mp); --i >= 0;) {
if (mp->mp_ptrs[i] <= ptr) if (mp->mp_ptrs[i] <= ptr) {
mp->mp_ptrs[i] += delta; assert((size_t)UINT16_MAX - mp->mp_ptrs[i] >= delta);
mp->mp_ptrs[i] += (indx_t)delta;
}
} }
mp->mp_upper += delta; assert((size_t)UINT16_MAX - mp->mp_upper >= delta);
mp->mp_upper += (indx_t)delta;
} }
/* Initial setup of a sorted-dups cursor. /* Initial setup of a sorted-dups cursor.
@ -7049,7 +7085,7 @@ static void mdbx_xcursor_init1(MDBX_cursor *mc, MDBX_node *node) {
mdbx_debug("Sub-db -%u root page %" PRIaPGNO "", mx->mx_cursor.mc_dbi, mdbx_debug("Sub-db -%u root page %" PRIaPGNO "", mx->mx_cursor.mc_dbi,
mx->mx_db.md_root); mx->mx_db.md_root);
mx->mx_dbflag = DB_VALID | DB_USRVALID | DB_DUPDATA; mx->mx_dbflag = DB_VALID | DB_USRVALID | DB_DUPDATA;
/* #if UINT_MAX < SIZE_MAX /* FIXME: #if UINT_MAX < SIZE_MAX
if (mx->mx_dbx.md_cmp == mdbx_cmp_int && mx->mx_db.md_pad == if (mx->mx_dbx.md_cmp == mdbx_cmp_int && mx->mx_db.md_pad ==
sizeof(size_t)) sizeof(size_t))
mx->mx_dbx.md_cmp = mdbx_cmp_clong; mx->mx_dbx.md_cmp = mdbx_cmp_clong;
@ -7217,9 +7253,9 @@ int mdbx_cursor_count(MDBX_cursor *mc, size_t *countp) {
if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
mdbx_cassert(mc, mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & mdbx_cassert(mc, mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags &
C_INITIALIZED)); C_INITIALIZED));
*countp = unlikely(mc->mc_xcursor->mx_db.md_entries > INT_MAX) *countp = unlikely(mc->mc_xcursor->mx_db.md_entries > SIZE_MAX)
? INT_MAX ? SIZE_MAX
: mc->mc_xcursor->mx_db.md_entries; : (size_t)mc->mc_xcursor->mx_db.md_entries;
} }
} }
return MDBX_SUCCESS; return MDBX_SUCCESS;
@ -8079,21 +8115,19 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
pgno_t newpgno, unsigned nflags) { pgno_t newpgno, unsigned nflags) {
unsigned flags; unsigned flags;
int rc = MDBX_SUCCESS, new_root = 0, did_split = 0; int rc = MDBX_SUCCESS, new_root = 0, did_split = 0;
indx_t newindx;
pgno_t pgno = 0; pgno_t pgno = 0;
int i, j, split_indx, nkeys, pmax; unsigned i, ptop;
MDBX_env *env = mc->mc_txn->mt_env; MDBX_env *env = mc->mc_txn->mt_env;
MDBX_node *node; MDBX_node *node;
MDBX_val sepkey, rkey, xdata, *rdata = &xdata; MDBX_val sepkey, rkey, xdata, *rdata = &xdata;
MDBX_page *copy = NULL; MDBX_page *copy = NULL;
MDBX_page *mp, *rp, *pp; MDBX_page *rp, *pp;
int ptop;
MDBX_cursor mn; MDBX_cursor mn;
DKBUF; DKBUF;
mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
newindx = mc->mc_ki[mc->mc_top]; unsigned newindx = mc->mc_ki[mc->mc_top];
nkeys = NUMKEYS(mp); unsigned nkeys = NUMKEYS(mp);
mdbx_debug("-----> splitting %s page %" PRIaPGNO mdbx_debug("-----> splitting %s page %" PRIaPGNO
" and adding [%s] at index %i/%i", " and adding [%s] at index %i/%i",
@ -8147,6 +8181,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
mn.mc_pg[mn.mc_top] = rp; mn.mc_pg[mn.mc_top] = rp;
mn.mc_ki[ptop] = mc->mc_ki[ptop] + 1; mn.mc_ki[ptop] = mc->mc_ki[ptop] + 1;
unsigned split_indx;
if (nflags & MDBX_APPEND) { if (nflags & MDBX_APPEND) {
mn.mc_ki[mn.mc_top] = 0; mn.mc_ki[mn.mc_top] = 0;
sepkey = *newkey; sepkey = *newkey;
@ -8176,27 +8211,32 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
sepkey.iov_base = split; sepkey.iov_base = split;
} }
if (x < 0) { if (x < 0) {
mdbx_cassert(mc, ksize >= sizeof(indx_t));
ins = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], ksize); ins = LEAF2KEY(mp, mc->mc_ki[mc->mc_top], ksize);
memcpy(rp->mp_ptrs, split, rsize); memcpy(rp->mp_ptrs, split, rsize);
sepkey.iov_base = rp->mp_ptrs; sepkey.iov_base = rp->mp_ptrs;
memmove(ins + ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize); memmove(ins + ksize, ins, (split_indx - mc->mc_ki[mc->mc_top]) * ksize);
memcpy(ins, newkey->iov_base, ksize); memcpy(ins, newkey->iov_base, ksize);
mdbx_cassert(mc, UINT16_MAX - mp->mp_lower >= (int)sizeof(indx_t));
mp->mp_lower += sizeof(indx_t); mp->mp_lower += sizeof(indx_t);
mp->mp_upper -= ksize - sizeof(indx_t); mdbx_cassert(mc, mp->mp_upper >= ksize - sizeof(indx_t));
mp->mp_upper -= (indx_t)(ksize - sizeof(indx_t));
} else { } else {
if (x) if (x)
memcpy(rp->mp_ptrs, split, x * ksize); memcpy(rp->mp_ptrs, split, x * ksize);
ins = LEAF2KEY(rp, x, ksize); ins = LEAF2KEY(rp, x, ksize);
memcpy(ins, newkey->iov_base, ksize); memcpy(ins, newkey->iov_base, ksize);
memcpy(ins + ksize, split + x * ksize, rsize - x * ksize); memcpy(ins + ksize, split + x * ksize, rsize - x * ksize);
mdbx_cassert(mc, UINT16_MAX - rp->mp_lower >= (int)sizeof(indx_t));
rp->mp_lower += sizeof(indx_t); rp->mp_lower += sizeof(indx_t);
rp->mp_upper -= ksize - sizeof(indx_t); mdbx_cassert(mc, rp->mp_upper >= ksize - sizeof(indx_t));
rp->mp_upper -= (indx_t)(ksize - sizeof(indx_t));
mc->mc_ki[mc->mc_top] = x; mc->mc_ki[mc->mc_top] = x;
} }
} else { } else {
int psize, nsize, k; size_t psize, nsize, k;
/* Maximum free space in an empty page */ /* Maximum free space in an empty page */
pmax = env->me_psize - PAGEHDRSZ; unsigned pmax = env->me_psize - PAGEHDRSZ;
if (IS_LEAF(mp)) if (IS_LEAF(mp))
nsize = mdbx_leaf_size(env, newkey, newdata); nsize = mdbx_leaf_size(env, newkey, newdata);
else else
@ -8215,10 +8255,9 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
copy->mp_upper = env->me_psize - PAGEHDRSZ; copy->mp_upper = env->me_psize - PAGEHDRSZ;
/* prepare to insert */ /* prepare to insert */
for (i = 0, j = 0; i < nkeys; i++) { for (unsigned j = i = 0; i < nkeys; i++) {
if (i == newindx) { if (i == newindx)
copy->mp_ptrs[j++] = 0; copy->mp_ptrs[j++] = 0;
}
copy->mp_ptrs[j++] = mp->mp_ptrs[i]; copy->mp_ptrs[j++] = mp->mp_ptrs[i];
} }
@ -8237,19 +8276,20 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
* the split so the new page is emptier than the old page. * the split so the new page is emptier than the old page.
* This yields better packing during sequential inserts. * This yields better packing during sequential inserts.
*/ */
int dir;
if (nkeys < 20 || nsize > pmax / 16 || newindx >= nkeys) { if (nkeys < 20 || nsize > pmax / 16 || newindx >= nkeys) {
/* Find split point */ /* Find split point */
psize = 0; psize = 0;
if (newindx <= split_indx || newindx >= nkeys) { if (newindx <= split_indx || newindx >= nkeys) {
i = 0; i = 0;
j = 1; dir = 1;
k = newindx >= nkeys ? nkeys : split_indx + 1 + IS_LEAF(mp); k = (newindx >= nkeys) ? nkeys : split_indx + 1 + IS_LEAF(mp);
} else { } else {
i = nkeys; i = nkeys;
j = -1; dir = -1;
k = split_indx - 1; k = split_indx - 1;
} }
for (; i != k; i += j) { for (; i != k; i += dir) {
if (i == newindx) { if (i == newindx) {
psize += nsize; psize += nsize;
node = NULL; node = NULL;
@ -8264,8 +8304,8 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
} }
psize = EVEN(psize); psize = EVEN(psize);
} }
if (psize > pmax || i == k - j) { if (psize > pmax || i == k - dir) {
split_indx = i + (j < 0); split_indx = i + (dir < 0);
break; break;
} }
} }
@ -8297,9 +8337,9 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
goto done; goto done;
/* root split? */ /* root split? */
if (mc->mc_snum > snum) { if (mc->mc_snum > snum)
ptop++; ptop++;
}
/* Right page might now have changed parent. /* Right page might now have changed parent.
* Check if left page also changed parent. */ * Check if left page also changed parent. */
if (mn.mc_pg[ptop] != mc->mc_pg[ptop] && if (mn.mc_pg[ptop] != mc->mc_pg[ptop] &&
@ -8341,7 +8381,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
/* Move nodes */ /* Move nodes */
mc->mc_pg[mc->mc_top] = rp; mc->mc_pg[mc->mc_top] = rp;
i = split_indx; i = split_indx;
j = 0; indx_t n = 0;
do { do {
if (i == newindx) { if (i == newindx) {
rkey.iov_base = newkey->iov_base; rkey.iov_base = newkey->iov_base;
@ -8352,7 +8392,7 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
pgno = newpgno; pgno = newpgno;
flags = nflags; flags = nflags;
/* Update index for the new key. */ /* Update index for the new key. */
mc->mc_ki[mc->mc_top] = j; mc->mc_ki[mc->mc_top] = n;
} else { } else {
node = (MDBX_node *)((char *)mp + copy->mp_ptrs[i] + PAGEHDRSZ); node = (MDBX_node *)((char *)mp + copy->mp_ptrs[i] + PAGEHDRSZ);
rkey.iov_base = NODEKEY(node); rkey.iov_base = NODEKEY(node);
@ -8366,21 +8406,21 @@ static int mdbx_page_split(MDBX_cursor *mc, MDBX_val *newkey, MDBX_val *newdata,
flags = node->mn_flags; flags = node->mn_flags;
} }
if (!IS_LEAF(mp) && j == 0) { if (!IS_LEAF(mp) && n == 0) {
/* First branch index doesn't need key data. */ /* First branch index doesn't need key data. */
rkey.iov_len = 0; rkey.iov_len = 0;
} }
rc = mdbx_node_add(mc, j, &rkey, rdata, pgno, flags); rc = mdbx_node_add(mc, n, &rkey, rdata, pgno, flags);
if (rc) if (rc)
goto done; goto done;
if (i == nkeys) { if (i == nkeys) {
i = 0; i = 0;
j = 0; n = 0;
mc->mc_pg[mc->mc_top] = copy; mc->mc_pg[mc->mc_top] = copy;
} else { } else {
i++; i++;
j++; n++;
} }
} while (i != split_indx); } while (i != split_indx);
@ -8552,8 +8592,8 @@ typedef struct mdbx_copy {
mdbx_condmutex_t mc_condmutex; mdbx_condmutex_t mc_condmutex;
char *mc_wbuf[2]; char *mc_wbuf[2];
char *mc_over[2]; char *mc_over[2];
int mc_wlen[2]; size_t mc_wlen[2];
int mc_olen[2]; size_t mc_olen[2];
pgno_t mc_next_pgno; pgno_t mc_next_pgno;
mdbx_filehandle_t mc_fd; mdbx_filehandle_t mc_fd;
int mc_toggle; /* Buffer number in provider */ int mc_toggle; /* Buffer number in provider */
@ -8567,7 +8607,7 @@ typedef struct mdbx_copy {
static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) { static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
mdbx_copy *my = arg; mdbx_copy *my = arg;
char *ptr; char *ptr;
int toggle = 0, wsize; int toggle = 0;
int rc; int rc;
#if defined(F_SETNOSIGPIPE) #if defined(F_SETNOSIGPIPE)
@ -8593,7 +8633,7 @@ static THREAD_RESULT __cold THREAD_CALL mdbx_env_copythr(void *arg) {
mdbx_condmutex_wait(&my->mc_condmutex); mdbx_condmutex_wait(&my->mc_condmutex);
if (my->mc_new == 0 + MDBX_EOF) /* 0 buffers, just EOF */ if (my->mc_new == 0 + MDBX_EOF) /* 0 buffers, just EOF */
break; break;
wsize = my->mc_wlen[toggle]; size_t wsize = my->mc_wlen[toggle];
ptr = my->mc_wbuf[toggle]; ptr = my->mc_wbuf[toggle];
again: again:
if (wsize > 0 && !my->mc_error) { if (wsize > 0 && !my->mc_error) {
@ -8942,14 +8982,13 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
} }
int __cold mdbx_env_copy(MDBX_env *env, const char *path, unsigned flags) { int __cold mdbx_env_copy(MDBX_env *env, const char *path, unsigned flags) {
int rc, len;
char *lck_pathname; char *lck_pathname;
mdbx_filehandle_t newfd = INVALID_HANDLE_VALUE; mdbx_filehandle_t newfd = INVALID_HANDLE_VALUE;
if (env->me_flags & MDBX_NOSUBDIR) { if (env->me_flags & MDBX_NOSUBDIR) {
lck_pathname = (char *)path; lck_pathname = (char *)path;
} else { } else {
len = strlen(path); size_t len = strlen(path);
len += sizeof(MDBX_DATANAME); len += sizeof(MDBX_DATANAME);
lck_pathname = malloc(len); lck_pathname = malloc(len);
if (!lck_pathname) if (!lck_pathname)
@ -8960,7 +8999,8 @@ int __cold mdbx_env_copy(MDBX_env *env, const char *path, unsigned flags) {
/* The destination path must exist, but the destination file must not. /* The destination path must exist, but the destination file must not.
* We don't want the OS to cache the writes, since the source data is * We don't want the OS to cache the writes, since the source data is
* already in the OS cache. */ * already in the OS cache. */
rc = mdbx_openfile(lck_pathname, O_WRONLY | O_CREAT | O_EXCL, 0666, &newfd); int rc =
mdbx_openfile(lck_pathname, O_WRONLY | O_CREAT | O_EXCL, 0666, &newfd);
if (rc == MDBX_SUCCESS) { if (rc == MDBX_SUCCESS) {
if (env->me_psize >= env->me_os_psize) { if (env->me_psize >= env->me_os_psize) {
#ifdef F_NOCACHE /* __APPLE__ */ #ifdef F_NOCACHE /* __APPLE__ */
@ -9761,7 +9801,9 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) {
if (oldest < snap || reader < 0) { if (oldest < snap || reader < 0) {
if (retry && env->me_oom_func) { if (retry && env->me_oom_func) {
/* LY: notify end of oom-loop */ /* LY: notify end of oom-loop */
env->me_oom_func(env, 0, 0, oldest, snap - oldest, -retry); const txnid_t gap = snap - oldest;
env->me_oom_func(env, 0, 0, oldest,
(gap < UINT_MAX) ? (unsigned)gap : UINT_MAX, -retry);
} }
return snap; return snap;
} }
@ -9780,9 +9822,10 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) {
if (r->mr_txnid != oldest || pid <= 0) if (r->mr_txnid != oldest || pid <= 0)
continue; continue;
rc = env->me_oom_func( const txnid_t gap =
env, pid, tid, oldest, mdbx_meta_txnid_stable(env, mdbx_meta_head(env)) - oldest;
mdbx_meta_txnid_stable(env, mdbx_meta_head(env)) - oldest, retry); rc = env->me_oom_func(env, pid, tid, oldest,
(gap < UINT_MAX) ? (unsigned)gap : UINT_MAX, retry);
if (rc < 0) if (rc < 0)
break; break;
@ -9849,11 +9892,11 @@ int mdbx_txn_straggler(MDBX_txn *txn, int *percent)
MDBX_env *env = txn->mt_env; MDBX_env *env = txn->mt_env;
MDBX_meta *meta = mdbx_meta_head(env); MDBX_meta *meta = mdbx_meta_head(env);
if (percent) { if (percent) {
size_t maxpg = env->me_maxpg; pgno_t maxpg = env->me_maxpg;
size_t last = meta->mm_last_pg + 1; pgno_t last = meta->mm_last_pg + 1;
if (env->me_txn) if (env->me_txn)
last = env->me_txn0->mt_next_pgno; last = env->me_txn0->mt_next_pgno;
*percent = (last * 100ull + maxpg / 2) / maxpg; *percent = (int)((last * UINT64_C(100) + maxpg / 2) / maxpg);
} }
txnid_t lag = mdbx_meta_txnid_fluid(env, meta) - txn->mt_ro_reader->mr_txnid; txnid_t lag = mdbx_meta_txnid_fluid(env, meta) - txn->mt_ro_reader->mr_txnid;
return (lag > INT_MAX) ? INT_MAX : (int)lag; return (lag > INT_MAX) ? INT_MAX : (int)lag;
@ -9870,7 +9913,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
pgno_t pg, int deep) { pgno_t pg, int deep) {
MDBX_page *mp; MDBX_page *mp;
int rc, i, nkeys; int rc, i, nkeys;
unsigned header_size, unused_size, payload_size, align_bytes; size_t header_size, unused_size, payload_size, align_bytes;
const char *type; const char *type;
if (pg == P_INVALID) if (pg == P_INVALID)
@ -10278,7 +10321,7 @@ bailout:
} }
int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data,
int *values_count) { size_t *values_count) {
DKBUF; DKBUF;
mdbx_debug("===> get db %u key [%s]", dbi, DKEY(key)); mdbx_debug("===> get db %u key [%s]", dbi, DKEY(key));
@ -10313,7 +10356,10 @@ int mdbx_get_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data,
if (F_ISSET(leaf->mn_flags, F_DUPDATA)) { if (F_ISSET(leaf->mn_flags, F_DUPDATA)) {
mdbx_tassert(txn, mc.mc_xcursor == &mx && mdbx_tassert(txn, mc.mc_xcursor == &mx &&
(mx.mx_cursor.mc_flags & C_INITIALIZED)); (mx.mx_cursor.mc_flags & C_INITIALIZED));
*values_count = mx.mx_db.md_entries; *values_count = (sizeof(*values_count) >= sizeof(mx.mx_db.md_entries) ||
mx.mx_db.md_entries <= SIZE_MAX)
? (size_t)mx.mx_db.md_entries
: SIZE_MAX;
} }
} }
} }

View File

@ -224,8 +224,9 @@ static uint64_t problems_pop(struct problem *list) {
} }
static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx,
const char *dbi, const char *type, int nentries, const char *dbi, const char *type, size_t nentries,
int payload_bytes, int header_bytes, int unused_bytes) { size_t payload_bytes, size_t header_bytes,
size_t unused_bytes) {
(void)ctx; (void)ctx;
if (type) { if (type) {
@ -240,13 +241,14 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx,
print(" %s-page %" PRIu64, type, pgno); print(" %s-page %" PRIu64, type, pgno);
else else
print(" %s-span %" PRIu64 "[%u]", type, pgno, pgnumber); print(" %s-span %" PRIu64 "[%u]", type, pgno, pgnumber);
print(" of %s: header %i, payload %i, unused %i\n", dbi, header_bytes, print(" of %s: header %" PRIiPTR ", payload %" PRIiPTR
payload_bytes, unused_bytes); ", unused %" PRIiPTR "\n",
dbi, header_bytes, payload_bytes, unused_bytes);
} }
walk.pgcount += pgnumber; walk.pgcount += pgnumber;
if (unused_bytes < 0 || (size_t)unused_bytes > page_size) if (unused_bytes > page_size)
problem_add("page", pgno, "illegal unused-bytes", "%u < %i < %u", 0, problem_add("page", pgno, "illegal unused-bytes", "%u < %i < %u", 0,
unused_bytes, envstat.ms_psize); unused_bytes, envstat.ms_psize);

View File

@ -163,9 +163,7 @@ uint64_t entropy_ticks(void) {
#elif defined(_M_IX86) || defined(_M_X64) #elif defined(_M_IX86) || defined(_M_X64)
return __rdtsc(); return __rdtsc();
#endif /* __GNUC__ || __clang__ */ #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
LARGE_INTEGER PerformanceCount; LARGE_INTEGER PerformanceCount;
if (QueryPerformanceCounter(&PerformanceCount)) if (QueryPerformanceCounter(&PerformanceCount))
return PerformanceCount.QuadPart; return PerformanceCount.QuadPart;