mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:44:13 +08:00
mdbx: предварительное вычисление me_maxgc_per_branch
.
This commit is contained in:
parent
3a77af7d8a
commit
4b27c4c7c9
54
src/core.c
54
src/core.c
@ -9846,38 +9846,35 @@ static int gcu_prepare_backlog(MDBX_txn *txn, gcu_context_t *ctx) {
|
|||||||
|
|
||||||
const intptr_t retired_left =
|
const intptr_t retired_left =
|
||||||
MDBX_PNL_SIZEOF(txn->tw.retired_pages) - ctx->retired_stored;
|
MDBX_PNL_SIZEOF(txn->tw.retired_pages) - ctx->retired_stored;
|
||||||
size_t for_retiredlist = 0;
|
size_t for_relist = 0;
|
||||||
if (MDBX_ENABLE_BIGFOOT && retired_left > 0) {
|
if (MDBX_ENABLE_BIGFOOT && retired_left > 0) {
|
||||||
for_retiredlist = (retired_left + txn->mt_env->me_maxgc_ov1page - 1) /
|
for_relist = (retired_left + txn->mt_env->me_maxgc_ov1page - 1) /
|
||||||
txn->mt_env->me_maxgc_ov1page;
|
txn->mt_env->me_maxgc_ov1page;
|
||||||
const size_t per_branch_page =
|
const size_t per_branch_page = txn->mt_env->me_maxgc_per_branch;
|
||||||
(txn->mt_env->me_psize - PAGEHDRSZ) /
|
for (size_t entries = for_relist; entries > 1; for_split += entries)
|
||||||
(sizeof(indx_t) + sizeof(MDBX_node) + sizeof(txnid_t));
|
|
||||||
for (size_t entries = for_retiredlist; entries > 1; for_split += entries)
|
|
||||||
entries = (entries + per_branch_page - 1) / per_branch_page;
|
entries = (entries + per_branch_page - 1) / per_branch_page;
|
||||||
} else if (!MDBX_ENABLE_BIGFOOT && retired_left != 0) {
|
} else if (!MDBX_ENABLE_BIGFOOT && retired_left != 0) {
|
||||||
for_retiredlist =
|
for_relist =
|
||||||
number_of_ovpages(txn->mt_env, MDBX_PNL_SIZEOF(txn->tw.retired_pages));
|
number_of_ovpages(txn->mt_env, MDBX_PNL_SIZEOF(txn->tw.retired_pages));
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t for_tree_before_touch = for_cow + for_rebalance + for_split;
|
const size_t for_tree_before_touch = for_cow + for_rebalance + for_split;
|
||||||
const size_t for_tree_after_touch = for_rebalance + for_split;
|
const size_t for_tree_after_touch = for_rebalance + for_split;
|
||||||
const size_t for_data = for_retiredlist;
|
const size_t for_all_before_touch = for_relist + for_tree_before_touch;
|
||||||
const size_t for_all_before_touch = for_data + for_tree_before_touch;
|
const size_t for_all_after_touch = for_relist + for_tree_after_touch;
|
||||||
const size_t for_all_after_touch = for_data + for_tree_after_touch;
|
|
||||||
|
|
||||||
if (likely(for_data < 2 && gcu_backlog_size(txn) > for_all_before_touch))
|
if (likely(for_relist < 2 && gcu_backlog_size(txn) > for_all_before_touch))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
|
||||||
TRACE(">> retired-stored %zu, left %zi, backlog %zu, need %zu (4list %zu, "
|
TRACE(">> retired-stored %zu, left %zi, backlog %zu, need %zu (4list %zu, "
|
||||||
"4split %zu, "
|
"4split %zu, "
|
||||||
"4cow %zu, 4tree %zu)",
|
"4cow %zu, 4tree %zu)",
|
||||||
ctx->retired_stored, retired_left, gcu_backlog_size(txn),
|
ctx->retired_stored, retired_left, gcu_backlog_size(txn),
|
||||||
for_all_before_touch, for_data, for_split, for_cow,
|
for_all_before_touch, for_relist, for_split, for_cow,
|
||||||
for_tree_before_touch);
|
for_tree_before_touch);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if (unlikely(for_data > 2)) {
|
if (unlikely(for_relist > 2)) {
|
||||||
MDBX_val key, val;
|
MDBX_val key, val;
|
||||||
key.iov_base = val.iov_base = nullptr;
|
key.iov_base = val.iov_base = nullptr;
|
||||||
key.iov_len = sizeof(txnid_t);
|
key.iov_len = sizeof(txnid_t);
|
||||||
@ -9890,7 +9887,7 @@ static int gcu_prepare_backlog(MDBX_txn *txn, gcu_context_t *ctx) {
|
|||||||
err = gcu_touch(ctx);
|
err = gcu_touch(ctx);
|
||||||
TRACE("== after-touch, backlog %zu, err %d", gcu_backlog_size(txn), err);
|
TRACE("== after-touch, backlog %zu, err %d", gcu_backlog_size(txn), err);
|
||||||
|
|
||||||
if (!MDBX_ENABLE_BIGFOOT && unlikely(for_data > 1) &&
|
if (!MDBX_ENABLE_BIGFOOT && unlikely(for_relist > 1) &&
|
||||||
MDBX_PNL_GETSIZE(txn->tw.retired_pages) != ctx->retired_stored &&
|
MDBX_PNL_GETSIZE(txn->tw.retired_pages) != ctx->retired_stored &&
|
||||||
err == MDBX_SUCCESS) {
|
err == MDBX_SUCCESS) {
|
||||||
if (unlikely(ctx->retired_stored)) {
|
if (unlikely(ctx->retired_stored)) {
|
||||||
@ -9900,10 +9897,10 @@ static int gcu_prepare_backlog(MDBX_txn *txn, gcu_context_t *ctx) {
|
|||||||
if (!ctx->retired_stored)
|
if (!ctx->retired_stored)
|
||||||
return /* restart by tail-recursion */ gcu_prepare_backlog(txn, ctx);
|
return /* restart by tail-recursion */ gcu_prepare_backlog(txn, ctx);
|
||||||
}
|
}
|
||||||
err = page_alloc_slowpath(&ctx->cursor, for_data, MDBX_ALLOC_RESERVE).err;
|
err = page_alloc_slowpath(&ctx->cursor, for_relist, MDBX_ALLOC_RESERVE).err;
|
||||||
TRACE("== after-4linear, backlog %zu, err %d", gcu_backlog_size(txn), err);
|
TRACE("== after-4linear, backlog %zu, err %d", gcu_backlog_size(txn), err);
|
||||||
cASSERT(&ctx->cursor,
|
cASSERT(&ctx->cursor,
|
||||||
gcu_backlog_size(txn) >= for_data || err != MDBX_SUCCESS);
|
gcu_backlog_size(txn) >= for_relist || err != MDBX_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (gcu_backlog_size(txn) < for_all_after_touch && err == MDBX_SUCCESS)
|
while (gcu_backlog_size(txn) < for_all_after_touch && err == MDBX_SUCCESS)
|
||||||
@ -9950,11 +9947,11 @@ static int update_gc(MDBX_txn *txn, gcu_context_t *ctx) {
|
|||||||
|
|
||||||
/* txn->tw.relist[] can grow and shrink during this call.
|
/* txn->tw.relist[] can grow and shrink during this call.
|
||||||
* txn->tw.last_reclaimed and txn->tw.retired_pages[] can only grow.
|
* txn->tw.last_reclaimed and txn->tw.retired_pages[] can only grow.
|
||||||
* Page numbers cannot disappear from txn->tw.retired_pages[]. */
|
* But page numbers cannot disappear from txn->tw.retired_pages[]. */
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
++ctx->loop;
|
if (ctx->loop++)
|
||||||
TRACE("%s", " >> restart");
|
TRACE("%s", " >> restart");
|
||||||
int rc = MDBX_SUCCESS;
|
int rc = MDBX_SUCCESS;
|
||||||
tASSERT(txn, pnl_check_allocated(txn->tw.relist,
|
tASSERT(txn, pnl_check_allocated(txn->tw.relist,
|
||||||
txn->mt_next_pgno - MDBX_ENABLE_REFUND));
|
txn->mt_next_pgno - MDBX_ENABLE_REFUND));
|
||||||
@ -9979,13 +9976,11 @@ retry:
|
|||||||
ctx->rid = txn->tw.last_reclaimed;
|
ctx->rid = txn->tw.last_reclaimed;
|
||||||
while (true) {
|
while (true) {
|
||||||
/* Come back here after each Put() in case retired-list changed */
|
/* Come back here after each Put() in case retired-list changed */
|
||||||
MDBX_val key, data;
|
|
||||||
TRACE("%s", " >> continue");
|
TRACE("%s", " >> continue");
|
||||||
|
|
||||||
if (ctx->retired_stored != MDBX_PNL_GETSIZE(txn->tw.retired_pages) &&
|
if (ctx->retired_stored != MDBX_PNL_GETSIZE(txn->tw.retired_pages) &&
|
||||||
(ctx->loop == 1 ||
|
(ctx->loop == 1 || ctx->retired_stored > env->me_maxgc_ov1page ||
|
||||||
MDBX_PNL_GETSIZE(txn->tw.retired_pages) > env->me_maxgc_ov1page ||
|
MDBX_PNL_GETSIZE(txn->tw.retired_pages) > env->me_maxgc_ov1page)) {
|
||||||
ctx->retired_stored > env->me_maxgc_ov1page)) {
|
|
||||||
rc = gcu_prepare_backlog(txn, ctx);
|
rc = gcu_prepare_backlog(txn, ctx);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
@ -9993,6 +9988,7 @@ retry:
|
|||||||
|
|
||||||
tASSERT(txn, pnl_check_allocated(txn->tw.relist,
|
tASSERT(txn, pnl_check_allocated(txn->tw.relist,
|
||||||
txn->mt_next_pgno - MDBX_ENABLE_REFUND));
|
txn->mt_next_pgno - MDBX_ENABLE_REFUND));
|
||||||
|
MDBX_val key, data;
|
||||||
if (ctx->lifo) {
|
if (ctx->lifo) {
|
||||||
if (ctx->cleaned_slot < (txn->tw.lifo_reclaimed
|
if (ctx->cleaned_slot < (txn->tw.lifo_reclaimed
|
||||||
? MDBX_PNL_GETSIZE(txn->tw.lifo_reclaimed)
|
? MDBX_PNL_GETSIZE(txn->tw.lifo_reclaimed)
|
||||||
@ -10446,10 +10442,11 @@ retry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (need_cleanup || ctx->dense) {
|
if (need_cleanup || ctx->dense) {
|
||||||
if (ctx->cleaned_slot)
|
if (ctx->cleaned_slot) {
|
||||||
TRACE("%s: restart inner-loop to clear and re-create GC entries",
|
TRACE("%s: restart to clear and re-create GC entries",
|
||||||
dbg_prefix_mode);
|
dbg_prefix_mode);
|
||||||
ctx->cleaned_slot = 0;
|
goto retry;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12527,6 +12524,9 @@ __cold static void setup_pagesize(MDBX_env *env, const size_t pagesize) {
|
|||||||
ENSURE(env,
|
ENSURE(env,
|
||||||
maxgc_ov1page > 42 && maxgc_ov1page < (intptr_t)MDBX_PGL_LIMIT / 4);
|
maxgc_ov1page > 42 && maxgc_ov1page < (intptr_t)MDBX_PGL_LIMIT / 4);
|
||||||
env->me_maxgc_ov1page = (unsigned)maxgc_ov1page;
|
env->me_maxgc_ov1page = (unsigned)maxgc_ov1page;
|
||||||
|
env->me_maxgc_per_branch =
|
||||||
|
(unsigned)((pagesize - PAGEHDRSZ) /
|
||||||
|
(sizeof(indx_t) + sizeof(MDBX_node) + sizeof(txnid_t)));
|
||||||
|
|
||||||
STATIC_ASSERT(LEAF_NODE_MAX(MIN_PAGESIZE) > sizeof(MDBX_db) + NODESIZE + 42);
|
STATIC_ASSERT(LEAF_NODE_MAX(MIN_PAGESIZE) > sizeof(MDBX_db) + NODESIZE + 42);
|
||||||
STATIC_ASSERT(LEAF_NODE_MAX(MAX_PAGESIZE) < UINT16_MAX);
|
STATIC_ASSERT(LEAF_NODE_MAX(MAX_PAGESIZE) < UINT16_MAX);
|
||||||
|
@ -1250,9 +1250,10 @@ struct MDBX_env {
|
|||||||
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
|
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
|
||||||
MDBX_atomic_uint32_t *me_dbiseqs; /* array of dbi sequence numbers */
|
MDBX_atomic_uint32_t *me_dbiseqs; /* array of dbi sequence numbers */
|
||||||
unsigned
|
unsigned
|
||||||
me_maxgc_ov1page; /* Number of pgno_t fit in a single overflow page */
|
me_maxgc_ov1page; /* Number of pgno_t fit in a single overflow page */
|
||||||
uint32_t me_live_reader; /* have liveness lock in reader table */
|
unsigned me_maxgc_per_branch;
|
||||||
void *me_userctx; /* User-settable context */
|
uint32_t me_live_reader; /* have liveness lock in reader table */
|
||||||
|
void *me_userctx; /* User-settable context */
|
||||||
MDBX_hsr_func *me_hsr_callback; /* Callback for kicking laggard readers */
|
MDBX_hsr_func *me_hsr_callback; /* Callback for kicking laggard readers */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user