Delay touching pages until cursor is positioned.

This avoids unnecessary rewrites of pages that do not change.
(Restructuring for upcoming mdb_page_spill work.)
vmware
Howard Chu 12 years ago
parent c09db5757d
commit d7bc4baf63
  1. 50
      libraries/liblmdb/mdb.c

@ -4968,6 +4968,7 @@ int
mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data, mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
unsigned int flags) unsigned int flags)
{ {
enum { MDB_NO_ROOT = MDB_LAST_ERRCODE+10 }; /* internal code */
MDB_node *leaf = NULL; MDB_node *leaf = NULL;
MDB_val xdata, *rdata, dkey; MDB_val xdata, *rdata, dkey;
MDB_page *fp; MDB_page *fp;
@ -5015,23 +5016,10 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
return EINVAL; return EINVAL;
rc = MDB_SUCCESS; rc = MDB_SUCCESS;
} else if (mc->mc_db->md_root == P_INVALID) { } else if (mc->mc_db->md_root == P_INVALID) {
MDB_page *np; /* new database, cursor has nothing to point to */
/* new database, write a root leaf page */
DPUTS("allocating new root leaf page");
if ((rc = mdb_page_new(mc, P_LEAF, 1, &np))) {
return rc;
}
mc->mc_snum = 0; mc->mc_snum = 0;
mdb_cursor_push(mc, np); mc->mc_flags &= ~C_INITIALIZED;
mc->mc_db->md_root = np->mp_pgno; rc = MDB_NO_ROOT;
mc->mc_db->md_depth++;
*mc->mc_dbflag |= DB_DIRTY;
if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED))
== MDB_DUPFIXED)
np->mp_flags |= P_LEAF2;
mc->mc_flags |= C_INITIALIZED;
rc = MDB_NOTFOUND;
goto top;
} else { } else {
int exact = 0; int exact = 0;
MDB_val d2; MDB_val d2;
@ -5049,7 +5037,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
} }
} }
} else { } else {
rc = mdb_cursor_set(mc, key, &d2, MDB_SET, &exact); rc = mdb_cursor_set(mc, key, &d2, MDB_SET, &exact);
} }
if ((flags & MDB_NOOVERWRITE) && rc == 0) { if ((flags & MDB_NOOVERWRITE) && rc == 0) {
DPRINTF("duplicate key [%s]", DKEY(key)); DPRINTF("duplicate key [%s]", DKEY(key));
@ -5060,12 +5048,30 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
return rc; return rc;
} }
/* Cursor is positioned, now make sure all pages are writable */ /* Cursor is positioned */
rc2 = mdb_cursor_touch(mc);
if (rc2) if (rc == MDB_NO_ROOT) {
return rc2; MDB_page *np;
/* new database, write a root leaf page */
DPUTS("allocating new root leaf page");
if ((rc2 = mdb_page_new(mc, P_LEAF, 1, &np))) {
return rc2;
}
mdb_cursor_push(mc, np);
mc->mc_db->md_root = np->mp_pgno;
mc->mc_db->md_depth++;
*mc->mc_dbflag |= DB_DIRTY;
if ((mc->mc_db->md_flags & (MDB_DUPSORT|MDB_DUPFIXED))
== MDB_DUPFIXED)
np->mp_flags |= P_LEAF2;
mc->mc_flags |= C_INITIALIZED;
} else {
/* make sure all cursor pages are writable */
rc2 = mdb_cursor_touch(mc);
if (rc2)
return rc2;
}
top:
/* The key already exists */ /* The key already exists */
if (rc == MDB_SUCCESS) { if (rc == MDB_SUCCESS) {
/* there's only a key anyway, so this is a no-op */ /* there's only a key anyway, so this is a no-op */

Loading…
Cancel
Save