Commit 460b31fd authored by Vincenzo Liberatore's avatar Vincenzo Liberatore

Addresses #288

Code coverage: 100%, exercise all branches except for asserts and similar.
Now requires end_cmp to be commutative.

git-svn-id: file:///svn/tokudb@1909 c7de825b-a66e-492c-adef-691d508d4ae1
parent c4b38c11
......@@ -5,7 +5,7 @@ LIBNAMELINEAR=librangetreelinear
LIBNAME=librangetree
OPTFLAGS = #-O2
# GCOV_FLAGS = -fprofile-arcs -ftest-coverage
GCOV_FLAGS = -O0 -fprofile-arcs -ftest-coverage
CFLAGS = -W -Wall -Werror -g3 -ggdb3 -fPIC $(OPTFLAGS) $(GCOV_FLAGS)
CPPFLAGS = -I../../include -I../../newbrt
#CPPFLAGS += -D_GNU_SOURCE -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
......
......@@ -94,8 +94,11 @@ static BOOL __toku_rt_exact(toku_range_tree* tree,
assert(tree);
assert(a);
assert(b);
/* The comparison function must be commutative */
assert(tree->end_cmp (a->left, b->left) != 0 ||
tree->end_cmp (a->right, b->right) == 0 );
return (tree->end_cmp (a->left, b->left) == 0 &&
tree->end_cmp (a->right, b->right) == 0 &&
tree->data_cmp(a->data, b->data) == 0);
}
......@@ -145,6 +148,9 @@ int toku_rt_close(toku_range_tree* tree) {
return 0;
}
/* It is all too true that this is a worst-case linear implementation,
but great performance gains could be obtained by simply making the
list into move-to-front (see Sleator, Tarjan, CACM 1985) */
int toku_rt_find(toku_range_tree* tree, toku_range* query, unsigned k,
toku_range** buf, unsigned* buflen, unsigned* numfound) {
if (!tree || !query || !buf || !buflen || !numfound) return EINVAL;
......
......@@ -36,7 +36,7 @@ typedef struct {
struct __toku_range_tree_internal {
//Shared fields:
/** A comparison function, as in bsearch(3), to compare the end-points of
a range */
a range. It is assumed to be commutative. */
int (*end_cmp)(void*,void*);
/** A comparison function, as in bsearch(3), to compare the data associated
with a range */
......@@ -87,6 +87,7 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed);
\param ptree Points to the new range tree if create is successful
\param end_cmp User provided function to compare end points.
Return value conforms to cmp in qsort(3).
It must be commutative.
\param data_cmp User provided function to compare data values.
Return value conforms to cmp in qsort(3).
\param allow_overlaps Whether ranges in this range tree are permitted
......
......@@ -21,6 +21,15 @@ int main(int argc, const char *argv[]) {
r = toku_rt_create(&tree, dummy_cmp, NULL, FALSE, malloc, free, realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, NULL, free, realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, NULL, realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, NULL);
CKERR2(r, EINVAL);
assert(tree == NULL);
/* Close tests */
......@@ -153,6 +162,24 @@ int main(int argc, const char *argv[]) {
r = toku_rt_close(tree); CKERR(r);
tree = NULL;
/* Get allow overlap */
BOOL allowed;
r = toku_rt_get_allow_overlaps(NULL, &allowed);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_get_allow_overlaps(tree, NULL);
CKERR2(r, EINVAL);
r = toku_rt_close(tree); CKERR(r);
tree = NULL;
/* That's it: clean up and go home */
toku_free(buf);
buf = NULL;
return 0;
......
......@@ -59,6 +59,16 @@ void runinsert(int rexpect, toku_range* toinsert) {
CKERR2(r, rexpect);
}
void verify_overlap(BOOL allow_overlaps) {
int r;
BOOL allowed;
r = toku_rt_get_allow_overlaps(tree, &allowed);
CKERR(r);
assert(allowed == allow_overlaps);
}
void tests(BOOL allow_overlaps) {
toku_range expect;
toku_range query;
......@@ -73,8 +83,11 @@ void tests(BOOL allow_overlaps) {
* Tree: {|0-1|}, insert of of |1-2| success == allow_overlaps
*/
/* Tree: {|0-1|}, query of |1-2| returns |0-1| */
/* Tree: {|0-1|}, query of |1-2| returns |0-1|
In this test, I am also going to verify that the allow_overlaps bit
is set appropriately. */
setup_tree(allow_overlaps, 0, 1, 0);
verify_overlap(allow_overlaps);
runsearch(0, init_range(&query, 1, 2, -1), init_range(&expect, 0, 1, 0));
close_tree();
......
......@@ -235,6 +235,26 @@ void tests(BOOL allow_overlaps) {
runtest(SUCC, init_point(40), FALSE, 0, 0, 0);
close_tree();
/*
With other interval that cannot be the predecessor
or the successor, but that need to be looked at. */
setup_tree(allow_overlaps, FALSE, 0, 0, 0);
runinsert(0, init_range(&insert, 5, 7, 0));
runinsert(0, init_range(&insert, 50, 60, 0));
runinsert(0, init_range(&insert, 10, 20, 0));
runinsert(0, init_range(&insert, 30, 40, 0));
runinsert(0, init_range(&insert, 2, 4, 0));
runinsert(0, init_range(&insert, 70, 80, 0));
runtest(PRED, init_point(25), TRUE, 10, 20, 0);
runtest(PRED, init_point(4), FALSE, 0, 0, 0);
runtest(SUCC, init_point(25), TRUE, 30, 40, 0);
runtest(SUCC, init_point(95), FALSE, 0, 0, 0);
close_tree();
}
int main(int argc, const char *argv[]) {
......
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