Rizin
unix-like reverse engineering framework and cli tools
rz_rbtree.h
Go to the documentation of this file.
1 #ifndef RZ_RBTREE_H
2 #define RZ_RBTREE_H
3 
4 #include <limits.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 
8 #include "rz_list.h"
9 
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13 
14 // max height <= 2 * floor(log2(n + 1))
15 // We use `int` for size, so <= 2 * 31
16 #define RZ_RBTREE_MAX_HEIGHT 62
17 
18 // Singleton can be zero initialized
19 typedef struct rz_rb_node_t {
20  struct rz_rb_node_t *child[2];
21  bool red;
23 
24 typedef RBNode *RBTree;
25 
26 // incoming < in_tree => return < 0
27 // incoming == in_tree => return == 0
28 // incoming > in_tree => return > 0
29 typedef int (*RBComparator)(const void *incoming, const RBNode *in_tree, void *user);
30 
31 typedef void (*RBNodeFree)(RBNode *node, void *user);
32 typedef void (*RBNodeSum)(RBNode *node);
33 
34 typedef struct rz_rb_iter_t {
35  // current depth
36  // if len == 0, the iterator is at the end/empty
37  // else path[len-1] is the current node
38  int len;
39 
40  // current path from root to the current node
41  // excluding nodes into whose right (or left, for reverse iteration) branch the iterator has descended
42  // (these nodes are before the current)
45 
46 typedef int (*RContRBCmp)(void *incoming, void *in, void *user);
47 typedef void (*RContRBFree)(void *);
48 typedef struct rz_containing_rb_node_t {
50  void *data;
52 
53 typedef struct rz_containing_rb_tree_t {
57 
58 // Routines for augmented red-black trees. The user should provide an aggregation (monoid sum) callback `sum`
59 // to calculate extra information such as size, sum, ...
60 RZ_API bool rz_rbtree_aug_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user, RBNodeSum sum);
61 RZ_API bool rz_rbtree_aug_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *cmp_user, RBNodeSum sum);
62 RZ_API bool rz_rbtree_aug_update_sum(RBNode *root, void *data, RBNode *node, RBComparator cmp, void *cmp_user, RBNodeSum sum);
63 
64 RZ_API bool rz_rbtree_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user);
65 RZ_API RBNode *rz_rbtree_find(RBNode *root, void *data, RBComparator cmp, void *user);
67 RZ_API bool rz_rbtree_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user);
68 // Return the smallest node that is greater than or equal to `data`
69 RZ_API RBNode *rz_rbtree_lower_bound(RBNode *root, void *data, RBComparator cmp, void *user);
70 // Return the greatest node that is less than or equal to `data`
71 RZ_API RBNode *rz_rbtree_upper_bound(RBNode *root, void *data, RBComparator cmp, void *user);
72 
73 // Create a forward iterator starting from the leftmost node
75 // Create a backward iterator starting from the rightmost node
77 
78 // Iterate [lower_bound, end] forward, used with rz_rbtree_iter_next
80 // Iterate [begin, upper_bound] backward, used with rz_rbtree_iter_prev
82 
83 // struct Node { int key; RBNode rb; };
84 // rz_rbtree_iter_get (it, struct Node, rb)
85 #define rz_rbtree_iter_get(it, struc, rb) (container_of((it)->path[(it)->len - 1], struc, rb))
86 // If the iterator still contains elements, including the current
87 #define rz_rbtree_iter_has(it) ((it)->len)
88 // Move forward
90 // Move backward
92 
93 // Iterate all elements of the forward iterator
94 #define rz_rbtree_iter_while(it, data, struc, rb) \
95  for (; rz_rbtree_iter_has(&it) && (data = rz_rbtree_iter_get(&it, struc, rb)); rz_rbtree_iter_next(&(it)))
96 
97 // Iterate all elements of the backward iterator
98 #define rz_rbtree_iter_while_prev(it, data, struc, rb) \
99  for (; rz_rbtree_iter_has(&it) && (data = rz_rbtree_iter_get(&it, struc, rb)); rz_rbtree_iter_prev(&(it)))
100 
101 #define rz_rbtree_foreach(root, it, data, struc, rb) \
102  for ((it) = rz_rbtree_first(root); rz_rbtree_iter_has(&it) && (data = rz_rbtree_iter_get(&it, struc, rb)); rz_rbtree_iter_next(&(it)))
103 
104 #define rz_rbtree_foreach_prev(root, it, data, struc, rb) \
105  for ((it) = rz_rbtree_last(root); rz_rbtree_iter_has(&it) && (data = rz_rbtree_iter_get(&it, struc, rb)); rz_rbtree_iter_prev(&(it)))
106 
109 RZ_API bool rz_rbtree_cont_insert(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
110 RZ_API bool rz_rbtree_cont_delete(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
111 RZ_API void *rz_rbtree_cont_find(RContRBTree *tree, void *data, RContRBCmp cmp, void *user);
112 
113 #define rz_rbtree_cont_foreach(tree, it, dat) \
114  for ((it) = rz_rbtree_first((tree)->root ? &(tree)->root->node : NULL); rz_rbtree_iter_has(&it) && (dat = rz_rbtree_iter_get(&it, RContRBNode, node)->data); rz_rbtree_iter_next(&(it)))
115 
116 #define rz_rbtree_cont_foreach_prev(tree, it, dat) \
117  for ((it) = rz_rbtree_last((tree)->root ? &(tree)->root->node : NULL); rz_rbtree_iter_has(&it) && (dat = rz_rbtree_iter_get(&it, RContRBNode, node)->data); rz_rbtree_iter_prev(&(it)))
118 
120 
121 #ifdef __cplusplus
122 }
123 #endif
124 
125 #endif
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
const lzma_allocator const uint8_t * in
Definition: block.h:527
#define RZ_API
int root
Definition: enough.c:226
static void freefn(HtName_(Ht) *ht, HT_(Kv) *kv)
Definition: ht_inc.c:46
RZ_API RZ_OWN RContRBTree * rz_rbtree_cont_newf(RContRBFree f)
Definition: rbtree.c:367
RZ_API bool rz_rbtree_cont_delete(RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
Definition: rbtree.c:443
RZ_API void rz_rbtree_cont_free(RContRBTree *tree)
Definition: rbtree.c:471
RZ_API RBNode * rz_rbtree_find(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:267
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281
RZ_API RBIter rz_rbtree_last(RBNode *root)
Definition: rbtree.c:344
RZ_API bool rz_rbtree_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user)
Returns true if the node was inserted successfully.
Definition: rbtree.c:291
struct rz_containing_rb_tree_t RContRBTree
void(* RContRBFree)(void *)
Definition: rz_rbtree.h:47
struct rz_rb_iter_t RBIter
void(* RBNodeFree)(RBNode *node, void *user)
Definition: rz_rbtree.h:31
RZ_API bool rz_rbtree_aug_update_sum(RBNode *root, void *data, RBNode *node, RBComparator cmp, void *cmp_user, RBNodeSum sum)
Returns true if the sum has been updated, false if node has not been found.
Definition: rbtree.c:235
RZ_API bool rz_rbtree_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user)
Returns true if a node with an equal key is deleted.
Definition: rbtree.c:263
struct rz_rb_node_t RBNode
RZ_API bool rz_rbtree_cont_insert(RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
Definition: rbtree.c:404
RBNode * RBTree
Definition: rz_rbtree.h:24
RZ_API bool rz_rbtree_aug_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user, RBNodeSum sum)
Returns true if a node with an equal key is deleted.
Definition: rbtree.c:67
void(* RBNodeSum)(RBNode *node)
Definition: rz_rbtree.h:32
RZ_API RBIter rz_rbtree_first(RBNode *root)
Definition: rbtree.c:340
struct rz_containing_rb_node_t RContRBNode
RZ_API RBIter rz_rbtree_lower_bound_forward(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:309
RZ_API void * rz_rbtree_cont_find(RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
Definition: rbtree.c:457
RZ_API RZ_OWN RContRBTree * rz_rbtree_cont_new(void)
Definition: rbtree.c:363
RZ_API void rz_rbtree_iter_next(RBIter *it)
Definition: rbtree.c:355
RZ_API void rz_rbtree_iter_prev(RBIter *it)
Definition: rbtree.c:359
#define RZ_RBTREE_MAX_HEIGHT
Definition: rz_rbtree.h:16
RZ_API RBNode * rz_rbtree_lower_bound(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:295
RZ_API bool rz_rbtree_aug_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *cmp_user, RBNodeSum sum)
Returns true if the node was inserted successfully.
Definition: rbtree.c:163
int(* RContRBCmp)(void *incoming, void *in, void *user)
Definition: rz_rbtree.h:46
RZ_API RBNode * rz_rbtree_upper_bound(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:313
int(* RBComparator)(const void *incoming, const RBNode *in_tree, void *user)
Definition: rz_rbtree.h:29
RZ_API RBIter rz_rbtree_upper_bound_backward(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:327
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
static int
Definition: sfsocketcall.h:114
#define f(i)
Definition: sha256.c:46
RContRBNode * root
Definition: rz_rbtree.h:54
RBNode * path[RZ_RBTREE_MAX_HEIGHT]
Definition: rz_rbtree.h:43
struct rz_rb_node_t * child[2]
Definition: rz_rbtree.h:20