Skip to content

Commit

Permalink
Implement search le/lt/ge/gt functions for red-black tree.
Browse files Browse the repository at this point in the history
  • Loading branch information
fmela committed Feb 28, 2014
1 parent 6a9aff6 commit 60ed507
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 15 deletions.
8 changes: 8 additions & 0 deletions include/rb_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ rb_tree* rb_tree_clone(rb_tree* tree,

void** rb_tree_insert(rb_tree* tree, void* key, bool* inserted);
void* rb_tree_search(rb_tree* tree, const void* key);
void* rb_tree_search_le(rb_tree* tree, const void* key);
void* rb_tree_search_lt(rb_tree* tree, const void* key);
void* rb_tree_search_ge(rb_tree* tree, const void* key);
void* rb_tree_search_gt(rb_tree* tree, const void* key);
bool rb_tree_remove(rb_tree* tree, const void* key);
size_t rb_tree_clear(rb_tree* tree);
size_t rb_tree_traverse(rb_tree* tree, dict_visit_func visit);
Expand All @@ -75,6 +79,10 @@ bool rb_itor_prevn(rb_itor* itor, size_t count);
bool rb_itor_first(rb_itor* itor);
bool rb_itor_last(rb_itor* itor);
bool rb_itor_search(rb_itor* itor, const void* key);
bool rb_itor_search_le(rb_itor* itor, const void* key);
bool rb_itor_search_lt(rb_itor* itor, const void* key);
bool rb_itor_search_ge(rb_itor* itor, const void* key);
bool rb_itor_search_gt(rb_itor* itor, const void* key);
const void* rb_itor_key(const rb_itor* itor);
void** rb_itor_data(rb_itor* itor);
bool rb_itor_remove(rb_itor* itor);
Expand Down
179 changes: 164 additions & 15 deletions src/rb_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,10 @@ static dict_vtable rb_tree_vtable = {
(dict_dfree_func) rb_tree_free,
(dict_insert_func) rb_tree_insert,
(dict_search_func) rb_tree_search,
(dict_search_func) NULL,/* search_le: not implemented */
(dict_search_func) NULL,/* search_lt: not implemented */
(dict_search_func) NULL,/* search_ge: not implemented */
(dict_search_func) NULL,/* search_gt: not implemented */
(dict_search_func) rb_tree_search_le,
(dict_search_func) rb_tree_search_lt,
(dict_search_func) rb_tree_search_ge,
(dict_search_func) rb_tree_search_gt,
(dict_remove_func) rb_tree_remove,
(dict_clear_func) rb_tree_clear,
(dict_traverse_func) rb_tree_traverse,
Expand All @@ -97,16 +97,16 @@ static itor_vtable rb_tree_itor_vtable = {
(dict_key_func) rb_itor_key,
(dict_data_func) rb_itor_data,
(dict_isearch_func) rb_itor_search,
(dict_isearch_func) NULL,/* itor_search_le: not implemented */
(dict_isearch_func) NULL,/* itor_search_lt: not implemented */
(dict_isearch_func) NULL,/* itor_search_ge: not implemented */
(dict_isearch_func) NULL,/* itor_search_gt: not implemented */
(dict_isearch_func) rb_itor_search_le,
(dict_isearch_func) rb_itor_search_lt,
(dict_isearch_func) rb_itor_search_ge,
(dict_isearch_func) rb_itor_search_gt,
(dict_iremove_func) NULL,/* rb_itor_remove not implemented yet */
(dict_icompare_func) NULL /* rb_itor_compare not implemented yet */
};

static rb_node _null = { NULL, NULL, NULL, NULL, { RB_BLACK } };
#define RB_NULL &_null
static rb_node rb_null = { NULL, NULL, NULL, NULL, { RB_BLACK } };
#define RB_NULL &rb_null

static void rot_left(rb_tree* tree, rb_node* node);
static void rot_right(rb_tree* tree, rb_node* node);
Expand Down Expand Up @@ -192,11 +192,10 @@ rb_tree_clone(rb_tree* tree, dict_key_datum_clone_func clone_func)
return clone;
}

void*
rb_tree_search(rb_tree* tree, const void* key)
rb_node*
rb_tree_search_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = tree->root;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
Expand All @@ -205,9 +204,127 @@ rb_tree_search(rb_tree* tree, const void* key)
else if (cmp)
node = RLINK(node);
else
return node->datum;
return node;
}
return RB_NULL;
}

