Commit d17ca6b7 authored by Yoni Fogel's avatar Yoni Fogel

Addresses #724

Tests for insert.
BUGFIX: Insert now properly returns DB_KEYEXIST if the heaviside function
returns 0 for some value in the tree.

git-svn-id: file:///svn/tokudb@3601 c7de825b-a66e-492c-adef-691d508d4ae1
parent 03e19f40
......@@ -245,10 +245,9 @@ void test_fetch_verify (void) {
u_int32_t i;
int r;
OMTVALUE v = (OMTVALUE)&i;
OMTVALUE oldv;
OMTVALUE oldv = v;
assert(length == toku_omt_size(omt));
for (i = 0; i < length; i++) {
oldv = v;
assert(oldv!=values[i]);
v = NULL;
r = toku_omt_fetch(omt, i, &v);
......@@ -266,7 +265,6 @@ void test_fetch_verify (void) {
assert(v == values[i]);
assert(v->number == values[i]->number);
}
oldv = v;
for (i = length; i < length*2; i++) {
v = oldv;
r = toku_omt_fetch(omt, i, &v);
......@@ -388,6 +386,69 @@ void test_create_set_at(enum create_type create_choice, enum close_when_done clo
test_close(close);
}
int insert_helper(OMTVALUE value, void* extra_insert) {
OMTVALUE to_insert = (OMTVALUE)extra_insert;
assert(to_insert);
if (value->number < to_insert->number) return -1;
if (value->number > to_insert->number) return +1;
return 0;
}
void test_create_insert(enum close_when_done close) {
u_int32_t i = 0;
u_int32_t* perm = NULL;
MALLOC_N(length, perm);
assert(perm);
permute_array(perm, length);
test_create(KEEP_WHEN_DONE);
int r;
u_int32_t size = length;
length = 0;
while (length < size) {
u_int32_t choice = perm[length];
OMTVALUE to_insert = &nums[choice];
u_int32_t idx = UINT32_MAX;
assert(length==toku_omt_size(omt));
r = toku_omt_insert(omt, to_insert, insert_helper, to_insert, &idx);
CKERR(r);
assert(idx <= length);
if (idx > 0) {
assert(to_insert->number > values[idx-1]->number);
}
if (idx < length) {
assert(to_insert->number < values[idx]->number);
}
length++;
assert(length==toku_omt_size(omt));
/* Make room */
for (i = length-1; i > idx; i--) {
values[i] = values[i-1];
}
values[idx] = to_insert;
test_fetch_verify();
test_iterate_verify();
idx = UINT32_MAX;
r = toku_omt_insert(omt, to_insert, insert_helper, to_insert, &idx);
CKERR2(r, DB_KEYEXIST);
assert(idx < length);
assert(values[idx]->number == to_insert->number);
assert(length==toku_omt_size(omt));
test_iterate_verify();
test_fetch_verify();
}
toku_free(perm);
test_close(close);
}
void test_create_delete_at(enum create_type create_choice, enum close_when_done close) {
u_int32_t i = 0;
int r = ENOSYS;
......@@ -421,7 +482,7 @@ void test_create_delete_at(enum create_type create_choice, enum close_when_done
test_close(close);
}
void test_create_array(enum create_type create_choice, enum rand_type rand_choice) {
void init_values(enum rand_type rand_choice) {
if (rand_choice == TEST_RANDOM) {
init_distinct_random_values(random_seed, 100);
}
......@@ -432,18 +493,28 @@ void test_create_array(enum create_type create_choice, enum rand_type rand_choic
init_identity_values(random_seed, 100);
}
else assert(FALSE);
}
void test_create_array(enum create_type create_choice, enum rand_type rand_choice) {
/* ********************************************************************** */
init_values(rand_choice);
test_create_from_sorted_array( create_choice, CLOSE_WHEN_DONE);
test_create_from_sorted_array_size(create_choice, CLOSE_WHEN_DONE);
/* ********************************************************************** */
init_values(rand_choice);
test_create_fetch_verify( create_choice, CLOSE_WHEN_DONE);
/* ********************************************************************** */
init_values(rand_choice);
test_create_iterate_verify( create_choice, CLOSE_WHEN_DONE);
/* ********************************************************************** */
init_values(rand_choice);
test_create_set_at( create_choice, CLOSE_WHEN_DONE);
/* ********************************************************************** */
init_values(rand_choice);
test_create_delete_at( create_choice, CLOSE_WHEN_DONE);
/* ********************************************************************** */
init_values(rand_choice);
test_create_insert( CLOSE_WHEN_DONE);
}
typedef struct {
......@@ -654,14 +725,5 @@ int toku_omt_merge(OMT leftomt, OMT rightomt, OMT *newomt);
// On error, nothing is modified.
// Performance: time=O(n) is acceptable, but one can imagine implementations that are O(\log n) worst-case.
int toku_omt_insert(OMT omt, OMTVALUE value, int(*h)(OMTVALUE, void*v), void *v, u_int32_t *index);
// Effect: Insert value into the OMT.
// If there is some i such that $h(V_i, v)=0$ then returns DB_KEYEXIST.
// Otherwise, let i be the minimum value such that $h(V_i, v)>0$.
// If no such i exists, then let i be |V|
// Then this has the same effect as
// omt_insert_at(tree, value, i);
// If index!=NULL then i is stored in *index
*/
......@@ -143,17 +143,20 @@ int toku_omt_set_at (OMT omt, OMTVALUE value, u_int32_t index) {
return 0;
}
int toku_omt_insert(OMT omt, OMTVALUE value, int(*h)(OMTVALUE, void*v), void *v, u_int32_t *index) {
int r;
u_int32_t idx;
r = toku_omt_find(omt, h, v, +1, NULL, &idx);
if (r==DB_NOTFOUND) idx=toku_omt_size(omt);
else if (r!=0) return r;
r = toku_omt_find_zero(omt, h, v, NULL, &idx);
if (r==0) {
if (index) *index = idx;
return DB_KEYEXIST;
}
if (r!=DB_NOTFOUND) return r;
if ((r = toku_omt_insert_at(omt, value, idx))) return r;
if (index) *index = idx;
return 0;
}
......
......@@ -202,8 +202,9 @@ int toku_omt_find(OMT V, int (*h)(OMTVALUE, void*extra), void*extra, int directi
The signus of the h must be monotonically increasing.
Given a function of the following form, A is the element
returned for direction>0, B is the element returned
for direction<0, and C is the element returned for
direction==0 (see find_zero).
for direction<0, C is the element returned for
direction==0 (see find_zero) (with a return of 0), and D is the element
returned for direction==0 (see find_zero) with a return of DB_NOTFOUND.
If any of A, B, or C are not found, then asking for the
associated direction will return DB_NOTFOUND.
See find_zero for more information.
......@@ -212,9 +213,11 @@ int toku_omt_find(OMT V, int (*h)(OMTVALUE, void*extra), void*extra, int directi
-...-
A
D
+...+
B
D
0...0
C
......@@ -227,6 +230,7 @@ int toku_omt_find(OMT V, int (*h)(OMTVALUE, void*extra), void*extra, int directi
-...-+...+
AB
D
-...-0...0+...+
AC B
......
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