mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 15:24:16 +01:00
Addresses #284
Added user malloc/free/realloc functions to the range tree. git-svn-id: file:///svn/tokudb@1821 c7de825b-a66e-492c-adef-691d508d4ae1
This commit is contained in:
parent
407c0ebebf
commit
e5f752c311
10 changed files with 66 additions and 36 deletions
|
@ -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.
|
||||
|
|
|
@ -42,8 +42,14 @@ struct __toku_range_tree_internal {
|
|||
int (*data_cmp)(void*,void*);
|
||||
/** Whether this tree allows ranges to overlap */
|
||||
BOOL allow_overlaps;
|
||||
/** The number of ranges in the range tree */
|
||||
/** 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));
|
||||
|
|
Loading…
Add table
Reference in a new issue