void*
rb_tree_search(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = rb_tree_search_node(tree, key);
return (node != RB_NULL) ? node->datum : NULL;
}

rb_node*
rb_tree_search_le_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = tree->root, *ret = RB_NULL;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
if (cmp == 0) {
return node;
} else if (cmp < 0) {
node = node->llink;
} else {
ret = node;
node = RLINK(node);
}
}
return ret;
}

void*
rb_tree_search_le(rb_tree* tree, const void* key)
{
rb_node* node = rb_tree_search_le_node(tree, key);

return (node != RB_NULL) ? node->datum : NULL;
}

rb_node*
rb_tree_search_lt_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = tree->root, *ret = RB_NULL;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
if (cmp <= 0) {
node = node->llink;
} else {
ret = node;
node = RLINK(node);
}
}
return NULL;
return ret;
}

void*
rb_tree_search_lt(rb_tree* tree, const void* key)
{
rb_node* node = rb_tree_search_lt_node(tree, key);

return (node != RB_NULL) ? node->datum : NULL;
}

rb_node*
rb_tree_search_ge_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = tree->root, *ret = RB_NULL;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
if (cmp == 0) {
return node;
}
if (cmp < 0) {
ret = node;
node = node->llink;
} else {
node = RLINK(node);
}
}
return ret;
}

void*
rb_tree_search_ge(rb_tree* tree, const void* key)
{
rb_node* node = rb_tree_search_ge_node(tree, key);

return (node != RB_NULL) ? node->datum : NULL;
}

rb_node*
rb_tree_search_gt_node(rb_tree* tree, const void* key)
{
ASSERT(tree != NULL);

rb_node* node = tree->root, *ret = RB_NULL;
while (node != RB_NULL) {
int cmp = tree->cmp_func(key, node->key);
if (cmp < 0) {
ret = node;
node = node->llink;
} else {
node = RLINK(node);
}
}
return ret;
}

void*
rb_tree_search_gt(rb_tree* tree, const void* key)
{
rb_node* node = rb_tree_search_gt_node(tree, key);

return (node != RB_NULL) ? node->datum : NULL;
}

void**
Expand Down Expand Up @@ -892,6 +1009,38 @@ rb_itor_search(rb_itor* itor, const void* key)
return false;
}

bool
rb_itor_search_le(rb_itor* itor, const void* key)
{
ASSERT(itor != NULL);
ASSERT(itor->tree != NULL);
return (itor->node = rb_tree_search_le_node(itor->tree, key)) != RB_NULL;
}

bool
rb_itor_search_lt(rb_itor* itor, const void* key)
{
ASSERT(itor != NULL);
ASSERT(itor->tree != NULL);
return (itor->node = rb_tree_search_lt_node(itor->tree, key)) != RB_NULL;
}

bool
rb_itor_search_ge(rb_itor* itor, const void* key)
{
ASSERT(itor != NULL);
ASSERT(itor->tree != NULL);
return (itor->node = rb_tree_search_ge_node(itor->tree, key)) != RB_NULL;
}

bool
rb_itor_search_gt(rb_itor* itor, const void* key)
{
ASSERT(itor != NULL);
ASSERT(itor->tree != NULL);
return (itor->node = rb_tree_search_gt_node(itor->tree, key)) != RB_NULL;
}

const void*
rb_itor_key(const rb_itor* itor)
{
Expand Down

0 comments on commit 60ed507

Please sign in to comment.