mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: backport - 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. Change-Id: Iad221be30edac0f82b650f787e5dbe721cc978e0
This commit is contained in:
parent
4bdeed9bd3
commit
02da85169e
1
CHANGES
1
CHANGES
@ -16,6 +16,7 @@ LMDB 0.9.17 Release Engineering
|
|||||||
Fix ITS#7789 ensure mapsize >= pages in use
|
Fix ITS#7789 ensure mapsize >= pages in use
|
||||||
Fix ITS#7971 mdb_txn_renew0() new reader slots
|
Fix ITS#7971 mdb_txn_renew0() new reader slots
|
||||||
Fix ITS#7969 use __sync_synchronize on non-x86
|
Fix ITS#7969 use __sync_synchronize on non-x86
|
||||||
|
Fix ITS#8311 page_split from update_key
|
||||||
Added mdb_txn_id() (ITS#7994)
|
Added mdb_txn_id() (ITS#7994)
|
||||||
Added robust mutex support
|
Added robust mutex support
|
||||||
Miscellaneous cleanup/simplification
|
Miscellaneous cleanup/simplification
|
||||||
|
25
mdb.c
25
mdb.c
@ -6509,16 +6509,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;
|
||||||
}
|
}
|
||||||
@ -8398,12 +8400,19 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
|
|||||||
rp->mp_ksize = mp->mp_ksize;
|
rp->mp_ksize = mp->mp_ksize;
|
||||||
mdb_debug("new right sibling: page %zu", rp->mp_pgno);
|
mdb_debug("new right sibling: page %zu", rp->mp_pgno);
|
||||||
|
|
||||||
if (mc->mc_snum < 2) {
|
/* Usually when splitting the root page, the cursor
|
||||||
|
* height is 1. But when called from mdb_update_key,
|
||||||
|
* the cursor height may be greater because it walks
|
||||||
|
* up the stack while finding the branch slot to update.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
@ -8419,8 +8428,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…
Reference in New Issue
Block a user