|
|
@ -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; |
|
|
|
|
|
|
|
|
|
|
|