mdbx: исправление недочета корректировки сопутствующих курсоров при разделении страницы по сценарию добавления пустой страницы слева.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-02-25 19:32:16 +03:00
parent 826441741d
commit 2e863cf7e0

View File

@ -21429,7 +21429,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
/* It is reasonable and possible to split the page at the begin */ /* It is reasonable and possible to split the page at the begin */
if (unlikely(newindx < minkeys)) { if (unlikely(newindx < minkeys)) {
split_indx = minkeys; split_indx = minkeys;
if (newindx == 0 && foliage == 0 && !(naf & MDBX_SPLIT_REPLACE)) { if (newindx == 0 && !(naf & MDBX_SPLIT_REPLACE)) {
split_indx = 0; split_indx = 0;
/* Checking for ability of splitting by the left-side insertion /* Checking for ability of splitting by the left-side insertion
* of a pure page with the new key */ * of a pure page with the new key */
@ -21449,8 +21449,8 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
} else } else
get_key(page_node(mp, 0), &sepkey); get_key(page_node(mp, 0), &sepkey);
cASSERT(mc, mc->mc_dbx->md_cmp(newkey, &sepkey) < 0); cASSERT(mc, mc->mc_dbx->md_cmp(newkey, &sepkey) < 0);
/* Avoiding rare complex cases of split the parent page */ /* Avoiding rare complex cases of nested split the parent page(s) */
if (page_room(mn.mc_pg[ptop]) < branch_size(env, &sepkey)) if (page_room(mc->mc_pg[ptop]) < branch_size(env, &sepkey))
split_indx = minkeys; split_indx = minkeys;
} }
if (foliage) { if (foliage) {
@ -21474,9 +21474,10 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
sepkey = *newkey; sepkey = *newkey;
} else if (unlikely(pure_left)) { } else if (unlikely(pure_left)) {
/* newindx == split_indx == 0 */ /* newindx == split_indx == 0 */
TRACE("no-split, but add new pure page at the %s", "left/before"); TRACE("pure-left: no-split, but add new pure page at the %s",
"left/before");
cASSERT(mc, newindx == 0 && split_indx == 0 && minkeys == 1); cASSERT(mc, newindx == 0 && split_indx == 0 && minkeys == 1);
TRACE("old-first-key is %s", DKEY_DEBUG(&sepkey)); TRACE("pure-left: old-first-key is %s", DKEY_DEBUG(&sepkey));
} else { } else {
if (IS_LEAF2(sister)) { if (IS_LEAF2(sister)) {
/* Move half of the keys to the right sibling */ /* Move half of the keys to the right sibling */
@ -21690,18 +21691,20 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
} }
} else if (unlikely(pure_left)) { } else if (unlikely(pure_left)) {
MDBX_page *ptop_page = mc->mc_pg[ptop]; MDBX_page *ptop_page = mc->mc_pg[ptop];
DEBUG("adding to parent page %u node[%u] left-leaf page #%u key %s", TRACE("pure-left: adding to parent page %u node[%u] left-leaf page #%u key "
"%s",
ptop_page->mp_pgno, mc->mc_ki[ptop], sister->mp_pgno, ptop_page->mp_pgno, mc->mc_ki[ptop], sister->mp_pgno,
DKEY(mc->mc_ki[ptop] ? newkey : NULL)); DKEY(mc->mc_ki[ptop] ? newkey : NULL));
mc->mc_top--; assert(mc->mc_top == ptop + 1);
mc->mc_top = (uint8_t)ptop;
rc = node_add_branch(mc, mc->mc_ki[ptop], mc->mc_ki[ptop] ? newkey : NULL, rc = node_add_branch(mc, mc->mc_ki[ptop], mc->mc_ki[ptop] ? newkey : NULL,
sister->mp_pgno); sister->mp_pgno);
cASSERT(mc, mp == mc->mc_pg[ptop + 1] && newindx == mc->mc_ki[ptop + 1] && cASSERT(mc, mp == mc->mc_pg[ptop + 1] && newindx == mc->mc_ki[ptop + 1] &&
ptop == mc->mc_top); ptop == mc->mc_top);
if (likely(rc == MDBX_SUCCESS) && mc->mc_ki[ptop] == 0) { if (likely(rc == MDBX_SUCCESS) && mc->mc_ki[ptop] == 0) {
DEBUG("update prev-first key on parent %s", DKEY(&sepkey));
MDBX_node *node = page_node(mc->mc_pg[ptop], 1); MDBX_node *node = page_node(mc->mc_pg[ptop], 1);
TRACE("pure-left: update prev-first key on parent to %s", DKEY(&sepkey));
cASSERT(mc, node_ks(node) == 0 && node_pgno(node) == mp->mp_pgno); cASSERT(mc, node_ks(node) == 0 && node_pgno(node) == mp->mp_pgno);
cASSERT(mc, mc->mc_top == ptop && mc->mc_ki[ptop] == 0); cASSERT(mc, mc->mc_top == ptop && mc->mc_ki[ptop] == 0);
mc->mc_ki[ptop] = 1; mc->mc_ki[ptop] = 1;
@ -21709,6 +21712,9 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
cASSERT(mc, mc->mc_top == ptop && mc->mc_ki[ptop] == 1); cASSERT(mc, mc->mc_top == ptop && mc->mc_ki[ptop] == 1);
cASSERT(mc, mp == mc->mc_pg[ptop + 1] && newindx == mc->mc_ki[ptop + 1]); cASSERT(mc, mp == mc->mc_pg[ptop + 1] && newindx == mc->mc_ki[ptop + 1]);
mc->mc_ki[ptop] = 0; mc->mc_ki[ptop] = 0;
} else {
TRACE("pure-left: no-need-update prev-first key on parent %s",
DKEY(&sepkey));
} }
mc->mc_top++; mc->mc_top++;
@ -21757,7 +21763,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
&sepkey); &sepkey);
if (mc->mc_dbx->md_cmp(newkey, &sepkey) < 0) { if (mc->mc_dbx->md_cmp(newkey, &sepkey) < 0) {
mc->mc_top -= (uint8_t)i; mc->mc_top -= (uint8_t)i;
DEBUG("update new-first on parent [%i] page %u key %s", DEBUG("pure-left: update new-first on parent [%i] page %u key %s",
mc->mc_ki[mc->mc_top], mc->mc_pg[mc->mc_top]->mp_pgno, mc->mc_ki[mc->mc_top], mc->mc_pg[mc->mc_top]->mp_pgno,
DKEY(newkey)); DKEY(newkey));
rc = update_key(mc, newkey); rc = update_key(mc, newkey);
@ -21768,7 +21774,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
break; break;
} }
} }
} else if (tmp_ki_copy /* !IS_LEAF2(mp) */) { } else if (tmp_ki_copy) { /* !IS_LEAF2(mp) */
/* Move nodes */ /* Move nodes */
mc->mc_pg[mc->mc_top] = sister; mc->mc_pg[mc->mc_top] = sister;
i = split_indx; i = split_indx;
@ -21887,7 +21893,7 @@ static int page_split(MDBX_cursor *mc, const MDBX_val *const newkey,
m3->mc_ki[k + 1] = m3->mc_ki[k]; m3->mc_ki[k + 1] = m3->mc_ki[k];
m3->mc_pg[k + 1] = m3->mc_pg[k]; m3->mc_pg[k + 1] = m3->mc_pg[k];
} }
m3->mc_ki[0] = m3->mc_ki[0] >= nkeys; m3->mc_ki[0] = m3->mc_ki[0] >= nkeys + pure_left;
m3->mc_pg[0] = mc->mc_pg[0]; m3->mc_pg[0] = mc->mc_pg[0];
m3->mc_snum++; m3->mc_snum++;
m3->mc_top++; m3->mc_top++;