|
|
|
@ -2551,10 +2551,14 @@ static inline void brt_split_init(BRT_SPLIT *split) { |
|
|
|
toku_init_dbt(&split->splitk); |
|
|
|
} |
|
|
|
|
|
|
|
static int brt_search_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, BRT_SPLIT *split, TOKULOGGER logger); |
|
|
|
static int brt_search_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, |
|
|
|
u_int64_t *est_left, |
|
|
|
BRT_SPLIT *split, TOKULOGGER logger); |
|
|
|
|
|
|
|
/* search in a node's child */ |
|
|
|
static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *search, DBT *newkey, DBT *newval, BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *search, DBT *newkey, DBT *newval, |
|
|
|
u_int64_t *est_left, // estimate number of items to left. |
|
|
|
BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
int r, rr; |
|
|
|
|
|
|
|
/* if the child's buffer is not empty then try to empty it */ |
|
|
|
@ -2572,7 +2576,7 @@ static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *s |
|
|
|
for (;;) { |
|
|
|
BRTNODE childnode = node_v; |
|
|
|
BRT_SPLIT childsplit; brt_split_init(&childsplit); |
|
|
|
r = brt_search_node(brt, childnode, search, newkey, newval, &childsplit, logger); |
|
|
|
r = brt_search_node(brt, childnode, search, newkey, newval, est_left, &childsplit, logger); |
|
|
|
if (childsplit.did_split) { |
|
|
|
rr = handle_split_of_child(brt, node, childnum, childsplit.nodea, childsplit.nodeb, &childsplit.splitk, |
|
|
|
&split->did_split, &split->nodea, &split->nodeb, &split->splitk, logger); |
|
|
|
@ -2590,8 +2594,8 @@ static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *s |
|
|
|
return r; |
|
|
|
} |
|
|
|
|
|
|
|
static int brt_search_nonleaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
int r = DB_NOTFOUND; |
|
|
|
static int brt_search_nonleaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, u_int64_t *est_left, BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
int r; |
|
|
|
int c; |
|
|
|
|
|
|
|
/* binary search is overkill for a small array */ |
|
|
|
@ -2608,16 +2612,37 @@ static int brt_search_nonleaf_node(BRT brt, BRTNODE node, brt_search_t *search, |
|
|
|
if (search->compare(search, |
|
|
|
toku_fill_dbt(&pivotkey, kv_pair_key(pivot), kv_pair_keylen(pivot)), |
|
|
|
brt->flags & TOKU_DB_DUPSORT ? toku_fill_dbt(&pivotval, kv_pair_val(pivot), kv_pair_vallen(pivot)): 0)) { |
|
|
|
r = brt_search_child(brt, node, child[c], search, newkey, newval, split, logger); |
|
|
|
if (r == 0 || r == EAGAIN) |
|
|
|
break; |
|
|
|
r = brt_search_child(brt, node, child[c], search, newkey, newval, est_left, split, logger); |
|
|
|
if (r == 0) { |
|
|
|
if (est_left) { |
|
|
|
int i; |
|
|
|
for (i=0; i<c; i++) |
|
|
|
*est_left += BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, child[i]); |
|
|
|
} |
|
|
|
return r; |
|
|
|
} else if (r == EAGAIN) { |
|
|
|
return r; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* check the first (left) or last (right) node if nothing has been found */ |
|
|
|
if (r == DB_NOTFOUND && c == node->u.n.n_children-1) |
|
|
|
r = brt_search_child(brt, node, child[c], search, newkey, newval, split, logger); |
|
|
|
|
|
|
|
r = brt_search_child(brt, node, child[c], search, newkey, newval, est_left, split, logger); |
|
|
|
if (r == 0) { |
|
|
|
if (est_left) { |
|
|
|
int i; |
|
|
|
for (i=0; i+1<c; i++) |
|
|
|
*est_left += BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, child[i]); |
|
|
|
} |
|
|
|
return r; |
|
|
|
} else if (r == DB_NOTFOUND) { |
|
|
|
if (est_left) { |
|
|
|
int i; |
|
|
|
for (i=0; i<c; i++) |
|
|
|
*est_left += BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, child[i]); |
|
|
|
} |
|
|
|
return r; |
|
|
|
} |
|
|
|
return r; |
|
|
|
} |
|
|
|
|
|
|
|
@ -2666,7 +2691,7 @@ static int bessel_from_search_t (OMTVALUE lev, void *extra) { |
|
|
|
LESWITCHCALL(leafval, pair_leafval_bessel, search); |
|
|
|
} |
|
|
|
|
|
|
|
static int brt_search_leaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval) { |
|
|
|
static int brt_search_leaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, u_int64_t *est_left) { |
|
|
|
// Now we have to convert from brt_search_t to the bessel function with a direction. What a pain... |
|
|
|
int direction; |
|
|
|
switch (search->direction) { |
|
|
|
@ -2682,7 +2707,16 @@ static int brt_search_leaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT |
|
|
|
search, |
|
|
|
direction, |
|
|
|
&datav, &idx); |
|
|
|
if (r!=0) return r; |
|
|
|
if (r!=0) { |
|
|
|
if (est_left) { |
|
|
|
switch (search->direction) { |
|
|
|
case BRT_SEARCH_LEFT: *est_left = toku_omt_size(node->u.l.buffer); return 0; |
|
|
|
case BRT_SEARCH_RIGHT: *est_left = 0; return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
return r; |
|
|
|
} |
|
|
|
if (est_left) *est_left = idx; |
|
|
|
|
|
|
|
LEAFENTRY le = datav; |
|
|
|
if (le_is_provdel(le)) { |
|
|
|
@ -2723,14 +2757,16 @@ static int brt_search_leaf_node(BRT brt, BRTNODE node, brt_search_t *search, DBT |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int brt_search_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
static int brt_search_node(BRT brt, BRTNODE node, brt_search_t *search, DBT *newkey, DBT *newval, |
|
|
|
u_int64_t *est_left, |
|
|
|
BRT_SPLIT *split, TOKULOGGER logger) { |
|
|
|
if (node->height > 0) |
|
|
|
return brt_search_nonleaf_node(brt, node, search, newkey, newval, split, logger); |
|
|
|
return brt_search_nonleaf_node(brt, node, search, newkey, newval, est_left, split, logger); |
|
|
|
else |
|
|
|
return brt_search_leaf_node(brt, node, search, newkey, newval); |
|
|
|
return brt_search_leaf_node(brt, node, search, newkey, newval, est_left); |
|
|
|
} |
|
|
|
|
|
|
|
int toku_brt_search(BRT brt, brt_search_t *search, DBT *newkey, DBT *newval, TOKULOGGER logger) { |
|
|
|
int toku_brt_search(BRT brt, brt_search_t *search, DBT *newkey, DBT *newval, u_int64_t *est_left, TOKULOGGER logger) { |
|
|
|
int r, rr; |
|
|
|
|
|
|
|
rr = toku_read_and_pin_brt_header(brt->cf, &brt->h); |
|
|
|
@ -2758,7 +2794,7 @@ int toku_brt_search(BRT brt, brt_search_t *search, DBT *newkey, DBT *newval, TOK |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
BRT_SPLIT split; brt_split_init(&split); |
|
|
|
r = brt_search_node(brt, node, search, newkey, newval, &split, logger); |
|
|
|
r = brt_search_node(brt, node, search, newkey, newval, est_left, &split, logger); |
|
|
|
|
|
|
|
if (split.did_split) { |
|
|
|
rr = brt_init_new_root(brt, split.nodea, split.nodeb, split.splitk, rootp, 0, &node); |
|
|
|
@ -2894,7 +2930,7 @@ static int brt_cursor_current(BRT_CURSOR cursor, int op, DBT *outkey, DBT *outva |
|
|
|
DBT newval; toku_init_dbt(&newval); newval.flags = DB_DBT_MALLOC; |
|
|
|
|
|
|
|
brt_search_t search; brt_search_init(&search, brt_cursor_compare_set, BRT_SEARCH_LEFT, &cursor->key, &cursor->val, cursor->brt); |
|
|
|
r = toku_brt_search(cursor->brt, &search, &newkey, &newval, logger); |
|
|
|
r = toku_brt_search(cursor->brt, &search, &newkey, &newval, (u_int64_t*)0,logger); |
|
|
|
if (r != 0 || compare_kv_xy(cursor->brt, &cursor->key, &cursor->val, &newkey, &newval) != 0) |
|
|
|
r = DB_KEYEMPTY; |
|
|
|
dbt_cleanup(&newkey); |
|
|
|
@ -2909,7 +2945,7 @@ static int brt_cursor_search(BRT_CURSOR cursor, brt_search_t *search, DBT *outke |
|
|
|
DBT newkey; toku_init_dbt(&newkey); newkey.flags = DB_DBT_MALLOC; |
|
|
|
DBT newval; toku_init_dbt(&newval); newval.flags = DB_DBT_MALLOC; |
|
|
|
|
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, logger); |
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, (u_int64_t*)0, logger); |
|
|
|
if (r == 0) { |
|
|
|
brt_cursor_set_key_val(cursor, &newkey, &newval); |
|
|
|
r = brt_cursor_copyout(cursor, outkey, outval); |
|
|
|
@ -2924,7 +2960,7 @@ static int brt_cursor_search_eq_kv_xy(BRT_CURSOR cursor, brt_search_t *search, D |
|
|
|
DBT newkey; toku_init_dbt(&newkey); newkey.flags = DB_DBT_MALLOC; |
|
|
|
DBT newval; toku_init_dbt(&newval); newval.flags = DB_DBT_MALLOC; |
|
|
|
|
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, logger); |
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, (u_int64_t*)0, logger); |
|
|
|
if (r == 0) { |
|
|
|
if (compare_kv_xy(cursor->brt, search->k, search->v, &newkey, &newval) == 0) { |
|
|
|
brt_cursor_set_key_val(cursor, &newkey, &newval); |
|
|
|
@ -2942,7 +2978,7 @@ static int brt_cursor_search_eq_k_x(BRT_CURSOR cursor, brt_search_t *search, DBT |
|
|
|
DBT newkey; toku_init_dbt(&newkey); newkey.flags = DB_DBT_MALLOC; |
|
|
|
DBT newval; toku_init_dbt(&newval); newval.flags = DB_DBT_MALLOC; |
|
|
|
|
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, logger); |
|
|
|
int r = toku_brt_search(cursor->brt, search, &newkey, &newval, (u_int64_t*)0, logger); |
|
|
|
if (r == 0) { |
|
|
|
if (compare_k_x(cursor->brt, search->k, &newkey) == 0) { |
|
|
|
brt_cursor_set_key_val(cursor, &newkey, &newval); |
|
|
|
|