Fix mdb_split, fix MDB_GET_BOTH

vmware
Howard Chu 13 years ago
parent e91dae3ed5
commit 9d821c26c3
  1. 19
      libraries/libmdb/mdb.c

@ -2580,6 +2580,7 @@ set2:
int ex2, *ex2p; int ex2, *ex2p;
if (op == MDB_GET_BOTH) { if (op == MDB_GET_BOTH) {
ex2p = &ex2; ex2p = &ex2;
ex2 = 0;
} else { } else {
ex2p = NULL; ex2p = NULL;
} }
@ -3662,34 +3663,32 @@ mdb_split(MDB_txn *txn, MDB_dbi dbi, MDB_page **mpp, unsigned int *newindxp,
/* Maximum free space in an empty page */ /* Maximum free space in an empty page */
pmax = txn->mt_env->me_psize - PAGEHDRSZ; pmax = txn->mt_env->me_psize - PAGEHDRSZ;
nsize = mdb_leaf_size(txn->mt_env, newkey, newdata); nsize = mdb_leaf_size(txn->mt_env, newkey, newdata);
if (newindx <= split_indx) { if (newindx < split_indx) {
split1:
psize = nsize; psize = nsize;
for (i=0; i<split_indx; i++) { for (i=0; i<split_indx; i++) {
node = NODEPTR(&mdp->p, i); node = NODEPTR(&mdp->p, i);
psize += NODESIZE + NODEKSZ(node); psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t);
if (F_ISSET(node->mn_flags, F_BIGDATA)) if (F_ISSET(node->mn_flags, F_BIGDATA))
psize += sizeof(pgno_t); psize += sizeof(pgno_t);
else else
psize += NODEDSZ(node); psize += NODEDSZ(node);
if (psize > pmax) { if (psize > pmax) {
split_indx--; split_indx = i;
goto split1; break;
} }
} }
} else { } else {
split2:
psize = nsize; psize = nsize;
for (i=split_indx; i<nkeys; i++) { for (i=nkeys-1; i>=split_indx; i--) {
node = NODEPTR(&mdp->p, i); node = NODEPTR(&mdp->p, i);
psize += NODESIZE + NODEKSZ(node); psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t);
if (F_ISSET(node->mn_flags, F_BIGDATA)) if (F_ISSET(node->mn_flags, F_BIGDATA))
psize += sizeof(pgno_t); psize += sizeof(pgno_t);
else else
psize += NODEDSZ(node); psize += NODEDSZ(node);
if (psize > pmax) { if (psize > pmax) {
split_indx++; split_indx = i+1;
goto split2; break;
} }
} }
} }

Loading…
Cancel
Save