Commit af4fc44e authored by Yoni Fogel's avatar Yoni Fogel

Addresses #523

Cleaned up iteration code based on code review.
Changed iteration return value to EDOM when you try to iterate after an insert, in
redblacktrees

git-svn-id: file:///svn/tokudb@2793 c7de825b-a66e-492c-adef-691d508d4ae1
parent 2f5edae6
...@@ -24,23 +24,21 @@ struct __toku_range_tree_local { ...@@ -24,23 +24,21 @@ struct __toku_range_tree_local {
struct toku_rbt_tree* rbt; struct toku_rbt_tree* rbt;
/* /*
* if iter_at_beginning is TRUE, then iteration is at beginning, * if iter_at_beginning is TRUE, then iteration is at beginning,
* if iter_at_beginning is FALSE and iterator_finger is NOT NULL, * if iter_at_beginning is FALSE and iter_finger is NOT NULL,
* iteration is ongoing, * iteration is ongoing,
* if iter_at_beginning is FALSE and iterator_finger is NULL, * if iter_at_beginning is FALSE and iter_finger is NULL,
* iteration has ended or in invalid state. * iteration has ended or in invalid state.
*/ */
/* /*
* BOOL that says if iteration is at beginning. * BOOL that says whether we are allowed to iterate.
* If at beginning, toku_rt_next returns first element
* in the range_tree, otherwise returns successor of curr_range
*/ */
BOOL iter_at_beginning; BOOL iter_is_valid;
/** /**
* The range we are currently at in the iterator, if it is set to NULL, that means * The range we are currently at in the iterator, if it is set to NULL, that means
* the iteration is no longer valid and/or the iteration is done * the iteration is no longer valid and/or the iteration is done
* */ * */
struct toku_rbt_node* iterator_finger; struct toku_rbt_node* iter_finger;
}; };
#include <rangetree-internal.h> #include <rangetree-internal.h>
...@@ -56,6 +54,10 @@ lookup (type) returns: ...@@ -56,6 +54,10 @@ lookup (type) returns:
Finger usefulness: Finger usefulness:
*/ */
static inline void toku_rt_invalidate_iteration(toku_range_tree* tree) {
tree->i.iter_is_valid = FALSE;
}
//FIRST PASS //FIRST PASS
int toku_rt_create(toku_range_tree** ptree, int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(const toku_point*,const toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
...@@ -80,8 +82,7 @@ int toku_rt_create(toku_range_tree** ptree, ...@@ -80,8 +82,7 @@ int toku_rt_create(toku_range_tree** ptree,
* Start range tree in invalid iteration state, toku_rt_start_scan must * Start range tree in invalid iteration state, toku_rt_start_scan must
* be called to start iteration * be called to start iteration
*/ */
temptree->i.iter_at_beginning = FALSE; toku_rt_invalidate_iteration(temptree);
temptree->i.iterator_finger = NULL;
*ptree = temptree; *ptree = temptree;
r = 0; r = 0;
cleanup: cleanup:
...@@ -210,7 +211,7 @@ int toku_rt_insert(toku_range_tree* tree, toku_range* range) { ...@@ -210,7 +211,7 @@ int toku_rt_insert(toku_range_tree* tree, toku_range* range) {
/* /*
* invalidate iteration, because we have inserted node * invalidate iteration, because we have inserted node
*/ */
tree->i.iterator_finger = NULL; toku_rt_invalidate_iteration(tree);
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
...@@ -251,7 +252,7 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range) { ...@@ -251,7 +252,7 @@ int toku_rt_delete(toku_range_tree* tree, toku_range* range) {
/* /*
* invalidate iteration, because we have deleted node * invalidate iteration, because we have deleted node
*/ */
tree->i.iterator_finger = NULL; toku_rt_invalidate_iteration(tree);
tree->numelements--; tree->numelements--;
r = 0; r = 0;
cleanup: cleanup:
...@@ -363,8 +364,9 @@ int toku_rt_get_size(toku_range_tree* tree, u_int32_t* size) { ...@@ -363,8 +364,9 @@ int toku_rt_get_size(toku_range_tree* tree, u_int32_t* size) {
void toku_rt_start_scan (toku_range_tree* range_tree) { void toku_rt_start_scan (toku_range_tree* range_tree) {
assert(range_tree); assert(range_tree);
range_tree->i.iter_at_beginning = TRUE; range_tree->i.iter_is_valid = TRUE;
range_tree->i.iterator_finger = NULL; /* NULL finger means we have not gotten any yet (beginning). */
range_tree->i.iter_finger = NULL;
return; return;
} }
...@@ -372,33 +374,32 @@ int toku_rt_next (toku_range_tree* range_tree, toku_range* out_range, BOOL* elem ...@@ -372,33 +374,32 @@ int toku_rt_next (toku_range_tree* range_tree, toku_range* out_range, BOOL* elem
int r = ENOSYS; int r = ENOSYS;
toku_range* ret_range = NULL; toku_range* ret_range = NULL;
struct toku_rbt_node* ignore_insert = NULL; struct toku_rbt_node* ignore_insert = NULL;
if (!range_tree || !out_range) { r = EINVAL; goto cleanup; }
/* Check to see if range tree is in invalid iteation state */
if (!range_tree->i.iter_at_beginning && !range_tree->i.iterator_finger){
r = EDOM; goto cleanup;
}
if (range_tree->i.iter_at_beginning) { if (!range_tree || !out_range || !elem_found) { r = EINVAL; goto cleanup; }
/* Check to see if range tree is in invalid iteration state */
if (!range_tree->i.iter_is_valid) { r = EDOM; goto cleanup; }
if (range_tree->i.iter_finger == NULL) {
/* Initial scan */
r = toku_rbt_lookup(RB_LUFIRST, NULL, range_tree->i.rbt, r = toku_rbt_lookup(RB_LUFIRST, NULL, range_tree->i.rbt,
&ignore_insert, &range_tree->i.iterator_finger, &ret_range); &ignore_insert, &range_tree->i.iter_finger, &ret_range);
if (r != 0) { goto cleanup; } if (r != 0) { goto cleanup; }
} }
else { else {
/* Repeated successor queries. */
/* /*
* If there is no successor because we have arrived at the end of the iteration, * If there is no successor because we have arrived at the end of the iteration,
* or because of some unexpected error, ret_range will have the value of NULL, * or because of some unexpected error, ret_range will have the value of NULL,
* which we want to return to the user in such cases * which we want to return to the user in such cases
*/ */
r = toku_rbt_finger_successor(&range_tree->i.iterator_finger, &ret_range); r = toku_rbt_finger_successor(&range_tree->i.iter_finger, &ret_range);
if (r != 0) { goto cleanup; } if (r != 0) { goto cleanup; }
} }
if (ret_range) { range_tree->i.iter_is_valid = ret_range != NULL;
*elem_found = TRUE; *elem_found = range_tree->i.iter_is_valid;
*out_range = *ret_range; if (*elem_found) { *out_range = *ret_range; }
}
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
} }
......
...@@ -621,8 +621,8 @@ int toku_rbt_finger_successor(struct toku_rbt_node** pfinger, ...@@ -621,8 +621,8 @@ int toku_rbt_finger_successor(struct toku_rbt_node** pfinger,
toku_range** psucc_data) { toku_range** psucc_data) {
int r = ENOSYS; int r = ENOSYS;
if (!pfinger || !*pfinger || if (!pfinger || !*pfinger || !psucc_data) { r = EINVAL; goto cleanup; }
*pfinger == RBNULL || !psucc_data) { r = EINVAL; goto cleanup; } if (*pfinger == RBNULL) { r = EDOM; goto cleanup; }
*pfinger = toku_rbt__successor(*pfinger); *pfinger = toku_rbt__successor(*pfinger);
*psucc_data = (toku_range*) *psucc_data = (toku_range*)
((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key)); ((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment