Reduce excessive memcpy in mdb_split

vmware
Howard Chu 13 years ago
parent 027e1daa10
commit d27a7754f3
  1. 53
      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; unsigned int i, j, split_indx, nkeys, pmax;
MDB_node *node; MDB_node *node;
MDB_val sepkey, rkey, rdata; MDB_val sepkey, rkey, rdata;
MDB_page *copy; MDB_page *copy, *cptr;
MDB_dpage *mdp, *rdp, *pdp; MDB_dpage *mdp, *rdp, *pdp;
MDB_dhead *dh; MDB_dhead *dh;
DKBUF; DKBUF;
@ -3301,13 +3301,6 @@ mdb_split(MDB_txn *txn, MDB_dbi dbi, MDB_page **mpp, unsigned int *newindxp,
goto newsep; 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 /* For leaf pages, check the split point based on what
* fits where, since otherwise add_node can fail. * fits where, since otherwise add_node can fail.
*/ */
@ -3356,7 +3349,7 @@ split2:
sepkey.mv_size = newkey->mv_size; sepkey.mv_size = newkey->mv_size;
sepkey.mv_data = newkey->mv_data; sepkey.mv_data = newkey->mv_data;
} else { } else {
node = NODEPTR(copy, split_indx); node = NODEPTR(&mdp->p, split_indx);
sepkey.mv_size = node->mn_ksize; sepkey.mv_size = node->mn_ksize;
sepkey.mv_data = NODEKEY(node); sepkey.mv_data = NODEKEY(node);
} }
@ -3386,20 +3379,24 @@ newsep:
return rc; return rc;
} }
if (rc != MDB_SUCCESS) { if (rc != MDB_SUCCESS) {
free(copy);
return rc; return rc;
} }
for (i = j = 0; i <= NUMKEYS(copy); j++) { /* Move half of the keys to the right sibling. */
if (i < split_indx) { if ((copy = malloc(txn->mt_env->me_psize)) == NULL)
/* Re-insert in left sibling. */ return ENOMEM;
pdp = mdp;
} else { copy->mp_pgno = mdp->p.mp_pgno;
/* Insert in right sibling. */ copy->mp_flags = mdp->p.mp_flags;
if (i == split_indx) copy->mp_lower = PAGEHDRSZ;
/* Reset insert index for right sibling. */ copy->mp_upper = txn->mt_env->me_psize;
j = (i == newindx && ins_new); cptr = copy;
pdp = rdp; 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) { if (i == newindx && !ins_new) {
@ -3417,11 +3414,12 @@ newsep:
/* Update page and index for the new key. */ /* Update page and index for the new key. */
*newindxp = j; *newindxp = j;
*mpp = &pdp->p; if (cptr == &rdp->p)
} else if (i == NUMKEYS(copy)) { *mpp = cptr;
} else if (i == nkeys) {
break; break;
} else { } else {
node = NODEPTR(copy, i); node = NODEPTR(&mdp->p, i);
rkey.mv_data = NODEKEY(node); rkey.mv_data = NODEKEY(node);
rkey.mv_size = node->mn_ksize; rkey.mv_size = node->mn_ksize;
if (IS_LEAF(&mdp->p)) { if (IS_LEAF(&mdp->p)) {
@ -3439,8 +3437,15 @@ newsep:
rkey.mv_size = 0; 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; i<nkeys; i++)
mdp->p.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); free(copy);
return rc; return rc;

Loading…
Cancel
Save