mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 01:34:14 +08:00
mdbx: устранение всех предупреждений статического анализатора MSVC (все несущественные или ложные).
This commit is contained in:
parent
7f5ea6d3b8
commit
25e958f081
17
src/base.h
17
src/base.h
@ -669,6 +669,23 @@ __extern_C key_t ftok(const char *, int);
|
||||
#endif
|
||||
#endif /* MDBX_WEAK_IMPORT_ATTRIBUTE */
|
||||
|
||||
#ifndef MDBX_GOOFY_MSVC_STATIC_ANALYZER
|
||||
#ifdef _PREFAST_
|
||||
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 1
|
||||
#else
|
||||
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 0
|
||||
#endif
|
||||
#endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */
|
||||
|
||||
#if MDBX_GOOFY_MSVC_STATIC_ANALYZER
|
||||
#define MDBX_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
|
||||
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id, note) \
|
||||
_Pragma(MDBX_STRINGIFY(prefast(suppress : warn_id)))
|
||||
#else
|
||||
#define MDBX_ANALYSIS_ASSUME(expr) assert(expr)
|
||||
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id, note)
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(MDBX_USE_VALGRIND)
|
||||
|
168
src/core.c
168
src/core.c
@ -1529,7 +1529,7 @@ __cold int rthc_alloc(osal_thread_key_t *pkey, MDBX_reader *begin,
|
||||
goto bailout;
|
||||
}
|
||||
if (rthc_table == rthc_table_static)
|
||||
memcpy(new_table, rthc_table_static, sizeof(rthc_table_static));
|
||||
memcpy(new_table, rthc_table, sizeof(rthc_entry_t) * rthc_limit);
|
||||
rthc_table = new_table;
|
||||
rthc_limit *= 2;
|
||||
}
|
||||
@ -2250,8 +2250,8 @@ static MDBX_PNL pnl_alloc(size_t size) {
|
||||
#endif /* malloc_usable_size */
|
||||
pl[0] = pnl_bytes2size(bytes);
|
||||
assert(pl[0] >= size);
|
||||
pl[1] = 0;
|
||||
pl += 1;
|
||||
*pl = 0;
|
||||
}
|
||||
return pl;
|
||||
}
|
||||
@ -2435,7 +2435,7 @@ pnl_merge_inner(pgno_t *__restrict dst, const pgno_t *__restrict src_a,
|
||||
// clang<=5: cmov×2, set+add/sub
|
||||
// clang>=6: cmov, set+add/sub
|
||||
*dst = flag ? *src_a : *src_b;
|
||||
src_b += flag - 1;
|
||||
src_b += (ptrdiff_t)flag - 1;
|
||||
src_a -= flag;
|
||||
#endif
|
||||
--dst;
|
||||
@ -2593,7 +2593,7 @@ static __inline size_t search_spilled(const MDBX_txn *txn, pgno_t pgno) {
|
||||
if (likely(!pnl))
|
||||
return 0;
|
||||
pgno <<= 1;
|
||||
size_t n = pnl_search(pnl, pgno, (size_t)(MAX_PAGENO + 1) << 1);
|
||||
size_t n = pnl_search(pnl, pgno, (size_t)MAX_PAGENO + MAX_PAGENO + 1);
|
||||
return (n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] == pgno) ? n : 0;
|
||||
}
|
||||
|
||||
@ -2620,7 +2620,7 @@ static __inline bool intersect_spilled(const MDBX_txn *txn, pgno_t pgno,
|
||||
const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] <= spilled_range_last;
|
||||
#else
|
||||
const size_t n =
|
||||
pnl_search(pnl, spilled_range_last, (size_t)(MAX_PAGENO + 1) << 1);
|
||||
pnl_search(pnl, spilled_range_last, (size_t)MAX_PAGENO + MAX_PAGENO + 1);
|
||||
assert(n && (n == MDBX_PNL_GETSIZE(pnl) + 1 || spilled_range_last >= pnl[n]));
|
||||
const bool rc = n <= MDBX_PNL_GETSIZE(pnl) && pnl[n] >= spilled_range_begin;
|
||||
#endif
|
||||
@ -2659,8 +2659,8 @@ static MDBX_TXL txl_alloc(void) {
|
||||
#endif /* malloc_usable_size */
|
||||
tl[0] = txl_bytes2size(bytes);
|
||||
assert(tl[0] >= MDBX_TXL_INITIAL);
|
||||
tl[1] = 0;
|
||||
tl += 1;
|
||||
*tl = 0;
|
||||
}
|
||||
return tl;
|
||||
}
|
||||
@ -2884,7 +2884,7 @@ __hot __noinline static MDBX_dpl *dpl_sort_slowpath(const MDBX_txn *txn) {
|
||||
#else
|
||||
*w = cmp ? *l : *r;
|
||||
l -= cmp;
|
||||
r += cmp - 1;
|
||||
r += (ptrdiff_t)cmp - 1;
|
||||
#endif
|
||||
} while (likely(--w > l));
|
||||
assert(r == tmp - 1);
|
||||
@ -4886,7 +4886,7 @@ spill_prio(const MDBX_txn *txn, const size_t i, const uint32_t reciprocal) {
|
||||
factor |= factor >> 4;
|
||||
factor |= factor >> 8;
|
||||
factor |= factor >> 16;
|
||||
factor = prio * log2n_powerof2(factor + 1) + /* golden ratio */ 157;
|
||||
factor = (size_t)prio * log2n_powerof2(factor + 1) + /* golden ratio */ 157;
|
||||
factor = (factor < 256) ? 255 - factor : 0;
|
||||
tASSERT(txn, factor < 256 && factor < (256 - prio));
|
||||
return prio = (unsigned)factor;
|
||||
@ -5007,6 +5007,7 @@ __cold static int txn_spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0,
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto bailout;
|
||||
#if MDBX_AVOID_MSYNC
|
||||
MDBX_ANALYSIS_ASSUME(txn->tw.dirtylist != nullptr);
|
||||
tASSERT(txn, dirtylist_check(txn));
|
||||
env->me_lck->mti_unsynced_pages.weak +=
|
||||
txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count;
|
||||
@ -5032,6 +5033,7 @@ __cold static int txn_spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0,
|
||||
|
||||
NOTICE("%s-spilling %zu dirty-entries, %zu dirty-npages", "write",
|
||||
need_spill_entries, need_spill_npages);
|
||||
MDBX_ANALYSIS_ASSUME(txn->tw.dirtylist != nullptr);
|
||||
tASSERT(txn, txn->tw.dirtylist->length - txn->tw.loose_count >= 1);
|
||||
tASSERT(txn, txn->tw.dirtylist->pages_including_loose - txn->tw.loose_count >=
|
||||
need_spill_npages);
|
||||
@ -5549,6 +5551,7 @@ meta_prefer_steady(const MDBX_env *env, const meta_troika_t *troika) {
|
||||
static __always_inline meta_ptr_t meta_tail(const MDBX_env *env,
|
||||
const meta_troika_t *troika) {
|
||||
const uint8_t tail = troika->tail_and_flags & 3;
|
||||
MDBX_ANALYSIS_ASSUME(tail < NUM_METAS);
|
||||
meta_ptr_t r;
|
||||
r.txnid = troika->txnid[tail];
|
||||
r.ptr_v = METAPAGE(env, tail);
|
||||
@ -5998,7 +6001,7 @@ static void adjust_defaults(MDBX_env *env) {
|
||||
const size_t basis = env->me_dbgeo.now;
|
||||
/* TODO: use options? */
|
||||
const unsigned factor = 9;
|
||||
size_t threshold = (basis < (65536ul << factor))
|
||||
size_t threshold = (basis < ((size_t)65536 << factor))
|
||||
? 65536 /* minimal threshold */
|
||||
: (basis > (MEGABYTE * 4 << factor))
|
||||
? MEGABYTE * 4 /* maximal threshold */
|
||||
@ -8300,22 +8303,24 @@ static int cursor_shadow(MDBX_txn *parent, MDBX_txn *nested) {
|
||||
static void cursors_eot(MDBX_txn *txn, const bool merge) {
|
||||
tASSERT(txn, txn->mt_cursors[FREE_DBI] == nullptr);
|
||||
for (intptr_t i = txn->mt_numdbs; --i > FREE_DBI;) {
|
||||
MDBX_cursor *next, *mc = txn->mt_cursors[i];
|
||||
MDBX_cursor *mc = txn->mt_cursors[i];
|
||||
if (!mc)
|
||||
continue;
|
||||
txn->mt_cursors[i] = NULL;
|
||||
txn->mt_cursors[i] = nullptr;
|
||||
do {
|
||||
const unsigned stage = mc->mc_signature;
|
||||
MDBX_cursor *bk = mc->mc_backup;
|
||||
next = mc->mc_next;
|
||||
MDBX_cursor *const next = mc->mc_next;
|
||||
MDBX_cursor *const bk = mc->mc_backup;
|
||||
ENSURE(txn->mt_env,
|
||||
stage == MDBX_MC_LIVE || (stage == MDBX_MC_WAIT4EOT && bk));
|
||||
cASSERT(mc, mc->mc_dbi == (MDBX_dbi)i);
|
||||
if (bk) {
|
||||
MDBX_xcursor *mx = mc->mc_xcursor;
|
||||
cASSERT(mc, mx == bk->mc_xcursor);
|
||||
tASSERT(txn, txn->mt_parent != NULL);
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6001, "Using uninitialized memory '*mc->mc_backup'.");
|
||||
ENSURE(txn->mt_env, bk->mc_signature == MDBX_MC_LIVE);
|
||||
tASSERT(txn, mx == bk->mc_xcursor);
|
||||
if (stage == MDBX_MC_WAIT4EOT /* Cursor was closed by user */)
|
||||
mc->mc_signature = stage /* Promote closed state to parent txn */;
|
||||
else if (merge) {
|
||||
@ -8345,7 +8350,8 @@ static void cursors_eot(MDBX_txn *txn, const bool merge) {
|
||||
mc->mc_signature = MDBX_MC_READY4CLOSE /* Cursor may be reused */;
|
||||
mc->mc_flags = 0 /* reset C_UNTRACK */;
|
||||
}
|
||||
} while ((mc = next) != NULL);
|
||||
mc = next;
|
||||
} while (mc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9187,9 +9193,6 @@ void *mdbx_txn_get_userctx(const MDBX_txn *txn) {
|
||||
|
||||
int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
|
||||
MDBX_txn **ret, void *context) {
|
||||
MDBX_txn *txn;
|
||||
size_t size, tsize;
|
||||
|
||||
if (unlikely(!ret))
|
||||
return MDBX_EINVAL;
|
||||
*ret = NULL;
|
||||
@ -9208,6 +9211,7 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
|
||||
|
||||
flags |= env->me_flags & MDBX_WRITEMAP;
|
||||
|
||||
MDBX_txn *txn = nullptr;
|
||||
if (parent) {
|
||||
/* Nested transactions: Max 1 child, write txns only, no writemap */
|
||||
rc = check_txn_rw(parent,
|
||||
@ -9238,9 +9242,13 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
|
||||
goto renew;
|
||||
}
|
||||
|
||||
size = env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1);
|
||||
size += tsize = sizeof(MDBX_txn);
|
||||
if (unlikely((txn = osal_malloc(size)) == NULL)) {
|
||||
const size_t base = (flags & MDBX_TXN_RDONLY)
|
||||
? sizeof(MDBX_txn) - sizeof(txn->tw) + sizeof(txn->to)
|
||||
: sizeof(MDBX_txn);
|
||||
const size_t size =
|
||||
base + env->me_maxdbs * (sizeof(MDBX_db) + sizeof(MDBX_cursor *) + 1);
|
||||
txn = osal_malloc(size);
|
||||
if (unlikely(txn == nullptr)) {
|
||||
DEBUG("calloc: %s", "failed");
|
||||
return MDBX_ENOMEM;
|
||||
}
|
||||
@ -9248,11 +9256,13 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
|
||||
memset(txn, 0xCD, size);
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(txn, size);
|
||||
#endif /* MDBX_DEBUG */
|
||||
memset(txn, 0, tsize);
|
||||
txn->mt_dbxs = env->me_dbxs; /* static */
|
||||
txn->mt_dbs = ptr_disp(txn, tsize);
|
||||
MDBX_ANALYSIS_ASSUME(size > base);
|
||||
memset(txn, 0,
|
||||
(MDBX_GOOFY_MSVC_STATIC_ANALYZER && base > size) ? size : base);
|
||||
txn->mt_dbs = ptr_disp(txn, base);
|
||||
txn->mt_cursors = ptr_disp(txn->mt_dbs, sizeof(MDBX_db) * env->me_maxdbs);
|
||||
txn->mt_dbistate = ptr_disp(txn, size - env->me_maxdbs);
|
||||
txn->mt_dbxs = env->me_dbxs; /* static */
|
||||
txn->mt_flags = flags;
|
||||
txn->mt_env = env;
|
||||
|
||||
@ -9987,8 +9997,9 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
|
||||
txn->mt_dbistate[i] |= DBI_AUDITED;
|
||||
if (txn->mt_dbs[i].md_root == P_INVALID)
|
||||
continue;
|
||||
used += txn->mt_dbs[i].md_branch_pages + txn->mt_dbs[i].md_leaf_pages +
|
||||
txn->mt_dbs[i].md_overflow_pages;
|
||||
used += (size_t)txn->mt_dbs[i].md_branch_pages +
|
||||
(size_t)txn->mt_dbs[i].md_leaf_pages +
|
||||
(size_t)txn->mt_dbs[i].md_overflow_pages;
|
||||
|
||||
if (i != MAIN_DBI)
|
||||
continue;
|
||||
@ -10016,8 +10027,8 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
|
||||
}
|
||||
}
|
||||
}
|
||||
used +=
|
||||
db->md_branch_pages + db->md_leaf_pages + db->md_overflow_pages;
|
||||
used += (size_t)db->md_branch_pages + (size_t)db->md_leaf_pages +
|
||||
(size_t)db->md_overflow_pages;
|
||||
}
|
||||
}
|
||||
rc = cursor_sibling(&cx.outer, SIBLING_RIGHT);
|
||||
@ -10031,11 +10042,13 @@ __cold static int audit_ex(MDBX_txn *txn, size_t retired_stored,
|
||||
continue;
|
||||
for (MDBX_txn *t = txn; t; t = t->mt_parent)
|
||||
if (F_ISSET(t->mt_dbistate[i], DBI_DIRTY | DBI_CREAT)) {
|
||||
used += t->mt_dbs[i].md_branch_pages + t->mt_dbs[i].md_leaf_pages +
|
||||
t->mt_dbs[i].md_overflow_pages;
|
||||
used += (size_t)t->mt_dbs[i].md_branch_pages +
|
||||
(size_t)t->mt_dbs[i].md_leaf_pages +
|
||||
(size_t)t->mt_dbs[i].md_overflow_pages;
|
||||
txn->mt_dbistate[i] |= DBI_AUDITED;
|
||||
break;
|
||||
}
|
||||
MDBX_ANALYSIS_ASSUME(txn != nullptr);
|
||||
if (!(txn->mt_dbistate[i] & DBI_AUDITED)) {
|
||||
WARNING("audit %s@%" PRIaTXN
|
||||
": unable account dbi %zd / \"%*s\", state 0x%02x",
|
||||
@ -10787,8 +10800,9 @@ retry:
|
||||
: INT16_MAX;
|
||||
if (avail_gc_slots > 1) {
|
||||
#if MDBX_ENABLE_BIGFOOT
|
||||
chunk = (chunk < env->me_maxgc_ov1page * 2) ? chunk / 2
|
||||
: env->me_maxgc_ov1page;
|
||||
chunk = (chunk < env->me_maxgc_ov1page * (size_t)2)
|
||||
? chunk / 2
|
||||
: env->me_maxgc_ov1page;
|
||||
#else
|
||||
if (chunk < env->me_maxgc_ov1page * 2)
|
||||
chunk /= 2;
|
||||
@ -12641,8 +12655,9 @@ static int sync_locked(MDBX_env *env, unsigned flags, MDBX_meta *const pending,
|
||||
? /* grow_step */ pv2pages(pending->mm_geo.grow_pv)
|
||||
: shrink_step;
|
||||
const pgno_t with_backlog_gap = largest_pgno + backlog_gap;
|
||||
const pgno_t aligned = pgno_align2os_pgno(
|
||||
env, with_backlog_gap + aligner - with_backlog_gap % aligner);
|
||||
const pgno_t aligned =
|
||||
pgno_align2os_pgno(env, (size_t)with_backlog_gap + aligner -
|
||||
with_backlog_gap % aligner);
|
||||
const pgno_t bottom = (aligned > pending->mm_geo.lower)
|
||||
? aligned
|
||||
: pending->mm_geo.lower;
|
||||
@ -13566,10 +13581,10 @@ __cold int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) {
|
||||
#endif /* LIBMDBX_NO_EXPORTS_LEGACY_API */
|
||||
|
||||
__cold static int alloc_page_buf(MDBX_env *env) {
|
||||
return env->me_pbuf
|
||||
? MDBX_SUCCESS
|
||||
: osal_memalign_alloc(env->me_os_psize, env->me_psize * NUM_METAS,
|
||||
&env->me_pbuf);
|
||||
return env->me_pbuf ? MDBX_SUCCESS
|
||||
: osal_memalign_alloc(env->me_os_psize,
|
||||
env->me_psize * (size_t)NUM_METAS,
|
||||
&env->me_pbuf);
|
||||
}
|
||||
|
||||
/* Further setup required for opening an MDBX environment */
|
||||
@ -13599,8 +13614,8 @@ __cold static int setup_dxb(MDBX_env *env, const int lck_rc,
|
||||
return err;
|
||||
|
||||
header = *init_metas(env, env->me_pbuf);
|
||||
err = osal_pwrite(env->me_lazy_fd, env->me_pbuf, env->me_psize * NUM_METAS,
|
||||
0);
|
||||
err = osal_pwrite(env->me_lazy_fd, env->me_pbuf,
|
||||
env->me_psize * (size_t)NUM_METAS, 0);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
|
||||
@ -14640,7 +14655,8 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
pathchar_t *const buf = ctx->buffer_for_free;
|
||||
rc = MDBX_SUCCESS;
|
||||
if (ctx->ent_len) {
|
||||
memcpy(buf, pathname, sizeof(pathchar_t) * pathname_len);
|
||||
memcpy(buf + /* shutting up goofy MSVC static analyzer */ 0, pathname,
|
||||
sizeof(pathchar_t) * pathname_len);
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
const pathchar_t *const lck_ext =
|
||||
osal_fileext(lck_name, ARRAY_LENGTH(lck_name));
|
||||
@ -14657,7 +14673,8 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
rc = check_alternative_lck_absent(buf);
|
||||
}
|
||||
|
||||
memcpy(ctx->dxb, pathname, sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||
memcpy(ctx->dxb + /* shutting up goofy MSVC static analyzer */ 0, pathname,
|
||||
sizeof(pathchar_t) * (ctx->ent_len + 1));
|
||||
memcpy(ctx->lck, pathname, sizeof(pathchar_t) * ctx->ent_len);
|
||||
if (*flags & MDBX_NOSUBDIR) {
|
||||
memcpy(ctx->lck + ctx->ent_len, lock_suffix, sizeof(lock_suffix));
|
||||
@ -14667,11 +14684,13 @@ __cold static int handle_env_pathname(MDBX_handle_env_pathname *ctx,
|
||||
}
|
||||
} else {
|
||||
assert(!(*flags & MDBX_NOSUBDIR));
|
||||
memcpy(buf, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(buf + /* shutting up goofy MSVC static analyzer */ 0, dxb_name + 1,
|
||||
sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(buf + dxb_name_len - 1, lock_suffix, sizeof(lock_suffix));
|
||||
rc = check_alternative_lck_absent(buf);
|
||||
|
||||
memcpy(ctx->dxb, dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(ctx->dxb + /* shutting up goofy MSVC static analyzer */ 0,
|
||||
dxb_name + 1, sizeof(dxb_name) - sizeof(pathchar_t));
|
||||
memcpy(ctx->lck, lck_name + 1, sizeof(lck_name) - sizeof(pathchar_t));
|
||||
}
|
||||
return rc;
|
||||
@ -15187,8 +15206,9 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
sizeof(MDBX_atomic_uint32_t) + 1);
|
||||
rc = alloc_page_buf(env);
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
memset(env->me_pbuf, -1, env->me_psize * 2);
|
||||
memset(ptr_disp(env->me_pbuf, env->me_psize * 2), 0, env->me_psize);
|
||||
memset(env->me_pbuf, -1, env->me_psize * (size_t)2);
|
||||
memset(ptr_disp(env->me_pbuf, env->me_psize * (size_t)2), 0,
|
||||
env->me_psize);
|
||||
MDBX_txn *txn = osal_calloc(1, size);
|
||||
if (txn) {
|
||||
txn->mt_dbs = ptr_disp(txn, tsize);
|
||||
@ -15735,7 +15755,7 @@ __hot __noinline static int page_search_root(MDBX_cursor *mc,
|
||||
} else {
|
||||
const struct node_result nsr = node_search(mc, key);
|
||||
if (likely(nsr.node))
|
||||
i = mc->mc_ki[mc->mc_top] + nsr.exact - 1;
|
||||
i = mc->mc_ki[mc->mc_top] + (intptr_t)nsr.exact - 1;
|
||||
else
|
||||
i = page_numkeys(mp) - 1;
|
||||
DEBUG("following index %zu for key [%s]", i, DKEY_DEBUG(key));
|
||||
@ -16137,9 +16157,9 @@ static int cursor_sibling(MDBX_cursor *mc, int dir) {
|
||||
DEBUG("parent page is page %" PRIaPGNO ", index %u",
|
||||
mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top]);
|
||||
|
||||
if ((dir == SIBLING_RIGHT)
|
||||
? (mc->mc_ki[mc->mc_top] + 1u >= page_numkeys(mc->mc_pg[mc->mc_top]))
|
||||
: (mc->mc_ki[mc->mc_top] == 0)) {
|
||||
if ((dir == SIBLING_RIGHT) ? (mc->mc_ki[mc->mc_top] + (size_t)1 >=
|
||||
page_numkeys(mc->mc_pg[mc->mc_top]))
|
||||
: (mc->mc_ki[mc->mc_top] == 0)) {
|
||||
DEBUG("no more keys aside, moving to next %s sibling",
|
||||
dir ? "right" : "left");
|
||||
if (unlikely((rc = cursor_sibling(mc, dir)) != MDBX_SUCCESS)) {
|
||||
@ -16188,7 +16208,7 @@ static int cursor_next(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
||||
|
||||
mp = mc->mc_pg[mc->mc_top];
|
||||
if (unlikely(mc->mc_flags & C_EOF)) {
|
||||
if (mc->mc_ki[mc->mc_top] + 1u >= page_numkeys(mp))
|
||||
if (mc->mc_ki[mc->mc_top] + (size_t)1 >= page_numkeys(mp))
|
||||
return MDBX_NOTFOUND;
|
||||
mc->mc_flags ^= C_EOF;
|
||||
}
|
||||
@ -16503,7 +16523,7 @@ cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, MDBX_cursor_op op) {
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
mc->mc_pg[0] = 0;
|
||||
mc->mc_pg[0] = nullptr;
|
||||
}
|
||||
|
||||
ret.err = page_search(mc, &aligned_key, 0);
|
||||
@ -16511,6 +16531,7 @@ cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, MDBX_cursor_op op) {
|
||||
return ret;
|
||||
|
||||
mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_ANALYSIS_ASSUME(mp != nullptr);
|
||||
cASSERT(mc, IS_LEAF(mp));
|
||||
|
||||
search_node:;
|
||||
@ -16568,10 +16589,12 @@ got_node:
|
||||
if (unlikely(ret.err != MDBX_SUCCESS))
|
||||
return ret;
|
||||
if (op == MDBX_SET || op == MDBX_SET_KEY || op == MDBX_SET_RANGE) {
|
||||
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
|
||||
ret.err = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
|
||||
if (unlikely(ret.err != MDBX_SUCCESS))
|
||||
return ret;
|
||||
} else {
|
||||
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
|
||||
ret = cursor_set(&mc->mc_xcursor->mx_cursor, data, NULL, MDBX_SET_RANGE);
|
||||
if (unlikely(ret.err != MDBX_SUCCESS))
|
||||
return ret;
|
||||
@ -16679,6 +16702,7 @@ static int cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
|
||||
rc = cursor_xinit1(mc, node, mp);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
|
||||
rc = cursor_first(&mc->mc_xcursor->mx_cursor, data, NULL);
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
@ -16728,6 +16752,7 @@ static int cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
|
||||
rc = cursor_xinit1(mc, node, mp);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
MDBX_ANALYSIS_ASSUME(mc->mc_xcursor != nullptr);
|
||||
rc = cursor_last(&mc->mc_xcursor->mx_cursor, data, NULL);
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
@ -17141,10 +17166,10 @@ static __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key,
|
||||
size_t need = CURSOR_STACK + 3;
|
||||
/* 2) GC/FreeDB for any payload */
|
||||
if (mc->mc_dbi > FREE_DBI) {
|
||||
need += txn->mt_dbs[FREE_DBI].md_depth + 3;
|
||||
need += txn->mt_dbs[FREE_DBI].md_depth + (size_t)3;
|
||||
/* 3) Named DBs also dirty the main DB */
|
||||
if (mc->mc_dbi > MAIN_DBI)
|
||||
need += txn->mt_dbs[MAIN_DBI].md_depth + 3;
|
||||
need += txn->mt_dbs[MAIN_DBI].md_depth + (size_t)3;
|
||||
}
|
||||
#if xMDBX_DEBUG_SPILLING != 2
|
||||
/* production mode */
|
||||
@ -17152,7 +17177,7 @@ static __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key,
|
||||
* for extensively splitting, rebalance and merging */
|
||||
need += need;
|
||||
/* 5) Factor the key+data which to be put in */
|
||||
need += bytes2pgno(txn->mt_env, node_size(key, data)) + 1;
|
||||
need += bytes2pgno(txn->mt_env, node_size(key, data)) + (size_t)1;
|
||||
#else
|
||||
/* debug mode */
|
||||
(void)key;
|
||||
@ -18242,6 +18267,7 @@ __hot static int __must_check_result node_add_leaf2(MDBX_cursor *mc,
|
||||
size_t indx,
|
||||
const MDBX_val *key) {
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_ANALYSIS_ASSUME(key != nullptr);
|
||||
DKBUF_DEBUG;
|
||||
DEBUG("add to leaf2-%spage %" PRIaPGNO " index %zi, "
|
||||
" key size %" PRIuPTR " [%s]",
|
||||
@ -18322,6 +18348,8 @@ __hot static int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx,
|
||||
const MDBX_val *key,
|
||||
MDBX_val *data,
|
||||
unsigned flags) {
|
||||
MDBX_ANALYSIS_ASSUME(key != nullptr);
|
||||
MDBX_ANALYSIS_ASSUME(data != nullptr);
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
DKBUF_DEBUG;
|
||||
DEBUG("add to leaf-%spage %" PRIaPGNO " index %zi, data size %" PRIuPTR
|
||||
@ -19659,7 +19687,7 @@ static int rebalance(MDBX_cursor *mc) {
|
||||
const int pagetype = PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top]);
|
||||
|
||||
STATIC_ASSERT(P_BRANCH == 1);
|
||||
const size_t minkeys = (pagetype & P_BRANCH) + 1;
|
||||
const size_t minkeys = (pagetype & P_BRANCH) + (size_t)1;
|
||||
|
||||
/* Pages emptier than this are candidates for merging. */
|
||||
size_t room_threshold = likely(mc->mc_dbi != FREE_DBI)
|
||||
@ -19797,9 +19825,10 @@ static int rebalance(MDBX_cursor *mc) {
|
||||
return rc;
|
||||
cASSERT(mc, PAGETYPE_WHOLE(left) == PAGETYPE_WHOLE(mc->mc_pg[mc->mc_top]));
|
||||
}
|
||||
if (mn.mc_ki[pre_top] + 1u < page_numkeys(mn.mc_pg[pre_top])) {
|
||||
if (mn.mc_ki[pre_top] + (size_t)1 < page_numkeys(mn.mc_pg[pre_top])) {
|
||||
rc = page_get(
|
||||
&mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + 1)),
|
||||
&mn,
|
||||
node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + (size_t)1)),
|
||||
&right, mc->mc_pg[mc->mc_top]->mp_txnid);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
@ -20454,7 +20483,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
|
||||
return rc;
|
||||
}
|
||||
STATIC_ASSERT(P_BRANCH == 1);
|
||||
const size_t minkeys = (mp->mp_flags & P_BRANCH) + 1;
|
||||
const size_t minkeys = (mp->mp_flags & P_BRANCH) + (size_t)1;
|
||||
|
||||
DEBUG(">> splitting %s-page %" PRIaPGNO
|
||||
" and adding %zu+%zu [%s] at %i, nkeys %zi",
|
||||
@ -20758,7 +20787,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
|
||||
}
|
||||
|
||||
/* root split? */
|
||||
ptop += mc->mc_snum - snum;
|
||||
ptop += mc->mc_snum - (size_t)snum;
|
||||
|
||||
/* Right page might now have changed parent.
|
||||
* Check if left page also changed parent. */
|
||||
@ -20811,7 +20840,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto done;
|
||||
|
||||
MDBX_node *node = page_node(mc->mc_pg[ptop], mc->mc_ki[ptop] + 1);
|
||||
MDBX_node *node = page_node(mc->mc_pg[ptop], mc->mc_ki[ptop] + (size_t)1);
|
||||
cASSERT(mc, node_pgno(node) == mp->mp_pgno && mc->mc_pg[ptop] == ptop_page);
|
||||
} else {
|
||||
mn.mc_top--;
|
||||
@ -21416,7 +21445,7 @@ __cold static void compacting_fixup_meta(MDBX_env *env, MDBX_meta *meta) {
|
||||
/* Calculate filesize taking in account shrink/growing thresholds */
|
||||
if (meta->mm_geo.next != meta->mm_geo.now) {
|
||||
meta->mm_geo.now = meta->mm_geo.next;
|
||||
const pgno_t aligner = pv2pages(
|
||||
const size_t aligner = pv2pages(
|
||||
meta->mm_geo.grow_pv ? meta->mm_geo.grow_pv : meta->mm_geo.shrink_pv);
|
||||
if (aligner) {
|
||||
const pgno_t aligned = pgno_align2os_pgno(
|
||||
@ -22874,9 +22903,10 @@ static int drop_tree(MDBX_cursor *mc, const bool may_have_subDBs) {
|
||||
if (!(may_have_subDBs | mc->mc_db->md_overflow_pages))
|
||||
cursor_pop(mc);
|
||||
|
||||
rc = pnl_need(&txn->tw.retired_pages, mc->mc_db->md_branch_pages +
|
||||
mc->mc_db->md_leaf_pages +
|
||||
mc->mc_db->md_overflow_pages);
|
||||
rc = pnl_need(&txn->tw.retired_pages,
|
||||
(size_t)mc->mc_db->md_branch_pages +
|
||||
(size_t)mc->mc_db->md_leaf_pages +
|
||||
(size_t)mc->mc_db->md_overflow_pages);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto bailout;
|
||||
|
||||
@ -24647,8 +24677,8 @@ uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer) {
|
||||
|
||||
assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD &&
|
||||
mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX);
|
||||
const uint64_t exponent =
|
||||
IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift;
|
||||
const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS +
|
||||
IEEE754_DOUBLE_MANTISSA_SIZE - shift;
|
||||
assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX);
|
||||
const uint64_t key = bias + (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) +
|
||||
(mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD);
|
||||
@ -24673,8 +24703,8 @@ uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer) {
|
||||
|
||||
assert(mantissa >= IEEE754_DOUBLE_IMPLICIT_LEAD &&
|
||||
mantissa <= IEEE754_DOUBLE_MANTISSA_AMAX);
|
||||
const uint64_t exponent =
|
||||
IEEE754_DOUBLE_EXPONENTA_BIAS + IEEE754_DOUBLE_MANTISSA_SIZE - shift;
|
||||
const uint64_t exponent = (uint64_t)IEEE754_DOUBLE_EXPONENTA_BIAS +
|
||||
IEEE754_DOUBLE_MANTISSA_SIZE - shift;
|
||||
assert(exponent > 0 && exponent <= IEEE754_DOUBLE_EXPONENTA_MAX);
|
||||
const uint64_t key = bias - 1 - (exponent << IEEE754_DOUBLE_MANTISSA_SIZE) -
|
||||
(mantissa - IEEE754_DOUBLE_IMPLICIT_LEAD);
|
||||
|
@ -86,14 +86,18 @@
|
||||
#pragma warning(disable : 4464) /* relative include path contains '..' */
|
||||
#endif
|
||||
#if _MSC_VER > 1913
|
||||
#pragma warning(disable : 5045) /* Compiler will insert Spectre mitigation... \
|
||||
*/
|
||||
#pragma warning(disable : 5045) /* will insert Spectre mitigation... */
|
||||
#endif
|
||||
#if _MSC_VER > 1914
|
||||
#pragma warning( \
|
||||
disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \
|
||||
producing 'defined' has undefined behavior */
|
||||
#endif
|
||||
#if _MSC_VER > 1930
|
||||
#pragma warning(disable : 6235) /* <expression> is always a constant */
|
||||
#pragma warning(disable : 6237) /* <expression> is never evaluated and might \
|
||||
have side effects */
|
||||
#endif
|
||||
#pragma warning(disable : 4710) /* 'xyz': function not inlined */
|
||||
#pragma warning(disable : 4711) /* function 'xyz' selected for automatic \
|
||||
inline expansion */
|
||||
@ -1693,14 +1697,14 @@ int64pgno(int64_t i64) {
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
|
||||
pgno_add(size_t base, size_t augend) {
|
||||
assert(base <= MAX_PAGENO + 1 && augend < MAX_PAGENO);
|
||||
return int64pgno(base + augend);
|
||||
return int64pgno((int64_t)base + (int64_t)augend);
|
||||
}
|
||||
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
|
||||
pgno_sub(size_t base, size_t subtrahend) {
|
||||
assert(base >= MIN_PAGENO && base <= MAX_PAGENO + 1 &&
|
||||
subtrahend < MAX_PAGENO);
|
||||
return int64pgno(base - subtrahend);
|
||||
return int64pgno((int64_t)base - (int64_t)subtrahend);
|
||||
}
|
||||
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __always_inline bool
|
||||
|
@ -175,7 +175,7 @@ static int funlock(mdbx_filehandle_t fd, size_t offset, size_t bytes) {
|
||||
#else
|
||||
#define DXB_MAXLEN UINT32_C(0x7ff00000)
|
||||
#endif
|
||||
#define DXB_BODY (env->me_psize * NUM_METAS), DXB_MAXLEN
|
||||
#define DXB_BODY (env->me_psize * (size_t)NUM_METAS), DXB_MAXLEN
|
||||
#define DXB_WHOLE 0, DXB_MAXLEN
|
||||
|
||||
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
@ -194,8 +194,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
}
|
||||
}
|
||||
|
||||
if (env->me_flags & MDBX_EXCLUSIVE)
|
||||
if (env->me_flags & MDBX_EXCLUSIVE) {
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
26115, "Failing to release lock 'env->me_windowsbug_lock' in function "
|
||||
"'mdbx_txn_lock'");
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
const HANDLE fd4data =
|
||||
env->me_overlapped_fd ? env->me_overlapped_fd : env->me_lazy_fd;
|
||||
@ -213,8 +217,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
LCK_EXCLUSIVE | LCK_DONTWAIT, DXB_BODY);
|
||||
}
|
||||
}
|
||||
if (rc == MDBX_SUCCESS)
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
26115, "Failing to release lock 'env->me_windowsbug_lock' in function "
|
||||
"'mdbx_txn_lock'");
|
||||
return rc;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&env->me_windowsbug_lock);
|
||||
return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY;
|
||||
@ -281,17 +289,18 @@ static int suspend_and_append(mdbx_handle_array_t **array,
|
||||
const DWORD ThreadId) {
|
||||
const unsigned limit = (*array)->limit;
|
||||
if ((*array)->count == limit) {
|
||||
void *ptr = osal_realloc(
|
||||
(limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) * (limit * 2 - ARRAY_LENGTH((*array)->handles)));
|
||||
mdbx_handle_array_t *const ptr =
|
||||
osal_realloc((limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) * (limit * (size_t)2 -
|
||||
ARRAY_LENGTH((*array)->handles)));
|
||||
if (!ptr)
|
||||
return MDBX_ENOMEM;
|
||||
if (limit == ARRAY_LENGTH((*array)->handles))
|
||||
memcpy(ptr, *array, sizeof(mdbx_handle_array_t));
|
||||
*array = (mdbx_handle_array_t *)ptr;
|
||||
*ptr = **array;
|
||||
*array = ptr;
|
||||
(*array)->limit = limit * 2;
|
||||
}
|
||||
|
||||
@ -839,38 +848,40 @@ MDBX_SetFileIoOverlappedRange mdbx_SetFileIoOverlappedRange;
|
||||
#endif /* GCC/MINGW */
|
||||
|
||||
static void mdbx_winnt_import(void) {
|
||||
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
#define GET_PROC_ADDR(dll, ENTRY) \
|
||||
mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(dll, #ENTRY)
|
||||
|
||||
if (GetProcAddress(hNtdll, "wine_get_version")) {
|
||||
assert(mdbx_RunningUnderWine());
|
||||
} else {
|
||||
GET_PROC_ADDR(hNtdll, NtFsControlFile);
|
||||
GET_PROC_ADDR(hNtdll, NtExtendSection);
|
||||
assert(!mdbx_RunningUnderWine());
|
||||
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
if (hNtdll) {
|
||||
if (GetProcAddress(hNtdll, "wine_get_version")) {
|
||||
assert(mdbx_RunningUnderWine());
|
||||
} else {
|
||||
GET_PROC_ADDR(hNtdll, NtFsControlFile);
|
||||
GET_PROC_ADDR(hNtdll, NtExtendSection);
|
||||
assert(!mdbx_RunningUnderWine());
|
||||
}
|
||||
}
|
||||
|
||||
const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll");
|
||||
GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx);
|
||||
GET_PROC_ADDR(hKernel32dll, GetTickCount64);
|
||||
if (!mdbx_GetTickCount64)
|
||||
mdbx_GetTickCount64 = stub_GetTickCount64;
|
||||
if (!mdbx_RunningUnderWine()) {
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle);
|
||||
GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW);
|
||||
GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW);
|
||||
GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory);
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange);
|
||||
if (hKernel32dll) {
|
||||
GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx);
|
||||
GET_PROC_ADDR(hKernel32dll, GetTickCount64);
|
||||
if (!mdbx_GetTickCount64)
|
||||
mdbx_GetTickCount64 = stub_GetTickCount64;
|
||||
if (!mdbx_RunningUnderWine()) {
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle);
|
||||
GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW);
|
||||
GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW);
|
||||
GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory);
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange);
|
||||
}
|
||||
}
|
||||
|
||||
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
|
||||
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA);
|
||||
#undef GET_PROC_ADDR
|
||||
|
||||
const osal_srwlock_t_function init = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "InitializeSRWLock");
|
||||
const osal_srwlock_t_function init =
|
||||
(osal_srwlock_t_function)(hKernel32dll
|
||||
? GetProcAddress(hKernel32dll,
|
||||
"InitializeSRWLock")
|
||||
: nullptr);
|
||||
if (init != NULL) {
|
||||
osal_srwlock_Init = init;
|
||||
osal_srwlock_AcquireShared = (osal_srwlock_t_function)GetProcAddress(
|
||||
@ -888,6 +899,12 @@ static void mdbx_winnt_import(void) {
|
||||
osal_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive;
|
||||
osal_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive;
|
||||
}
|
||||
|
||||
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
|
||||
if (hAdvapi32dll) {
|
||||
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA);
|
||||
}
|
||||
#undef GET_PROC_ADDR
|
||||
}
|
||||
|
||||
#if __GNUC_PREREQ(8, 0)
|
||||
|
@ -571,8 +571,8 @@ static int pgvisitor(const uint64_t pgno, const unsigned pgnumber,
|
||||
data_tree_problems += !is_gc_tree;
|
||||
gc_tree_problems += is_gc_tree;
|
||||
} else {
|
||||
dbi->payload_bytes += payload_bytes + header_bytes;
|
||||
walk.total_payload_bytes += payload_bytes + header_bytes;
|
||||
dbi->payload_bytes += (uint64_t)payload_bytes + header_bytes;
|
||||
walk.total_payload_bytes += (uint64_t)payload_bytes + header_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -632,7 +632,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
|
||||
pgno_t prev = MDBX_PNL_ASCENDING ? NUM_METAS - 1 : txn->mt_next_pgno;
|
||||
pgno_t span = 1;
|
||||
for (unsigned i = 0; i < number; ++i) {
|
||||
for (size_t i = 0; i < number; ++i) {
|
||||
if (check_user_break())
|
||||
return MDBX_EINTR;
|
||||
const pgno_t pgno = iptr[i];
|
||||
@ -651,7 +651,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
if (MDBX_PNL_DISORDERED(prev, pgno)) {
|
||||
bad = " [bad sequence]";
|
||||
problem_add("entry", txnid, "bad sequence",
|
||||
"%" PRIaPGNO " %c [%u].%" PRIaPGNO, prev,
|
||||
"%" PRIaPGNO " %c [%zu].%" PRIaPGNO, prev,
|
||||
(prev == pgno) ? '=' : (MDBX_PNL_ASCENDING ? '>' : '<'),
|
||||
i, pgno);
|
||||
}
|
||||
@ -677,7 +677,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
" pages, maxspan %" PRIaPGNO "%s\n",
|
||||
txnid, number, span, bad);
|
||||
if (verbose > 4) {
|
||||
for (unsigned i = 0; i < number; i += span) {
|
||||
for (size_t i = 0; i < number; i += span) {
|
||||
const pgno_t pgno = iptr[i];
|
||||
for (span = 1;
|
||||
i + span < number &&
|
||||
|
@ -673,7 +673,7 @@ int main(int argc, char *argv[]) {
|
||||
goto env_close;
|
||||
}
|
||||
|
||||
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + 1;
|
||||
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + (size_t)1;
|
||||
if (kbuf.iov_len >= INTPTR_MAX / 2) {
|
||||
if (!quiet)
|
||||
fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n",
|
||||
|
26
src/osal.c
26
src/osal.c
@ -48,6 +48,7 @@ static int ntstatus2errcode(NTSTATUS status) {
|
||||
OVERLAPPED ov;
|
||||
memset(&ov, 0, sizeof(ov));
|
||||
ov.Internal = status;
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6387, "'_Param_(1)' could be '0'");
|
||||
return GetOverlappedResult(NULL, &ov, &dummy, FALSE) ? MDBX_SUCCESS
|
||||
: (int)GetLastError();
|
||||
}
|
||||
@ -82,6 +83,8 @@ extern NTSTATUS NTAPI NtMapViewOfSection(
|
||||
extern NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle,
|
||||
IN OPTIONAL PVOID BaseAddress);
|
||||
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(28251,
|
||||
"Inconsistent annotation for 'NtClose'...")
|
||||
extern NTSTATUS NTAPI NtClose(HANDLE Handle);
|
||||
|
||||
extern NTSTATUS NTAPI NtAllocateVirtualMemory(
|
||||
@ -320,7 +323,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
|
||||
return needed;
|
||||
}
|
||||
|
||||
*strp = osal_malloc(needed + 1);
|
||||
*strp = osal_malloc(needed + (size_t)1);
|
||||
if (unlikely(*strp == nullptr)) {
|
||||
va_end(ones);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@ -331,7 +334,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int actual = vsnprintf(*strp, needed + 1, fmt, ones);
|
||||
int actual = vsnprintf(*strp, needed + (size_t)1, fmt, ones);
|
||||
va_end(ones);
|
||||
|
||||
assert(actual == needed);
|
||||
@ -692,7 +695,7 @@ MDBX_INTERNAL_FUNC int osal_ioring_add(osal_ioring_t *ior, const size_t offset,
|
||||
((bytes | (uintptr_t)data | ior->last_bytes |
|
||||
(uintptr_t)(uint64_t)item->sgv[0].Buffer) &
|
||||
ior_alignment_mask) == 0 &&
|
||||
ior->last_sgvcnt + segments < OSAL_IOV_MAX) {
|
||||
ior->last_sgvcnt + (size_t)segments < OSAL_IOV_MAX) {
|
||||
assert(ior->overlapped_fd);
|
||||
assert((item->single.iov_len & ior_WriteFile_flag) == 0);
|
||||
assert(item->sgv[ior->last_sgvcnt].Buffer == 0);
|
||||
@ -801,6 +804,8 @@ MDBX_INTERNAL_FUNC void osal_ioring_walk(
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
data = Ptr64ToPtr(item->sgv[0].Buffer);
|
||||
bytes = ior->pagesize;
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6385, "Reading invalid data from 'item->sgv'");
|
||||
while (item->sgv[i].Buffer) {
|
||||
if (data + ior->pagesize != item->sgv[i].Buffer) {
|
||||
callback(ctx, offset, data, bytes);
|
||||
@ -847,6 +852,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
assert(ior->overlapped_fd && fd == ior->overlapped_fd);
|
||||
bytes = ior->pagesize;
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6385, "Reading invalid data from 'item->sgv'");
|
||||
while (item->sgv[i].Buffer) {
|
||||
bytes += ior->pagesize;
|
||||
++i;
|
||||
@ -985,6 +992,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
|
||||
size_t i = 1, bytes = item->single.iov_len - ior_WriteFile_flag;
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
bytes = ior->pagesize;
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6385, "Reading invalid data from 'item->sgv'");
|
||||
while (item->sgv[i].Buffer) {
|
||||
bytes += ior->pagesize;
|
||||
++i;
|
||||
@ -1078,9 +1087,12 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
|
||||
if (item->ov.hEvent && item->ov.hEvent != ior)
|
||||
ior_put_event(ior, item->ov.hEvent);
|
||||
size_t i = 1;
|
||||
if ((item->single.iov_len & ior_WriteFile_flag) == 0)
|
||||
if ((item->single.iov_len & ior_WriteFile_flag) == 0) {
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6385, "Reading invalid data from 'item->sgv'");
|
||||
while (item->sgv[i].Buffer)
|
||||
++i;
|
||||
}
|
||||
item = ior_next(item, i);
|
||||
}
|
||||
}
|
||||
@ -1095,8 +1107,11 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
|
||||
static void ior_cleanup(osal_ioring_t *ior, const size_t since) {
|
||||
osal_ioring_reset(ior);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
for (size_t i = since; i < ior->event_stack; ++i)
|
||||
for (size_t i = since; i < ior->event_stack; ++i) {
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(
|
||||
6001, "Using uninitialized memory '**ior.event_pool'");
|
||||
CloseHandle(ior->event_pool[i]);
|
||||
}
|
||||
ior->event_stack = 0;
|
||||
#else
|
||||
(void)since;
|
||||
@ -2734,6 +2749,7 @@ retry_mapview:;
|
||||
|
||||
#endif /* POSIX / Windows */
|
||||
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6287, "Redundant code");
|
||||
assert(rc != MDBX_SUCCESS ||
|
||||
(map->base != nullptr && map->base != MAP_FAILED &&
|
||||
map->current == size && map->limit == limit &&
|
||||
|
@ -87,10 +87,11 @@ time from_ms(uint64_t ms) {
|
||||
time now_realtime() {
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
|
||||
static void(WINAPI * query_time)(LPFILETIME);
|
||||
if (!query_time) {
|
||||
query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress(
|
||||
GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"GetSystemTimePreciseAsFileTime");
|
||||
if (unlikely(!query_time)) {
|
||||
HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll"));
|
||||
if (hModule)
|
||||
query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress(
|
||||
hModule, "GetSystemTimePreciseAsFileTime");
|
||||
if (!query_time)
|
||||
query_time = GetSystemTimeAsFileTime;
|
||||
}
|
||||
|
@ -227,7 +227,8 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id,
|
||||
|
||||
(void)thread_number;
|
||||
mapping = actor.keygen;
|
||||
salt = (actor.keygen.seed + actor_id) * UINT64_C(14653293970879851569);
|
||||
salt =
|
||||
(actor.keygen.seed + uint64_t(actor_id)) * UINT64_C(14653293970879851569);
|
||||
|
||||
base = actor.serial_base();
|
||||
}
|
||||
@ -315,11 +316,12 @@ void __hot maker::mk_begin(const serial_t serial, const essentials ¶ms,
|
||||
out.value.iov_len = std::max(unsigned(params.minlen), length(serial));
|
||||
const auto variation = params.maxlen - params.minlen;
|
||||
if (variation) {
|
||||
if (serial % (variation + 1)) {
|
||||
if (serial % (variation + serial_t(1))) {
|
||||
auto refix = serial * UINT64_C(48835288005252737);
|
||||
refix ^= refix >> 32;
|
||||
out.value.iov_len = std::max(
|
||||
out.value.iov_len, params.minlen + 1 + size_t(refix) % variation);
|
||||
out.value.iov_len =
|
||||
std::max(out.value.iov_len,
|
||||
params.minlen + size_t(1) + size_t(refix) % variation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
|
||||
prefix.c_str(), level2str(priority), suffix.c_str());
|
||||
|
||||
va_list ones;
|
||||
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other stupid compilers */;
|
||||
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */;
|
||||
if (same_or_higher(priority, error))
|
||||
va_copy(ones, ap);
|
||||
vfprintf(last, format, ap);
|
||||
@ -153,11 +153,11 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
|
||||
switch (end) {
|
||||
default:
|
||||
putc('\n', last);
|
||||
// fall through
|
||||
MDBX_CXX17_FALLTHROUGH; // fall through
|
||||
case '\n':
|
||||
fflush(last);
|
||||
last = nullptr;
|
||||
// fall through
|
||||
MDBX_CXX17_FALLTHROUGH; // fall through
|
||||
case ' ':
|
||||
case '_':
|
||||
case ':':
|
||||
|
@ -248,7 +248,7 @@ Environment:
|
||||
CommandLine.push_back('"');
|
||||
|
||||
for (auto It = Argument.begin();; ++It) {
|
||||
unsigned NumberBackslashes = 0;
|
||||
size_t NumberBackslashes = 0;
|
||||
|
||||
while (It != Argument.end() && *It == '\\') {
|
||||
++It;
|
||||
@ -435,7 +435,7 @@ void osal_udelay(size_t us) {
|
||||
unsigned timeslice_ms = 1;
|
||||
while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO)
|
||||
++timeslice_ms;
|
||||
threshold_us = timeslice_ms * 1500u;
|
||||
threshold_us = timeslice_ms * size_t(1500);
|
||||
assert(threshold_us > 0);
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ int testcase::hsr_callback(const MDBX_env *env, const MDBX_txn *txn,
|
||||
info.mi_geo.current >= info.mi_geo.upper)) {
|
||||
osal_yield();
|
||||
if (retry > 0)
|
||||
osal_udelay(retry * 100);
|
||||
osal_udelay(retry * size_t(100));
|
||||
return MDBX_RESULT_FALSE /* retry / wait until reader done */;
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,10 @@ class testcase;
|
||||
|
||||
class registry {
|
||||
struct record {
|
||||
actor_testcase id;
|
||||
actor_testcase id = ac_none;
|
||||
std::string name;
|
||||
bool (*review_params)(actor_params &);
|
||||
testcase *(*constructor)(const actor_config &, const mdbx_pid_t);
|
||||
bool (*review_params)(actor_params &) = nullptr;
|
||||
testcase *(*constructor)(const actor_config &, const mdbx_pid_t) = nullptr;
|
||||
};
|
||||
std::unordered_map<std::string, const record *> name2id;
|
||||
std::unordered_map<int, const record *> id2record;
|
||||
|
Loading…
x
Reference in New Issue
Block a user