diff --git a/libraries/libmdb/mdb.c b/libraries/libmdb/mdb.c index d1efdd1..7487f7f 100644 --- a/libraries/libmdb/mdb.c +++ b/libraries/libmdb/mdb.c @@ -3216,7 +3216,7 @@ mdb_split(MDB_txn *txn, MDB_dbi dbi, MDB_page **mpp, unsigned int *newindxp, unsigned int i, j, split_indx, nkeys, pmax; MDB_node *node; MDB_val sepkey, rkey, rdata; - MDB_page *copy; + MDB_page *copy, *cptr; MDB_dpage *mdp, *rdp, *pdp; MDB_dhead *dh; DKBUF; @@ -3301,13 +3301,6 @@ mdb_split(MDB_txn *txn, MDB_dbi dbi, MDB_page **mpp, unsigned int *newindxp, goto newsep; } - /* Move half of the keys to the right sibling. */ - if ((copy = malloc(txn->mt_env->me_psize)) == NULL) - return ENOMEM; - memcpy(copy, &mdp->p, txn->mt_env->me_psize); - memset(&mdp->p.mp_ptrs, 0, txn->mt_env->me_psize - PAGEHDRSZ); - mdp->p.mp_lower = PAGEHDRSZ; - mdp->p.mp_upper = txn->mt_env->me_psize; /* For leaf pages, check the split point based on what * fits where, since otherwise add_node can fail. */ @@ -3356,7 +3349,7 @@ split2: sepkey.mv_size = newkey->mv_size; sepkey.mv_data = newkey->mv_data; } else { - node = NODEPTR(copy, split_indx); + node = NODEPTR(&mdp->p, split_indx); sepkey.mv_size = node->mn_ksize; sepkey.mv_data = NODEKEY(node); } @@ -3386,20 +3379,24 @@ newsep: return rc; } if (rc != MDB_SUCCESS) { - free(copy); return rc; } - for (i = j = 0; i <= NUMKEYS(copy); j++) { - if (i < split_indx) { - /* Re-insert in left sibling. */ - pdp = mdp; - } else { - /* Insert in right sibling. */ - if (i == split_indx) - /* Reset insert index for right sibling. */ - j = (i == newindx && ins_new); - pdp = rdp; + /* Move half of the keys to the right sibling. */ + if ((copy = malloc(txn->mt_env->me_psize)) == NULL) + return ENOMEM; + + copy->mp_pgno = mdp->p.mp_pgno; + copy->mp_flags = mdp->p.mp_flags; + copy->mp_lower = PAGEHDRSZ; + copy->mp_upper = txn->mt_env->me_psize; + cptr = copy; + for (i = j = 0; i <= nkeys; j++) { + if (i == split_indx) { + /* Insert in right sibling. */ + /* Reset insert index for right sibling. */ + j = (i == newindx && ins_new); + cptr = &rdp->p; } if (i == newindx && !ins_new) { @@ -3417,11 +3414,12 @@ newsep: /* Update page and index for the new key. */ *newindxp = j; - *mpp = &pdp->p; - } else if (i == NUMKEYS(copy)) { + if (cptr == &rdp->p) + *mpp = cptr; + } else if (i == nkeys) { break; } else { - node = NODEPTR(copy, i); + node = NODEPTR(&mdp->p, i); rkey.mv_data = NODEKEY(node); rkey.mv_size = node->mn_ksize; if (IS_LEAF(&mdp->p)) { @@ -3439,8 +3437,15 @@ newsep: rkey.mv_size = 0; } - rc = mdb_add_node(txn, dbi, &pdp->p, j, &rkey, &rdata, pgno,flags); + rc = mdb_add_node(txn, dbi, cptr, j, &rkey, &rdata, pgno, flags); } + nkeys = NUMKEYS(copy); + for (i=0; ip.mp_ptrs[i] = copy->mp_ptrs[i]; + mdp->p.mp_lower = copy->mp_lower; + mdp->p.mp_upper = copy->mp_upper; + memcpy(NODEPTR(&mdp->p, nkeys-1), NODEPTR(copy, nkeys-1), + txn->mt_env->me_psize - copy->mp_upper); free(copy); return rc;