Commit 9ac4686e authored by Yoni Fogel's avatar Yoni Fogel

Addresses #479

Implementation of range tree wrapper for red black tree.

git-svn-id: file:///svn/tokudb@2706 c7de825b-a66e-492c-adef-691d508d4ae1
parent b3257f90
...@@ -83,11 +83,11 @@ static inline DBT* toku__recreate_DBT(DBT* dbt, void* payload, u_int32_t length) ...@@ -83,11 +83,11 @@ static inline DBT* toku__recreate_DBT(DBT* dbt, void* payload, u_int32_t length)
return dbt; return dbt;
} }
static inline int toku__lt_txn_cmp(DB_TXN* a, DB_TXN* b) { static inline int toku__lt_txn_cmp(const DB_TXN* a, const DB_TXN* b) {
return a < b ? -1 : (a != b); return a < b ? -1 : (a != b);
} }
int toku__lt_point_cmp(toku_point* x, toku_point* y) { int toku__lt_point_cmp(const toku_point* x, const toku_point* y) {
int partial_result; int partial_result;
DBT point_1; DBT point_1;
DBT point_2; DBT point_2;
......
...@@ -82,8 +82,8 @@ static inline BOOL toku__rt_exact(toku_range_tree* tree, ...@@ -82,8 +82,8 @@ static inline 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)(toku_point*,toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*), int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps, BOOL allow_overlaps,
void* (*user_malloc) (size_t), void* (*user_malloc) (size_t),
void (*user_free) (void*), void (*user_free) (void*),
......
This diff is collapsed.
...@@ -20,10 +20,10 @@ struct __toku_range_tree { ...@@ -20,10 +20,10 @@ struct __toku_range_tree {
//Shared fields: //Shared fields:
/** A comparison function, as in bsearch(3), to compare the end-points of /** A comparison function, as in bsearch(3), to compare the end-points of
a range. It is assumed to be commutative. */ a range. It is assumed to be commutative. */
int (*end_cmp)(toku_point*,toku_point*); int (*end_cmp)(const toku_point*,const toku_point*);
/** A comparison function, as in bsearch(3), to compare the data associated /** A comparison function, as in bsearch(3), to compare the data associated
with a range */ with a range */
int (*data_cmp)(DB_TXN*,DB_TXN*); int (*data_cmp)(const DB_TXN*,const DB_TXN*);
/** Whether this tree allows ranges to overlap */ /** Whether this tree allows ranges to overlap */
BOOL allow_overlaps; BOOL allow_overlaps;
/** The number of ranges in the range tree */ /** The number of ranges in the range tree */
...@@ -69,8 +69,8 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b ...@@ -69,8 +69,8 @@ static inline int toku__rt_increase_buffer(toku_range_tree* tree, toku_range** b
static inline int toku_rt_super_create(toku_range_tree** upperptree, static inline int toku_rt_super_create(toku_range_tree** upperptree,
toku_range_tree** ptree, toku_range_tree** ptree,
int (*end_cmp)(toku_point*,toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*), int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps, BOOL allow_overlaps,
void* (*user_malloc) (size_t), void* (*user_malloc) (size_t),
void (*user_free) (void*), void (*user_free) (void*),
......
...@@ -79,12 +79,13 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed); ...@@ -79,12 +79,13 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed);
\return \return
- 0: Success. - 0: Success.
- EINVAL: If any pointer argument is NULL. - EINVAL: If any pointer argument is NULL.
- ENOSYS: If allow_overlaps = TRUE and the implementation does - EINVAL: If allow_overlaps = TRUE and the implementation does
not support overlaps. not support overlaps.
- 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 toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(toku_point*,toku_point*), int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*), BOOL allow_overlaps, int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps,
void* (*user_malloc) (size_t), void* (*user_malloc) (size_t),
void (*user_free) (void*), void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)); void* (*user_realloc)(void*, size_t));
......
...@@ -28,7 +28,7 @@ LIN_TESTS = $(patsubst %.c,%.lin,$(SRCS)) ...@@ -28,7 +28,7 @@ LIN_TESTS = $(patsubst %.c,%.lin,$(SRCS))
ALL_TESTS = $(LIN_TESTS) $(LOG_TESTS) $(TLOG_TESTS) ALL_TESTS = $(LIN_TESTS) $(LOG_TESTS) $(TLOG_TESTS)
RUN_LOG_TESTS = $(patsubst %.log,%.logrun,$(LOG_TESTS)) RUN_LOG_TESTS = $(patsubst %.log,%.logrun,$(LOG_TESTS))
RUN_TLOG_TESTS = $(patsubst %.log,%.logrun,$(TLOG_TESTS)) RUN_TLOG_TESTS = $(patsubst %.tlog,%.tlogrun,$(TLOG_TESTS))
RUN_LIN_TESTS = $(patsubst %.lin,%.linrun,$(LIN_TESTS)) RUN_LIN_TESTS = $(patsubst %.lin,%.linrun,$(LIN_TESTS))
RUN_ALL_TESTS = $(RUN_LIN_TESTS) $(RUN_TLOG_TESTS) $(RUN_LOG_TESTS) RUN_ALL_TESTS = $(RUN_LIN_TESTS) $(RUN_TLOG_TESTS) $(RUN_LOG_TESTS)
...@@ -85,7 +85,7 @@ endif ...@@ -85,7 +85,7 @@ endif
$(MAYBEATSIGN) $(VGRIND) ./$< $(VERBVERBOSE) $(MAYBEATSIGN) $(VGRIND) ./$< $(VERBVERBOSE)
LINEAR_BINS = ../linear.o LINEAR_BINS = ../linear.o
TLOG_BINS = ../log_nooverlap.o TLOG_BINS = ../log_nooverlap.o ../tokuredblack.o
LOG_BINS = ../log.o LOG_BINS = ../log.o
HEADERS=../rangetree.h ../rangetree-internal.h test.h HEADERS=../rangetree.h ../rangetree-internal.h test.h
......
...@@ -40,22 +40,22 @@ static inline uint32_t myrandom (void) { ...@@ -40,22 +40,22 @@ static inline uint32_t myrandom (void) {
} }
int dummy_cmp(toku_point *a __attribute__((__unused__)), int dummy_cmp(const toku_point *a __attribute__((__unused__)),
toku_point *b __attribute__((__unused__))) { const toku_point *b __attribute__((__unused__))) {
return 0; return 0;
} }
int ptr_cmp(DB_TXN* a, DB_TXN* b) { int ptr_cmp(const DB_TXN* a, const DB_TXN* b) {
return a < b ? -1 : (a != b); /* \marginpar{!?} */ return a < b ? -1 : (a != b); /* \marginpar{!?} */
} }
int int_cmp(toku_point* a, toku_point*b) { int int_cmp(const toku_point* a, const toku_point*b) {
int x = *(int*)a; int x = *(int*)a;
int y = *(int*)b; int y = *(int*)b;
return x -y; return x -y;
} }
int char_cmp(DB_TXN *a, DB_TXN *b) { int char_cmp(const DB_TXN *a, const DB_TXN *b) {
int x = *(char*)a; int x = *(char*)a;
int y = *(char*)b; int y = *(char*)b;
return x -y; return x -y;
......
...@@ -88,7 +88,7 @@ static void toku_rbt__delete_fix(struct toku_rbt_node **, struct toku_rbt_node * ...@@ -88,7 +88,7 @@ static void toku_rbt__delete_fix(struct toku_rbt_node **, struct toku_rbt_node *
* Returns a pointer to the top of the tree. * Returns a pointer to the top of the tree.
*/ */
int toku_rbt_init ( int toku_rbt_init (
int (*cmp)(const toku_range*, const toku_range*), int (*cmp)(const toku_point*, const toku_point*),
struct toku_rbt_tree** ptree, struct toku_rbt_tree** ptree,
void* (*user_malloc) (size_t), void* (*user_malloc) (size_t),
void (*user_free) (void*), void (*user_free) (void*),
...@@ -108,7 +108,8 @@ int toku_rbt_init ( ...@@ -108,7 +108,8 @@ int toku_rbt_init (
/* Key is initialized since the toku_rbt__null is static. */ /* Key is initialized since the toku_rbt__null is static. */
} }
if (!ptree) { r = EINVAL; goto cleanup; } if (!cmp || !ptree || !user_malloc || !user_free || !user_realloc) {
r = EINVAL; goto cleanup; }
temptree=(struct toku_rbt_tree *) user_malloc(sizeof(struct toku_rbt_tree)); temptree=(struct toku_rbt_tree *) user_malloc(sizeof(struct toku_rbt_tree));
if (!temptree) { r = ENOMEM; goto cleanup; } if (!temptree) { r = ENOMEM; goto cleanup; }
...@@ -153,7 +154,7 @@ int toku_rbt_lookup( ...@@ -153,7 +154,7 @@ int toku_rbt_lookup(
struct toku_rbt_tree* rbinfo, struct toku_rbt_tree* rbinfo,
struct toku_rbt_node** pinsert_finger, struct toku_rbt_node** pinsert_finger,
struct toku_rbt_node** pelement_finger, struct toku_rbt_node** pelement_finger,
const toku_range** pdata toku_range** pdata
) )
{ {
int r = ENOSYS; int r = ENOSYS;
...@@ -193,7 +194,7 @@ toku_rbt__traverse(int insert, const toku_range *key, struct toku_rbt_tree *rbin ...@@ -193,7 +194,7 @@ toku_rbt__traverse(int insert, const toku_range *key, struct toku_rbt_tree *rbin
{ {
y=x; y=x;
/* printf("key=%s, RB_GET(x, key)=%s\n", key, RB_GET(x, key)); */ /* printf("key=%s, RB_GET(x, key)=%s\n", key, RB_GET(x, key)); */
cmp=rbinfo->rb_cmp(key, RB_GET(x, key)); cmp=rbinfo->rb_cmp(key->left, x->key.left);
if (cmp<0) if (cmp<0)
x=x->left; x=x->left;
...@@ -239,7 +240,7 @@ static struct toku_rbt_node* toku_rbt__insert( ...@@ -239,7 +240,7 @@ static struct toku_rbt_node* toku_rbt__insert(
} }
else else
{ {
cmp=rbinfo->rb_cmp(RB_GET(z, key), RB_GET(y, key)); cmp=rbinfo->rb_cmp(z->key.left, y->key.left);
if (cmp<0) if (cmp<0)
y->left=z; y->left=z;
else else
...@@ -375,7 +376,7 @@ toku_rbt__lookup(int mode, const toku_range *key, struct toku_rbt_tree *rbinfo, ...@@ -375,7 +376,7 @@ toku_rbt__lookup(int mode, const toku_range *key, struct toku_rbt_tree *rbinfo,
{ {
y=x; y=x;
/* printf("key=%s, RB_GET(x, key)=%s\n", key, RB_GET(x, key)); */ /* printf("key=%s, RB_GET(x, key)=%s\n", key, RB_GET(x, key)); */
cmp=rbinfo->rb_cmp(key, RB_GET(x, key)); cmp=rbinfo->rb_cmp(key->left, x->key.left);
if (cmp<0) if (cmp<0)
...@@ -602,41 +603,42 @@ toku_rbt__predecessor(const struct toku_rbt_node *x) ...@@ -602,41 +603,42 @@ toku_rbt__predecessor(const struct toku_rbt_node *x)
return(y); return(y);
} }
int toku_rbt_finger_predecessor(const struct toku_rbt_node** pfinger, int toku_rbt_finger_predecessor(struct toku_rbt_node** pfinger,
const toku_range** ppred_data) { toku_range** ppred_data) {
int r = ENOSYS; int r = ENOSYS;
if (!pfinger || !*pfinger || if (!pfinger || !*pfinger ||
*pfinger == RBNULL || !ppred_data) { r = EINVAL; goto cleanup; } *pfinger == RBNULL || !ppred_data) { r = EINVAL; goto cleanup; }
*pfinger = toku_rbt__predecessor(*pfinger); *pfinger = toku_rbt__predecessor(*pfinger);
*ppred_data = ((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key)); *ppred_data = (toku_range*)
((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key));
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
} }
int toku_rbt_finger_succecessor(const struct toku_rbt_node** pfinger, int toku_rbt_finger_successor(struct toku_rbt_node** pfinger,
const toku_range** psucc_data) { toku_range** psucc_data) {
int r = ENOSYS; int r = ENOSYS;
if (!pfinger || !*pfinger || if (!pfinger || !*pfinger ||
*pfinger == RBNULL || !psucc_data) { r = EINVAL; goto cleanup; } *pfinger == RBNULL || !psucc_data) { r = EINVAL; goto cleanup; }
*pfinger = toku_rbt__successor(*pfinger); *pfinger = toku_rbt__successor(*pfinger);
*psucc_data = ((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key)); *psucc_data = (toku_range*)
((*pfinger==RBNULL) ? NULL : RB_GET((*pfinger), key));
r = 0; r = 0;
cleanup: cleanup:
return r; return r;
} }
const toku_range* toku_rbt_finger_insert( int toku_rbt_finger_insert(
const toku_range* key, const toku_range* key,
struct toku_rbt_tree* rbinfo, struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent struct toku_rbt_node* parent
) { ) {
struct toku_rbt_node* x; if (!key || !rbinfo || !parent) return EINVAL;
if (!parent) return NULL; toku_rbt__insert(key, rbinfo, parent);
x = toku_rbt__insert(key, rbinfo, parent); return 0;
return ((x==RBNULL) ? NULL : RB_GET(x, key));
} }
/* Delete the node z, and free up the space /* Delete the node z, and free up the space
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#define TOKU_REDBLACK_H #define TOKU_REDBLACK_H
#include <rangetree.h> #include <rangetree.h>
#define toku_range toku_range
#define RB_INLINE #define RB_INLINE
/* Modes for rblookup */ /* Modes for rblookup */
...@@ -44,7 +43,7 @@ const struct toku_rbt_node *nextp; ...@@ -44,7 +43,7 @@ const struct toku_rbt_node *nextp;
}; };
struct toku_rbt_tree { struct toku_rbt_tree {
int (*rb_cmp)(const toku_range*, const toku_range*); int (*rb_cmp)(const toku_point*, const toku_point*);
struct toku_rbt_node *rb_root; struct toku_rbt_node *rb_root;
void* (*rb_malloc) (size_t); void* (*rb_malloc) (size_t);
void (*rb_free) (void*); void (*rb_free) (void*);
...@@ -52,23 +51,24 @@ struct toku_rbt_tree { ...@@ -52,23 +51,24 @@ struct toku_rbt_tree {
}; };
int toku_rbt_init ( int toku_rbt_init (
int (*cmp)(const toku_range*, const toku_range*), int (*cmp)(const toku_point*, const toku_point*),
struct toku_rbt_tree** ptree, struct toku_rbt_tree** ptree,
void* (*user_malloc) (size_t), void* (*user_malloc) (size_t),
void (*user_free) (void*), void (*user_free) (void*),
void* (*user_realloc)(void*, size_t) void* (*user_realloc)(void*, size_t)
); );
/* Sets *pdata to NULL if not found. (unless error) */
int toku_rbt_lookup( int toku_rbt_lookup(
int mode, int mode,
const toku_range* key, const toku_range* key,
struct toku_rbt_tree* rbinfo, struct toku_rbt_tree* rbinfo,
struct toku_rbt_node** pinsert_finger, struct toku_rbt_node** pinsert_finger,
struct toku_rbt_node** pelement_finger, struct toku_rbt_node** pelement_finger,
const toku_range** pdata toku_range** pdata
); );
const toku_range* toku_rbt_finger_insert( int toku_rbt_finger_insert(
const toku_range* key, const toku_range* key,
struct toku_rbt_tree* rbinfo, struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent struct toku_rbt_node* parent
...@@ -76,9 +76,9 @@ const toku_range* toku_rbt_finger_insert( ...@@ -76,9 +76,9 @@ const toku_range* toku_rbt_finger_insert(
int toku_rbt_finger_delete(struct toku_rbt_node* node, struct toku_rbt_tree *rbinfo); int toku_rbt_finger_delete(struct toku_rbt_node* node, struct toku_rbt_tree *rbinfo);
int toku_rbt_finger_predecessor(const struct toku_rbt_node** pfinger, const toku_range** ppred_data); int toku_rbt_finger_predecessor(struct toku_rbt_node** pfinger, toku_range** ppred_data);
int toku_rbt_finger_successor(const struct toku_rbt_node** pfinger, const toku_range** psucc_data); int toku_rbt_finger_successor(struct toku_rbt_node** pfinger, toku_range** psucc_data);
void toku_rbt_destroy(struct toku_rbt_tree *); void toku_rbt_destroy(struct toku_rbt_tree *);
......
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