"MDB_NOTFOUND: No matching key/data pair found",
"MDB_PAGE_NOTFOUND: Requested page not found",
"MDB_CORRUPTED: Located page was wrong type",
- "MDB_PANIC: Update of meta page failed, or environment had fatal error",
+ "MDB_PANIC: Update of meta page failed",
"MDB_VERSION_MISMATCH: Database environment version mismatch",
"MDB_INVALID: File is not an MDB file",
"MDB_MAP_FULL: Environment mapsize limit reached",
mop += mop_len;
rc = mdb_cursor_first(&mc, &key, &data);
for (; !rc; rc = mdb_cursor_next(&mc, &key, &data, MDB_NEXT)) {
- unsigned flags = MDB_CURRENT;
txnid_t id = *(txnid_t *)key.mv_data;
ssize_t len = (ssize_t)(data.mv_size / sizeof(MDB_ID)) - 1;
MDB_ID save;
mdb_tassert(txn, len >= 0 && id <= env->me_pglast);
+ key.mv_data = &id;
if (len > mop_len) {
len = mop_len;
data.mv_size = (len + 1) * sizeof(MDB_ID);
- /* Drop MDB_CURRENT when changing the data size */
- key.mv_data = &id;
- flags = 0;
}
data.mv_data = mop -= len;
save = mop[0];
mop[0] = len;
- rc = mdb_cursor_put(&mc, &key, &data, flags);
+ rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT);
mop[0] = save;
if (rc || !(mop_len -= len))
break;
unsigned int nflags;
DKBUF;
- if (mc == NULL)
+ if (mc == NULL || key == NULL)
return EINVAL;
env = mc->mc_txn->mt_env;
if (mc->mc_txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
return (mc->mc_txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
- if (flags != MDB_CURRENT) {
- if (key == NULL)
- return EINVAL;
- if (key->mv_size-1 >= ENV_MAXKEY(env))
- return MDB_BAD_VALSIZE;
- } else {
- /* Ignore key except in sub-cursor, where key holds the data */
- if (!(mc->mc_flags & C_SUB))
- key = NULL;
- }
+ if (flags != MDB_CURRENT && key->mv_size-1 >= ENV_MAXKEY(env))
+ return MDB_BAD_VALSIZE;
#if SIZE_MAX > MAXDATASIZE
if (data->mv_size > ((mc->mc_db->md_flags & MDB_DUPSORT) ? ENV_MAXKEY(env) : MAXDATASIZE))
goto done;
}
mdb_node_del(mc, 0);
- mc->mc_db->md_entries--;
}
rdata = data;
/* sub-writes might have failed so check rc again.
* Don't increment count if we just replaced an existing item.
*/
- if (!rc && !(flags & MDB_CURRENT))
+ if (!rc && insert)
mc->mc_db->md_entries++;
if (flags & MDB_MULTIPLE) {
if (!rc) {
int rc;
unsigned int ptop, minkeys;
MDB_cursor mn;
+ indx_t oldki;
minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top]));
DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)",
mdb_cursor_copy(mc, &mn);
mn.mc_xcursor = NULL;
+ oldki = mc->mc_ki[mc->mc_top];
if (mc->mc_ki[ptop] == 0) {
/* We're the leftmost leaf in our parent.
*/
* (A branch page must never have less than 2 keys.)
*/
minkeys = 1 + (IS_BRANCH(mn.mc_pg[mn.mc_top]));
- if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys)
- return mdb_node_move(&mn, mc);
- else {
- if (mc->mc_ki[ptop] == 0)
+ if (PAGEFILL(mc->mc_txn->mt_env, mn.mc_pg[mn.mc_top]) >= FILL_THRESHOLD && NUMKEYS(mn.mc_pg[mn.mc_top]) > minkeys) {
+ rc = mdb_node_move(&mn, mc);
+ if (mc->mc_ki[ptop] == 0) {
+ mc->mc_ki[mc->mc_top] = oldki;
+ } else {
+ mc->mc_ki[mc->mc_top] = oldki + 1;
+ }
+ } else {
+ if (mc->mc_ki[ptop] == 0) {
rc = mdb_page_merge(&mn, mc);
- else {
+ mc->mc_ki[mc->mc_top] = oldki;
+ } else {
+ unsigned int nkeys = NUMKEYS(mn.mc_pg[mn.mc_top]);
mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
rc = mdb_page_merge(mc, &mn);
- mdb_cursor_copy(&mn, mc);
+ mc->mc_pg[mc->mc_top] = mn.mc_pg[mn.mc_top];
+ mc->mc_ki[mc->mc_top] = oldki + nkeys;
}
- mc->mc_flags &= ~(C_INITIALIZED|C_EOF);
+ mc->mc_flags &= ~C_EOF;
}
return rc;
}