ITS#8311 fix page_split from update_key

Check for top of stack. Usually the cursor only has height 1 when
calling page_split, but not always.
mdb.RE/0.9
Howard Chu 9 years ago
parent a9877f783a
commit f9d3dc8293
  1. 20
      libraries/liblmdb/mdb.c

@ -6391,16 +6391,18 @@ fix_parent:
* update branch key if there is a parent page * update branch key if there is a parent page
*/ */
if (mc->mc_top && !mc->mc_ki[mc->mc_top]) { if (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
unsigned short top = mc->mc_top; unsigned short dtop = 1;
mc->mc_top--; mc->mc_top--;
/* slot 0 is always an empty key, find real slot */ /* slot 0 is always an empty key, find real slot */
while (mc->mc_top && !mc->mc_ki[mc->mc_top]) while (mc->mc_top && !mc->mc_ki[mc->mc_top]) {
mc->mc_top--; mc->mc_top--;
dtop++;
}
if (mc->mc_ki[mc->mc_top]) if (mc->mc_ki[mc->mc_top])
rc2 = mdb_update_key(mc, key); rc2 = mdb_update_key(mc, key);
else else
rc2 = MDB_SUCCESS; rc2 = MDB_SUCCESS;
mc->mc_top = top; mc->mc_top += dtop;
if (rc2) if (rc2)
return rc2; return rc2;
} }
@ -8249,12 +8251,14 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
rp->mp_pad = mp->mp_pad; rp->mp_pad = mp->mp_pad;
DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno)); DPRINTF(("new right sibling: page %"Z"u", rp->mp_pgno));
if (mc->mc_snum < 2) { if (mc->mc_top < 1) {
if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp))) if ((rc = mdb_page_new(mc, P_BRANCH, 1, &pp)))
goto done; goto done;
/* shift current top to make room for new parent */ /* shift current top to make room for new parent */
mc->mc_pg[1] = mc->mc_pg[0]; for (i=mc->mc_snum; i>0; i--) {
mc->mc_ki[1] = mc->mc_ki[0]; mc->mc_pg[i] = mc->mc_pg[i-1];
mc->mc_ki[i] = mc->mc_ki[i-1];
}
mc->mc_pg[0] = pp; mc->mc_pg[0] = pp;
mc->mc_ki[0] = 0; mc->mc_ki[0] = 0;
mc->mc_db->md_root = pp->mp_pgno; mc->mc_db->md_root = pp->mp_pgno;
@ -8270,8 +8274,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
mc->mc_db->md_depth--; mc->mc_db->md_depth--;
goto done; goto done;
} }
mc->mc_snum = 2; mc->mc_snum++;
mc->mc_top = 1; mc->mc_top++;
ptop = 0; ptop = 0;
} else { } else {
ptop = mc->mc_top-1; ptop = mc->mc_top-1;

Loading…
Cancel
Save