Tweak search_node inner loop to avoid LEAF2 checks

vmware
Howard Chu 13 years ago
parent 70c79df1df
commit 56fe0d4f1a
  1. 78
      libraries/libmdb/mdb.c

@ -2413,36 +2413,43 @@ mdb_search_node(MDB_cursor *mc, MDB_val *key, int *exactp)
if (IS_LEAF2(mp)) { if (IS_LEAF2(mp)) {
nodekey.mv_size = mc->mc_db->md_pad; nodekey.mv_size = mc->mc_db->md_pad;
node = NODEPTR(mp, 0); /* fake */ node = NODEPTR(mp, 0); /* fake */
} while (low <= high) {
while (low <= high) { i = (low + high) >> 1;
i = (low + high) >> 1;
if (IS_LEAF2(mp)) {
nodekey.mv_data = LEAF2KEY(mp, i, nodekey.mv_size); nodekey.mv_data = LEAF2KEY(mp, i, nodekey.mv_size);
} else { rc = cmp(key, &nodekey);
node = NODEPTR(mp, i); DPRINTF("found leaf index %u [%s], rc = %i",
i, DKEY(&nodekey), rc);
nodekey.mv_size = node->mn_ksize; if (rc == 0)
nodekey.mv_data = NODEKEY(node); break;
if (rc > 0)
low = i + 1;
else
high = i - 1;
} }
} else {
while (low <= high) {
i = (low + high) >> 1;
rc = cmp(key, &nodekey); node = NODEPTR(mp, i);
nodekey.mv_size = NODEKSZ(node);
nodekey.mv_data = NODEKEY(node);
rc = cmp(key, &nodekey);
#if DEBUG #if DEBUG
if (IS_LEAF(mp)) if (IS_LEAF(mp))
DPRINTF("found leaf index %u [%s], rc = %i", DPRINTF("found leaf index %u [%s], rc = %i",
i, DKEY(&nodekey), rc); i, DKEY(&nodekey), rc);
else else
DPRINTF("found branch index %u [%s -> %zu], rc = %i", DPRINTF("found branch index %u [%s -> %zu], rc = %i",
i, DKEY(&nodekey), NODEPGNO(node), rc); i, DKEY(&nodekey), NODEPGNO(node), rc);
#endif #endif
if (rc == 0)
if (rc == 0) break;
break; if (rc > 0)
if (rc > 0) low = i + 1;
low = i + 1; else
else high = i - 1;
high = i - 1; }
} }
if (rc > 0) { /* Found entry is less than the key. */ if (rc > 0) { /* Found entry is less than the key. */
@ -2530,36 +2537,41 @@ mdb_search_page_root(MDB_cursor *mc, MDB_val *key, int modify)
while (IS_BRANCH(mp)) { while (IS_BRANCH(mp)) {
MDB_node *node; MDB_node *node;
indx_t i;
DPRINTF("branch page %zu has %u keys", mp->mp_pgno, NUMKEYS(mp)); DPRINTF("branch page %zu has %u keys", mp->mp_pgno, NUMKEYS(mp));
assert(NUMKEYS(mp) > 1); assert(NUMKEYS(mp) > 1);
DPRINTF("found index 0 to page %zu", NODEPGNO(NODEPTR(mp, 0))); DPRINTF("found index 0 to page %zu", NODEPGNO(NODEPTR(mp, 0)));
if (key == NULL) /* Initialize cursor to first page. */ if (key == NULL) /* Initialize cursor to first page. */
mc->mc_ki[mc->mc_top] = 0; i = 0;
else if (key->mv_size > MAXKEYSIZE && key->mv_data == NULL) { else if (key->mv_size > MAXKEYSIZE && key->mv_data == NULL) {
/* cursor to last page */ /* cursor to last page */
mc->mc_ki[mc->mc_top] = NUMKEYS(mp)-1; i = NUMKEYS(mp)-1;
} else { } else {
int exact; int exact;
node = mdb_search_node(mc, key, &exact); node = mdb_search_node(mc, key, &exact);
if (node == NULL) if (node == NULL)
mc->mc_ki[mc->mc_top] = NUMKEYS(mp) - 1; i = NUMKEYS(mp) - 1;
else if (!exact) { else {
assert(mc->mc_ki[mc->mc_top] > 0); i = mc->mc_ki[mc->mc_top];
mc->mc_ki[mc->mc_top]--; if (!exact) {
assert(i > 0);
i--;
}
} }
} }
if (key) if (key)
DPRINTF("following index %u for key [%s]", DPRINTF("following index %u for key [%s]",
mc->mc_ki[mc->mc_top], DKEY(key)); i, DKEY(key));
assert(mc->mc_ki[mc->mc_top] < NUMKEYS(mp)); assert(i < NUMKEYS(mp));
node = NODEPTR(mp, mc->mc_ki[mc->mc_top]); node = NODEPTR(mp, i);
if ((rc = mdb_get_page(mc->mc_txn, NODEPGNO(node), &mp))) if ((rc = mdb_get_page(mc->mc_txn, NODEPGNO(node), &mp)))
return rc; return rc;
mc->mc_ki[mc->mc_top] = i;
if ((rc = cursor_push_page(mc, mp))) if ((rc = cursor_push_page(mc, mp)))
return rc; return rc;

Loading…
Cancel
Save