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