49#define PARENT(node) ((rb_node*)((node)->color & ~RB_BLACK))
50#define COLOR(node) ((node)->color & RB_BLACK)
52#define SET_RED(node) (node)->color &= (~(intptr_t)RB_BLACK)
53#define SET_BLACK(node) (node)->color |= ((intptr_t)RB_BLACK)
54#define SET_PARENT(node,p) (node)->color = COLOR(node) | (intptr_t)(p)
63_Static_assert(
sizeof(intptr_t) ==
sizeof(
rb_node*),
64 "rb_node tags a parent pointer stored in an intptr_t");
66 "rb_node must be layout-compatible with tree_node_base");
68 "rb_node must be layout-compatible with tree_node_base");
70 "rb_node must be layout-compatible with tree_node_base");
72 "rb_node must be layout-compatible with tree_node_base");
74 "rb_node must be layout-compatible with tree_node_base");
95static bool vt_rb_tree_select(
void* obj,
size_t n,
const void** key,
void** datum) {
return rb_tree_select(obj, n, key, datum); }
96static bool vt_rb_tree_verify(
const void* obj) {
return rb_tree_verify(obj); }
97static void vt_rb_itor_free(
void* itor) {
rb_itor_free(itor); }
98static bool vt_rb_itor_valid(
const void* itor) {
return rb_itor_valid(itor); }
100static bool vt_rb_itor_next(
void* itor) {
return rb_itor_next(itor); }
101static bool vt_rb_itor_prev(
void* itor) {
return rb_itor_prev(itor); }
102static bool vt_rb_itor_nextn(
void* itor,
size_t count) {
return rb_itor_nextn(itor, count); }
103static bool vt_rb_itor_prevn(
void* itor,
size_t count) {
return rb_itor_prevn(itor, count); }
104static bool vt_rb_itor_first(
void* itor) {
return rb_itor_first(itor); }
105static bool vt_rb_itor_last(
void* itor) {
return rb_itor_last(itor); }
106static void* vt_rb_itor_key(
void* itor) {
return dict_unconst(
rb_itor_key(itor)); }
107static void** vt_rb_itor_datum(
void* itor) {
return rb_itor_datum(itor); }
108static bool vt_rb_itor_search(
void* itor,
const void* key) {
return rb_itor_search(itor, key); }
109static bool vt_rb_itor_search_le(
void* itor,
const void* key) {
return rb_itor_search_le(itor, key); }
110static bool vt_rb_itor_search_lt(
void* itor,
const void* key) {
return rb_itor_search_lt(itor, key); }
111static bool vt_rb_itor_search_ge(
void* itor,
const void* key) {
return rb_itor_search_ge(itor, key); }
112static bool vt_rb_itor_search_gt(
void* itor,
const void* key) {
return rb_itor_search_gt(itor, key); }
113static bool vt_rb_itor_remove(
void* itor) {
return rb_itor_remove(itor); }
136 vt_rb_itor_invalidate,
146 vt_rb_itor_search_le,
147 vt_rb_itor_search_lt,
148 vt_rb_itor_search_ge,
149 vt_rb_itor_search_gt,
158static rb_node* node_new(
void* key);
186 dct->
_vtable = &rb_tree_vtable;
209 if (delete_func) delete_func(node->
key, node->
datum);
237 parent = node; node = node->
llink;
238 }
else if (cmp > 0) {
239 parent = node; node = node->
rlink;
244 if (!(node = node_new(key)))
248 if (parent == NULL) {
255 parent->
llink = node;
257 parent->
rlink = node;
268 unsigned rotations = 0;
279 if (node ==
PARENT(node)->rlink) {
281 rot_left(
tree, node);
288 rot_right(
tree, temp);
300 if (node ==
PARENT(node)->llink) {
302 rot_right(
tree, node);
309 rot_left(
tree, temp);
336 bool left = xp && xp->
llink == out;
352 remove_node(
tree, node);
359 unsigned rotations = 0;
366 rot_left(
tree, parent); ++rotations;
374 left = parent && parent->
llink == node;
379 rot_right(
tree, w); ++rotations;
389 rot_left(
tree, parent); ++rotations;
397 rot_right(
tree, parent); ++rotations;
405 left = parent && parent->
llink == node;
410 rot_left(
tree, w); ++rotations;
420 rot_right(
tree, parent); ++rotations;
445 for (; node != NULL; node = node_next(node)) {
447 if (!visit(node->
key, node->
datum, user_data))
break;
467 node = node_prev(node);
471 node = node_next(node);
476 *datum = node->
datum;
515 if ((((uintptr_t) node) & 1) != 0) {
516 fprintf(stderr,
"%s:%d (%s) dict_malloc_func returned an odd "
517 "pointer: %p\n", __FILE__, __LINE__, __func__, (
void*) node);
537 while (temp && temp->
rlink == node) {
555 while (temp && temp->
llink == node) {
567 unsigned black_node_count,
unsigned leaf_black_node_count,
568 const void* lower,
const void* upper,
size_t* count)
570 if (parent == NULL) {
581 VERIFY(black_node_count == leaf_black_node_count);
601 bool l = node_verify(
tree, node, node->
llink, black_node_count,
602 leaf_black_node_count, lower, node->
key, count);
603 bool r = node_verify(
tree, node, node->
rlink, black_node_count,
604 leaf_black_node_count, node->
key, upper, count);
613 unsigned leaf_black_node_count = 0;
618 leaf_black_node_count++;
623 if (!node_verify(
tree, NULL,
tree->
root, 0, leaf_black_node_count,
650 itor->
_vtable = &rb_tree_itor_vtable;
664 return itor->
node != NULL;
672 return itor->
node != NULL;
682 return itor->
node != NULL;
692 return itor->
node != NULL;
int(* dict_compare_func)(const void *, const void *)
A pointer to a function that compares two keys.
void(* dict_delete_func)(void *, void *)
A pointer to a function that is called when a key-value pair gets removed from a dictionary.
bool(* dict_visit_func)(const void *, void *, void *)
A pointer to a function used for iterating over dictionary contents.
void ** rb_tree_search_lt(rb_tree *tree, const void *key)
Return the address of the datum of the greatest key less than |key|, or NULL if there is none.
size_t rb_tree_min_path_length(const rb_tree *tree)
Return the shallowest depth at which a child link is absent, the root being at depth 1,...
bool rb_itor_search_lt(rb_itor *itor, const void *key)
Position |itor| on the greatest key less than |key| and return true, or unposition it and return fals...
bool rb_itor_search_ge(rb_itor *itor, const void *key)
Position |itor| on the least key greater than or equal to |key| and return true, or unposition it and...
const void * rb_itor_key(const rb_itor *itor)
Return the key |itor| is positioned on, or NULL if it is not positioned.
rb_tree * rb_tree_new(dict_compare_func cmp_func)
Create an empty tree that orders keys with |cmp_func| (must not be NULL).
bool rb_itor_next(rb_itor *itor)
Move |itor| to the next element in key order and return true, or unposition it and return false if th...
bool rb_itor_valid(const rb_itor *itor)
Return whether |itor| is positioned on an element.
void ** rb_tree_search_ge(rb_tree *tree, const void *key)
Return the address of the datum of the least key greater than or equal to |key|, or NULL if there is ...
dict_itor * rb_dict_itor_new(rb_tree *tree)
Like rb_itor_new(), but wrapped in a generic dict_itor for use with the dict_itor_* macros.
size_t rb_tree_traverse(rb_tree *tree, dict_visit_func visit, void *user_data)
Call |visit|(key, datum, |user_data|) for each element in key order, stopping early if |visit| return...
size_t rb_tree_total_path_length(const rb_tree *tree)
Return the sum of the depths of all nodes, the root being at depth 1, or 0 for an empty tree.
void ** rb_tree_search(rb_tree *tree, const void *key)
Return the address of the datum stored for |key|, or NULL if |key| is not present.
bool rb_itor_search_le(rb_itor *itor, const void *key)
Position |itor| on the greatest key less than or equal to |key| and return true, or unposition it and...
void rb_itor_invalidate(rb_itor *itor)
Unposition |itor|, so that it is not positioned on any element.
size_t rb_tree_clear(rb_tree *tree, dict_delete_func delete_func)
Remove every element, calling |delete_func|(key, datum) for each unless |delete_func| is NULL.
size_t rb_tree_max_path_length(const rb_tree *tree)
Return the greatest depth of any node, the root being at depth 1, or 0 for an empty tree: the height ...
rb_itor * rb_itor_new(rb_tree *tree)
Create an iterator over |tree| that is not positioned on any element yet.
bool rb_itor_remove(rb_itor *it)
Remove the element |itor| is positioned on and unposition |itor|; return false if it was not position...
bool rb_itor_prevn(rb_itor *itor, size_t count)
Move |itor| |count| elements back and return whether it is still positioned.
bool rb_itor_search(rb_itor *itor, const void *key)
Position |itor| on |key| and return true, or unposition it and return false if |key| is not present.
bool rb_itor_prev(rb_itor *itor)
Move |itor| to the previous element in key order and return true, or unposition it and return false i...
#define SET_PARENT(node, p)
void ** rb_itor_datum(rb_itor *itor)
Return the address of the datum |itor| is positioned on, through which it can be read or replaced,...
bool rb_itor_first(rb_itor *itor)
Position |itor| on the first element in key order and return true, or unposition it and return false ...
size_t rb_tree_free(rb_tree *tree, dict_delete_func delete_func)
Remove every element, calling |delete_func|(key, datum) for each unless |delete_func| is NULL,...
bool rb_itor_nextn(rb_itor *itor, size_t count)
Move |itor| |count| elements forward and return whether it is still positioned.
void rb_itor_free(rb_itor *itor)
Free an iterator.
bool rb_itor_last(rb_itor *itor)
Position |itor| on the last element in key order and return true, or unposition it and return false i...
dict_insert_result rb_tree_insert(rb_tree *tree, void *key)
Insert |key| unless an equal key is present.
bool rb_tree_verify(const rb_tree *tree)
Check the internal invariants of the tree and return true if they hold, or print the first failed che...
void ** rb_tree_search_le(rb_tree *tree, const void *key)
Return the address of the datum of the greatest key less than or equal to |key|, or NULL if there is ...
size_t rb_tree_count(const rb_tree *tree)
Return the number of elements.
dict * rb_dict_new(dict_compare_func cmp_func)
Like rb_tree_new(), but wrapped in a generic dict for use with the dict_* macros.
dict_remove_result rb_tree_remove(rb_tree *tree, const void *key)
Remove the element with key |key|.
bool rb_tree_select(rb_tree *tree, size_t n, const void **key, void **datum)
Store the key and datum of the |n|th element in key order (0-based) through |key| and |datum| and ret...
bool rb_itor_search_gt(rb_itor *itor, const void *key)
Position |itor| on the least key greater than |key| and return true, or unposition it and return fals...
void ** rb_tree_search_gt(rb_tree *tree, const void *key)
Return the address of the datum of the least key greater than |key|, or NULL if there is none.
int rb_itor_compare(const rb_itor *i1, const rb_itor *i2)
Compare the positions of two iterators over the same tree: return a negative value,...
const itor_vtable * _vtable
The operations of one container type.
const dict_vtable * _vtable
dict_compare_func cmp_func
bool tree_iterator_last(void *Iterator)
void ** tree_iterator_datum(void *Iterator)
void * tree_node_max(void *Node)
void tree_iterator_invalidate(void *Iterator)
void ** tree_search_gt(void *Tree, const void *key)
int tree_iterator_compare(const void *Iterator1, const void *Iterator2)
void * tree_search_node(void *Tree, const void *key)
bool tree_iterator_search_le(void *Iterator, const void *key)
bool tree_iterator_valid(const void *Iterator)
size_t tree_count(const void *Tree)
void ** tree_search_lt(void *Tree, const void *key)
const void * tree_iterator_key(const void *Iterator)
size_t tree_min_path_length(const void *Tree)
void * tree_node_min(void *Node)
void ** tree_search(void *Tree, const void *key)
size_t tree_total_path_length(const void *Tree)
bool tree_iterator_first(void *Iterator)
void tree_iterator_free(void *Iterator)
bool tree_iterator_search_lt(void *Iterator, const void *key)
bool tree_iterator_search_ge(void *Iterator, const void *key)
size_t tree_max_path_length(const void *Tree)
int tree_iterator_compare_vt(void *Iterator1, void *Iterator2)
bool tree_iterator_search_gt(void *Iterator, const void *key)
void ** tree_search_ge(void *Tree, const void *key)
void ** tree_search_le(void *Tree, const void *key)
bool tree_iterator_search(void *Iterator, const void *key)
#define TREE_ITERATOR_FIELDS(tree_type, node_type)
#define TREE_FIELDS(node_type)