Commit 29d9b65e authored by Yoni Fogel's avatar Yoni Fogel

Addresses #284

Added user malloc/free/realloc functions to the range tree.

git-svn-id: file:///svn/tokudb@1821 c7de825b-a66e-492c-adef-691d508d4ae1
parent 23ac848f
......@@ -41,7 +41,7 @@ static int __toku_rt_decrease_capacity(toku_range_tree* tree, unsigned _num) {
while (temp_len >= num * 2) temp_len /= 2;
assert(temp_len >= _num); //Sanity check.
toku_range* temp_ranges =
realloc(tree->ranges, temp_len * sizeof(toku_range));
tree->realloc(tree->ranges, temp_len * sizeof(toku_range));
if (!temp_ranges) return errno;
tree->ranges = temp_ranges;
tree->ranges_len = temp_len;
......@@ -55,7 +55,7 @@ static int __toku_rt_increase_capacity(toku_range_tree* tree, unsigned num) {
unsigned temp_len = tree->ranges_len;
while (temp_len < num) temp_len *= 2;
toku_range* temp_ranges =
realloc(tree->ranges, temp_len * sizeof(toku_range));
tree->realloc(tree->ranges, temp_len * sizeof(toku_range));
if (!temp_ranges) return errno;
tree->ranges = temp_ranges;
tree->ranges_len = temp_len;
......@@ -63,14 +63,15 @@ static int __toku_rt_increase_capacity(toku_range_tree* tree, unsigned num) {
return 0;
}
static int __toku_increase_buffer(toku_range** buf, unsigned* buflen,
unsigned num) {
static int __toku_rt_increase_buffer(toku_range_tree* tree, toku_range** buf,
unsigned* buflen, unsigned num) {
assert(buf);
assert(buflen);
if (*buflen < num) {
unsigned temp_len = *buflen;
while (temp_len < num) temp_len *= 2;
toku_range* temp_buf = realloc(*buf, temp_len * sizeof(toku_range));
toku_range* temp_buf =
tree->realloc(*buf, temp_len * sizeof(toku_range));
if (!temp_buf) return errno;
*buf = temp_buf;
*buflen = temp_len;
......@@ -100,15 +101,19 @@ static BOOL __toku_rt_exact(toku_range_tree* tree,
int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(void*,void*), int (*data_cmp)(void*,void*),
BOOL allow_overlaps) {
BOOL allow_overlaps,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)) {
int r;
toku_range_tree* temptree;
if (!ptree || !end_cmp || !data_cmp) return EINVAL;
if (!ptree || !end_cmp || !data_cmp ||
!user_malloc || !user_free || !user_realloc) return EINVAL;
temptree = (toku_range_tree*)malloc(sizeof(toku_range_tree));
temptree = (toku_range_tree*)user_malloc(sizeof(toku_range_tree));
if (0) {
died1:
free(temptree);
user_free(temptree);
return r;
}
if (!temptree) return errno;
......@@ -120,11 +125,14 @@ int toku_rt_create(toku_range_tree** ptree,
temptree->allow_overlaps = allow_overlaps;
temptree->ranges_len = minlen;
temptree->ranges = (toku_range*)
malloc(temptree->ranges_len * sizeof(toku_range));
user_malloc(temptree->ranges_len * sizeof(toku_range));
if (!temptree->ranges) {
r = errno;
goto died1;
}
temptree->malloc = user_malloc;
temptree->free = user_free;
temptree->realloc = user_realloc;
*ptree = temptree;
return 0;
......@@ -132,8 +140,8 @@ int toku_rt_create(toku_range_tree** ptree,
int toku_rt_close(toku_range_tree* tree) {
if (!tree) return EINVAL;
free(tree->ranges);
free(tree);
tree->free(tree->ranges);
tree->free(tree);
return 0;
}
......@@ -149,7 +157,7 @@ int toku_rt_find(toku_range_tree* tree, toku_range* query, unsigned k,
for (i = 0; i < tree->numelements; i++) {
if (__toku_rt_overlap(tree, query, &tree->ranges[i])) {
r = __toku_increase_buffer(buf, buflen, temp_numfound + 1);
r = __toku_rt_increase_buffer(tree, buf, buflen, temp_numfound + 1);
if (r != 0) return r;
(*buf)[temp_numfound++] = tree->ranges[i];
//k == 0 means limit of infinity, this is not a bug.
......
......@@ -44,6 +44,12 @@ struct __toku_range_tree_internal {
BOOL allow_overlaps;
/** The number of ranges in the range tree */
unsigned numelements;
/** The user malloc function */
void* (*malloc) (size_t);
/** The user free function */
void (*free) (void*);
/** The user realloc function */
void* (*realloc)(void*, size_t);
#if defined(TOKU_LINEAR_RANGE_TREE)
#if defined(TOKU_LOG_RANGE_TREE)
#error Choose just one range tree type.
......@@ -73,13 +79,19 @@ typedef struct __toku_range_tree_internal toku_range_tree;
Return value conforms to cmp in qsort(3).
\param allow_overlaps Whether ranges in this range tree are permitted
to overlap.
\param user_malloc A user provided malloc(3) function.
\param user_free A user provided free(3) function.
\param user_realloc A user provided realloc(3) function.
\return
- 0: Success.
- EINVAL: If any pointer argument is NULL.
- Other exit codes may be forwarded from underlying system calls. */
int toku_rt_create(toku_range_tree** ptree, int (*end_cmp)(void*,void*),
int (*data_cmp)(void*,void*), BOOL allow_overlaps);
int (*data_cmp)(void*,void*), BOOL allow_overlaps,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
/**
Destroys and frees a range tree.
......
......@@ -9,7 +9,7 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv);
/* Test no overlap */
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree!=NULL);
......@@ -20,7 +20,7 @@ int main(int argc, const char *argv[]) {
tree = NULL;
/* Test overlap */
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE, malloc, free, realloc);
CKERR(r);
assert(tree!=NULL);
......
......@@ -10,15 +10,15 @@ int main(int argc, const char *argv[]) {
parse_args(argc, argv);
/* Create tests */
r = toku_rt_create(NULL, dummy_cmp, dummy_cmp, FALSE);
r = toku_rt_create(NULL, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, NULL, dummy_cmp, FALSE);
r = toku_rt_create(&tree, NULL, dummy_cmp, FALSE, malloc, free, realloc);
CKERR2(r, EINVAL);
assert(tree == NULL);
r = toku_rt_create(&tree, dummy_cmp, NULL, FALSE);
r = toku_rt_create(&tree, dummy_cmp, NULL, FALSE, malloc, free, realloc);
CKERR2(r, EINVAL);
assert(tree == NULL);
......@@ -31,7 +31,8 @@ int main(int argc, const char *argv[]) {
r = toku_rt_insert(NULL, &range);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_insert(tree, NULL); CKERR2(r, EINVAL);
......@@ -43,7 +44,8 @@ int main(int argc, const char *argv[]) {
r = toku_rt_delete(NULL, &range);
CKERR2(r, EINVAL);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_delete(tree, NULL); CKERR2(r, EINVAL);
......@@ -59,7 +61,8 @@ int main(int argc, const char *argv[]) {
range.right = &stuff[1];
range.data = NULL;
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_find(NULL, &range, 2, &buf, &bufsize, &found);
......@@ -93,7 +96,8 @@ int main(int argc, const char *argv[]) {
/* Predecessor tests */
int foo;
BOOL wasfound;
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_predecessor(NULL, &foo, &range, &wasfound);
......@@ -110,7 +114,8 @@ int main(int argc, const char *argv[]) {
r = toku_rt_close(tree); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_predecessor(tree, &foo, &range, &wasfound);
......@@ -120,7 +125,8 @@ int main(int argc, const char *argv[]) {
/* Successor tests */
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, FALSE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_successor(NULL, &foo, &range, &wasfound);
......@@ -137,7 +143,8 @@ int main(int argc, const char *argv[]) {
r = toku_rt_close(tree); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE); CKERR(r);
r = toku_rt_create(&tree, dummy_cmp, dummy_cmp, TRUE, malloc, free, realloc);
CKERR(r);
assert(tree != NULL);
r = toku_rt_successor(tree, &foo, &range, &wasfound);
......
......@@ -20,7 +20,7 @@ int main(int argc, const char *argv[]) {
|-------A-------|
|-------B-------|
*/
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE);
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, malloc, free, realloc);
CKERR(r);
/* Verify we can insert a trivial range and lose it. */
......@@ -98,7 +98,7 @@ int main(int argc, const char *argv[]) {
|---A---|
|---B---|
*/
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE);
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, malloc, free, realloc);
CKERR(r);
/* Verify we can insert a trivial range and lose it. */
......
......@@ -17,7 +17,7 @@ int main(int argc, const char *argv[]) {
1 2 3 4 5 6 7
|---A-----------|
*/
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE);
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, malloc, free, realloc);
CKERR(r);
range.left = &nums[1];
......@@ -34,7 +34,7 @@ int main(int argc, const char *argv[]) {
1 2 3 4 5 6 7
|---A-----------|
*/
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE);
r = toku_rt_create(&tree, int_cmp, char_cmp, FALSE, malloc, free, realloc);
CKERR(r);
range.left = &nums[1];
......
......@@ -38,7 +38,7 @@ int main(int argc, const char *argv[]) {
|-------A-------|
|-------B-------|
*/
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE);
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, malloc, free, realloc);
CKERR(r);
r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r);
......@@ -184,7 +184,7 @@ int main(int argc, const char *argv[]) {
find_range.right = &nums[4];
find_range.data = NULL;
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE);
r = toku_rt_create(&tree, int_cmp, char_cmp, TRUE, malloc, free, realloc);
CKERR(r);
r = toku_rt_find(tree, &find_range, 4, &buf, &bufsize, &found); CKERR(r);
......
......@@ -30,7 +30,8 @@ toku_range* init_range(toku_range* range, int left, int right, int data) {
void setup_tree(BOOL allow_overlaps, BOOL insert, int left, int right, int data) {
int r;
toku_range range;
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps); CKERR(r);
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, malloc, free, realloc);
CKERR(r);
if (insert) {
r = toku_rt_insert(tree, init_range(&range, left, right, data));
......
......@@ -30,7 +30,8 @@ toku_range* init_range(toku_range* range, int left, int right, int data) {
void setup_tree(BOOL allow_overlaps, int left, int right, int data) {
int r;
toku_range range;
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps); CKERR(r);
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, malloc, free, realloc);
CKERR(r);
r = toku_rt_insert(tree, init_range(&range, left, right, data));CKERR(r);
}
......
......@@ -34,7 +34,8 @@ void* init_point(int left) {
void setup_tree(BOOL allow_overlaps, BOOL insert, int left, int right, int data) {
int r;
toku_range range;
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps); CKERR(r);
r = toku_rt_create(&tree, int_cmp, char_cmp, allow_overlaps, malloc, free, realloc);
CKERR(r);
if (insert) {
r = toku_rt_insert(tree, init_range(&range, left, right, data));
......
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