Commit becb7c5b 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 c4a1dd67
......@@ -83,11 +83,11 @@ static inline DBT* toku__recreate_DBT(DBT* dbt, void* payload, u_int32_t length)
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);
}
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;
DBT point_1;
DBT point_2;
......
......@@ -82,8 +82,8 @@ static inline BOOL toku__rt_exact(toku_range_tree* tree,
}
int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(toku_point*,toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*),
int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
......
This diff is collapsed.
......@@ -20,10 +20,10 @@ struct __toku_range_tree {
//Shared fields:
/** A comparison function, as in bsearch(3), to compare the end-points of
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
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 */
BOOL allow_overlaps;
/** 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
static inline int toku_rt_super_create(toku_range_tree** upperptree,
toku_range_tree** ptree,
int (*end_cmp)(toku_point*,toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*),
int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
......
......@@ -79,12 +79,13 @@ int toku_rt_get_allow_overlaps(toku_range_tree* tree, BOOL* allowed);
\return
- 0: Success.
- 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.
- Other exit codes may be forwarded from underlying system calls. */
int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(toku_point*,toku_point*),
int (*data_cmp)(DB_TXN*,DB_TXN*), BOOL allow_overlaps,
int (*end_cmp)(const toku_point*,const toku_point*),
int (*data_cmp)(const DB_TXN*,const DB_TXN*),
BOOL allow_overlaps,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t));
......
......@@ -28,7 +28,7 @@ LIN_TESTS = $(patsubst %.c,%.lin,$(SRCS))
ALL_TESTS = $(LIN_TESTS) $(LOG_TESTS) $(TLOG_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_ALL_TESTS = $(RUN_LIN_TESTS) $(RUN_TLOG_TESTS) $(RUN_LOG_TESTS)
......@@ -85,7 +85,7 @@ endif
$(MAYBEATSIGN) $(VGRIND) ./$< $(VERBVERBOSE)
LINEAR_BINS = ../linear.o
TLOG_BINS = ../log_nooverlap.o
TLOG_BINS = ../log_nooverlap.o ../tokuredblack.o
LOG_BINS = ../log.o
HEADERS=../rangetree.h ../rangetree-internal.h test.h
......
......@@ -40,22 +40,22 @@ static inline uint32_t myrandom (void) {
}
int dummy_cmp(toku_point *a __attribute__((__unused__)),
toku_point *b __attribute__((__unused__))) {
int dummy_cmp(const toku_point *a __attribute__((__unused__)),
const toku_point *b __attribute__((__unused__))) {
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{!?} */
}
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 y = *(int*)b;
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 y = *(char*)b;
return x -y;
......
......@@ -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.
*/
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,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
......@@ -108,7 +108,8 @@ int toku_rbt_init (
/* 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));
if (!temptree) { r = ENOMEM; goto cleanup; }
......@@ -153,7 +154,7 @@ int toku_rbt_lookup(
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node** pinsert_finger,
struct toku_rbt_node** pelement_finger,
const toku_range** pdata
toku_range** pdata
)
{
int r = ENOSYS;
......@@ -193,7 +194,7 @@ toku_rbt__traverse(int insert, const toku_range *key, struct toku_rbt_tree *rbin
{
y=x;
/* 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)
x=x->left;
......@@ -211,8 +212,8 @@ toku_rbt__traverse(int insert, const toku_range *key, struct toku_rbt_tree *rbin
static struct toku_rbt_node* toku_rbt__insert(
const toku_range* key,
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
) {
struct toku_rbt_node* x;
struct toku_rbt_node* y = parent;
......@@ -239,7 +240,7 @@ static struct toku_rbt_node* toku_rbt__insert(
}
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)
y->left=z;
else
......@@ -375,7 +376,7 @@ toku_rbt__lookup(int mode, const toku_range *key, struct toku_rbt_tree *rbinfo,
{
y=x;
/* 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)
......@@ -602,41 +603,42 @@ toku_rbt__predecessor(const struct toku_rbt_node *x)
return(y);
}
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 r = ENOSYS;
if (!pfinger || !*pfinger ||
*pfinger == RBNULL || !ppred_data) { r = EINVAL; goto cleanup; }
*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;
cleanup:
return r;
}
int toku_rbt_finger_succecessor(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) {
int r = ENOSYS;
if (!pfinger || !*pfinger ||
*pfinger == RBNULL || !psucc_data) { r = EINVAL; goto cleanup; }
*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;
cleanup:
return r;
}
const toku_range* toku_rbt_finger_insert(
int toku_rbt_finger_insert(
const toku_range* key,
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
) {
struct toku_rbt_node* x;
if (!parent) return NULL;
x = toku_rbt__insert(key, rbinfo, parent);
return ((x==RBNULL) ? NULL : RB_GET(x, key));
if (!key || !rbinfo || !parent) return EINVAL;
toku_rbt__insert(key, rbinfo, parent);
return 0;
}
/* Delete the node z, and free up the space
......
......@@ -21,7 +21,6 @@
#define TOKU_REDBLACK_H
#include <rangetree.h>
#define toku_range toku_range
#define RB_INLINE
/* Modes for rblookup */
......@@ -44,7 +43,7 @@ const struct toku_rbt_node *nextp;
};
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;
void* (*rb_malloc) (size_t);
void (*rb_free) (void*);
......@@ -52,33 +51,34 @@ struct toku_rbt_tree {
};
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,
void* (*user_malloc) (size_t),
void (*user_free) (void*),
void* (*user_realloc)(void*, size_t)
);
/* Sets *pdata to NULL if not found. (unless error) */
int toku_rbt_lookup(
int mode,
const toku_range* key,
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node** pinsert_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,
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
struct toku_rbt_tree* rbinfo,
struct toku_rbt_node* parent
);
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 *);
......
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