Rizin
unix-like reverse engineering framework and cli tools
rbtree.c File Reference
#include <stdio.h>
#include <rz_util/rz_rbtree.h>
#include <rz_util.h>

Go to the source code of this file.

Classes

struct  rcrb_cmp_wrap_t
 

Typedefs

typedef struct rcrb_cmp_wrap_t RCRBCmpWrap
 

Functions

static bool red (RBNode *x)
 
static RBNodezag (RBNode *x, int dir, RBNodeSum sum)
 
static RBNodezig_zag (RBNode *x, int dir, RBNodeSum sum)
 
static RBIter bound_iter (RBNode *x, void *data, RBComparator cmp, bool upper, void *user)
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
RZ_API RBNoderz_rbtree_find (RBNode *x, void *data, RBComparator cmp, void *user)
 
RZ_API void rz_rbtree_free (RZ_NULLABLE RBNode *x, RBNodeFree freefn, void *user)
 
RZ_API bool rz_rbtree_insert (RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user)
 Returns true if the node was inserted successfully. More...
 
RZ_API RBNoderz_rbtree_lower_bound (RBNode *x, void *data, RBComparator cmp, void *user)
 
RZ_API RBIter rz_rbtree_lower_bound_forward (RBNode *root, void *data, RBComparator cmp, void *user)
 
RZ_API RBNoderz_rbtree_upper_bound (RBNode *x, void *data, RBComparator cmp, void *user)
 
RZ_API RBIter rz_rbtree_upper_bound_backward (RBNode *root, void *data, RBComparator cmp, void *user)
 
static RBIter _first (RBNode *x, int dir)
 
RZ_API RBIter rz_rbtree_first (RBNode *tree)
 
RZ_API RBIter rz_rbtree_last (RBNode *tree)
 
static void _next (RBIter *it, int dir)
 
RZ_API void rz_rbtree_iter_next (RBIter *it)
 
RZ_API void rz_rbtree_iter_prev (RBIter *it)
 
RZ_API RZ_OWN RContRBTreerz_rbtree_cont_new (void)
 
RZ_API RZ_OWN RContRBTreerz_rbtree_cont_newf (RContRBFree f)
 
static int cont_rbtree_cmp_wrapper (const void *incoming, const RBNode *in_tree, void *user)
 
static int cont_rbtree_search_cmp_wrapper (const void *incoming, const RBNode *in_tree, void *user)
 
static int cont_rbtree_free_cmp_wrapper (const void *data, const RBNode *in_tree, void *user)
 
RZ_API bool rz_rbtree_cont_insert (RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
 
static void cont_node_free (RBNode *node, void *user)
 
RZ_API bool rz_rbtree_cont_delete (RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
 
RZ_API void * rz_rbtree_cont_find (RContRBTree *tree, void *data, RContRBCmp cmp, void *user)
 
RZ_API void rz_rbtree_cont_free (RContRBTree *tree)
 

Typedef Documentation

◆ RCRBCmpWrap

typedef struct rcrb_cmp_wrap_t RCRBCmpWrap

Function Documentation

◆ _first()

static RBIter _first ( RBNode x,
int  dir 
)
static

Definition at line 331 of file rbtree.c.

331  {
332  RBIter it;
333  it.len = 0;
334  for (; x; x = x->child[dir]) {
335  it.path[it.len++] = x;
336  }
337  return it;
338 }
int x
Definition: mipsasm.c:20
RBNode * path[RZ_RBTREE_MAX_HEIGHT]
Definition: rz_rbtree.h:43

References rz_rb_iter_t::len, rz_rb_iter_t::path, and x.

Referenced by rz_rbtree_first(), and rz_rbtree_last().

◆ _next()

static void _next ( RBIter it,
int  dir 
)
inlinestatic

Definition at line 348 of file rbtree.c.

348  {
349  RBNode *x = it->path[--it->len];
350  for (x = x->child[!dir]; x; x = x->child[dir]) {
351  it->path[it->len++] = x;
352  }
353 }

References rz_rb_iter_t::len, rz_rb_iter_t::path, and x.

Referenced by rz_rbtree_iter_next(), and rz_rbtree_iter_prev().

◆ bound_iter()

static RBIter bound_iter ( RBNode x,
void *  data,
RBComparator  cmp,
bool  upper,
void *  user 
)
inlinestatic

Definition at line 40 of file rbtree.c.

40  {
41  RBIter it = { 0 };
42  while (x) {
43  int d = cmp(data, x, user);
44 
45  if (d == 0) {
46  it.path[it.len++] = x;
47  return it;
48  }
49 
50  if (d < 0) {
51  if (!upper) {
52  it.path[it.len++] = x;
53  }
54  x = x->child[0];
55  } else {
56  if (upper) {
57  it.path[it.len++] = x;
58  }
59  x = x->child[1];
60  }
61  }
62 
63  return it;
64 }
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
#define d(i)
Definition: sha256.c:44

References cmp(), d, rz_rb_iter_t::len, rz_rb_iter_t::path, and x.

Referenced by rz_rbtree_lower_bound_forward(), and rz_rbtree_upper_bound_backward().

◆ cont_node_free()

static void cont_node_free ( RBNode node,
void *  user 
)
static

Definition at line 435 of file rbtree.c.

435  {
436  RContRBNode *contnode = container_of(node, RContRBNode, node);
437  if (user) {
438  ((RContRBFree)user)(contnode->data);
439  }
440  free(contnode);
441 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
void(* RContRBFree)(void *)
Definition: rz_rbtree.h:47
#define container_of(ptr, type, member)
Definition: rz_types.h:650

References container_of, rz_containing_rb_node_t::data, and free().

Referenced by rz_rbtree_cont_delete(), and rz_rbtree_cont_free().

◆ cont_rbtree_cmp_wrapper()

static int cont_rbtree_cmp_wrapper ( const void *  incoming,
const RBNode in_tree,
void *  user 
)
static

Definition at line 381 of file rbtree.c.

381  {
382  RCRBCmpWrap *cmp_wrap = (RCRBCmpWrap *)user;
383  RContRBNode *incoming_node = (RContRBNode *)incoming;
384  RContRBNode *in_tree_node = container_of((RBNode *)in_tree, RContRBNode, node);
385  return cmp_wrap->cmp(incoming_node->data, in_tree_node->data, cmp_wrap->user);
386 }
RContRBCmp cmp
Definition: rbtree.c:376
void * user
Definition: rbtree.c:378

References rcrb_cmp_wrap_t::cmp, container_of, rz_containing_rb_node_t::data, and rcrb_cmp_wrap_t::user.

Referenced by cont_rbtree_free_cmp_wrapper(), and rz_rbtree_cont_insert().

◆ cont_rbtree_free_cmp_wrapper()

static int cont_rbtree_free_cmp_wrapper ( const void *  data,
const RBNode in_tree,
void *  user 
)
static

Definition at line 394 of file rbtree.c.

394  {
395  RCRBCmpWrap *cmp_wrap = (RCRBCmpWrap *)user;
396  const int ret = cont_rbtree_cmp_wrapper((void *)data, in_tree, user);
397  if (!ret && cmp_wrap->free) { // this is for deleting
398  RContRBNode *in_tree_node = container_of((void *)in_tree, RContRBNode, node);
399  cmp_wrap->free(in_tree_node->data);
400  }
401  return ret;
402 }
static int cont_rbtree_cmp_wrapper(const void *incoming, const RBNode *in_tree, void *user)
Definition: rbtree.c:381
RContRBFree free
Definition: rbtree.c:377

References cont_rbtree_cmp_wrapper(), container_of, rz_containing_rb_node_t::data, and rcrb_cmp_wrap_t::free.

Referenced by rz_rbtree_cont_delete().

◆ cont_rbtree_search_cmp_wrapper()

static int cont_rbtree_search_cmp_wrapper ( const void *  incoming,
const RBNode in_tree,
void *  user 
)
static

Definition at line 388 of file rbtree.c.

388  {
389  RCRBCmpWrap *cmp_wrap = (RCRBCmpWrap *)user;
390  RContRBNode *in_tree_node = container_of((RBNode *)in_tree, RContRBNode, node);
391  return cmp_wrap->cmp((void *)incoming, in_tree_node->data, cmp_wrap->user);
392 }

References rcrb_cmp_wrap_t::cmp, container_of, rz_containing_rb_node_t::data, and rcrb_cmp_wrap_t::user.

Referenced by rz_rbtree_cont_find().

◆ red()

static bool red ( RBNode x)
inlinestatic

Definition at line 9 of file rbtree.c.

9  {
10  return x && x->red;
11 }

References x.

Referenced by rz_rbtree_aug_delete(), and rz_rbtree_aug_insert().

◆ rz_rbtree_aug_delete()

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 at line 67 of file rbtree.c.

67  {
68  RBNode head, *del = NULL, **del_link = NULL, *g = NULL, *p = NULL, *q = &head, *path[RZ_RBTREE_MAX_HEIGHT];
69  int d = 1, d2, dep = 0;
70  head.child[0] = NULL;
71  head.child[1] = *root;
72  while (q->child[d]) {
73  d2 = d;
74  g = p;
75  p = q;
76  if (del_link) {
77  d = 1;
78  } else {
79  d = cmp(data, q->child[d2], cmp_user);
80  if (d < 0) {
81  d = 0;
82  } else if (d > 0) {
83  d = 1;
84  } else {
85  del_link = &q->child[d2];
86  }
87  }
88  if (q != &head) {
89  if (dep >= RZ_RBTREE_MAX_HEIGHT) {
90  RZ_LOG_ERROR("Red-black tree depth is too big\n");
91  break;
92  }
93  path[dep++] = q;
94  }
95  q = q->child[d2];
96  if (q->red || red(q->child[d])) {
97  continue;
98  }
99  if (red(q->child[!d])) {
100  if (del_link && *del_link == q) {
101  del_link = &q->child[!d]->child[d];
102  }
103  p->child[d2] = zag(q, !d, sum);
104  p = p->child[d2];
105  if (dep >= RZ_RBTREE_MAX_HEIGHT) {
106  RZ_LOG_ERROR("Red-black tree depth is too big\n");
107  break;
108  }
109  path[dep++] = p;
110  } else {
111  RBNode *s = p->child[!d2];
112  if (!s) {
113  continue;
114  }
115  if (!red(s->child[0]) && !red(s->child[1])) {
116  p->red = false;
117  q->red = s->red = true;
118  } else {
119  int d3 = g->child[0] != p;
120  RBNode *t;
121  if (red(s->child[d2])) {
122  if (del_link && *del_link == p) {
123  del_link = &s->child[d2]->child[d2];
124  }
125  t = zig_zag(p, !d2, sum);
126  } else {
127  if (del_link && *del_link == p) {
128  del_link = &s->child[d2];
129  }
130  t = zag(p, !d2, sum);
131  }
132  t->red = q->red = true;
133  t->child[0]->red = t->child[1]->red = false;
134  g->child[d3] = t;
135  path[dep - 1] = t;
136  path[dep++] = p;
137  }
138  }
139  }
140  if (del_link) {
141  del = *del_link;
142  p->child[q != p->child[0]] = q->child[q->child[0] == NULL];
143  if (del != q) {
144  *q = *del;
145  *del_link = q;
146  }
147  if (freefn) {
148  freefn(del, free_user);
149  }
150  }
151  if (sum) {
152  while (dep--) {
153  sum(path[dep] == del ? q : path[dep]);
154  }
155  }
156  if ((*root = head.child[1])) {
157  (*root)->red = false;
158  }
159  return del;
160 }
#define NULL
Definition: cris-opc.c:27
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
int root
Definition: enough.c:226
struct @667 g
static void freefn(HtName_(Ht) *ht, HT_(Kv) *kv)
Definition: ht_inc.c:46
void * p
Definition: libc.cpp:67
static void del(RzAnalysis *a, RzAnalysisMetaType type, const RzSpace *space, ut64 addr, ut64 size)
Definition: meta.c:155
static RBNode * zig_zag(RBNode *x, int dir, RBNodeSum sum)
Definition: rbtree.c:25
static bool red(RBNode *x)
Definition: rbtree.c:9
static RBNode * zag(RBNode *x, int dir, RBNodeSum sum)
Definition: rbtree.c:13
static RzSocket * s
Definition: rtr.c:28
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define RZ_RBTREE_MAX_HEIGHT
Definition: rz_rbtree.h:16
struct rz_rb_node_t * child[2]
Definition: rz_rbtree.h:20

References rz_rb_node_t::child, cmp(), d, d2, d3, del(), freefn(), g, test-lz4-versions::head, NULL, p, path, rz_rb_node_t::red, red(), root, RZ_LOG_ERROR, RZ_RBTREE_MAX_HEIGHT, s, zag(), and zig_zag().

Referenced by rz_analysis_block_merge(), rz_analysis_block_relocate(), rz_analysis_block_unref(), rz_interval_tree_delete(), rz_rbtree_cont_delete(), and rz_rbtree_delete().

◆ rz_rbtree_aug_insert()

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 at line 163 of file rbtree.c.

163  {
164  node->child[0] = node->child[1] = NULL;
165  if (!*root) {
166  *root = node;
167  node->red = false;
168  if (sum) {
169  sum(node);
170  }
171  return true;
172  }
173  RBNode *t = NULL, *g = NULL, *p = NULL, *q = *root;
174  int d = 0, dep = 0;
175  bool done = false;
177  for (;;) {
178  if (!q) {
179  q = node;
180  q->red = true;
181  p->child[d] = q;
182  done = true;
183  } else if (red(q->child[0]) && red(q->child[1])) {
184  q->child[0]->red = q->child[1]->red = false;
185  if (q != *root) {
186  q->red = true;
187  }
188  }
189  if (q->red && p && p->red) {
190  int d3 = t ? t->child[0] != g : -1, d2 = g->child[0] != p;
191  if (p->child[d2] == q) {
192  g = zag(g, d2, sum);
193  dep--;
194  path[dep - 1] = g;
195  } else {
196  g = zig_zag(g, d2, sum);
197  dep -= 2;
198  }
199  if (t) {
200  t->child[d3] = g;
201  } else {
202  *root = g;
203  }
204  }
205  if (done) {
206  break;
207  }
208  d = cmp(data, q, cmp_user);
209  t = g;
210  g = p;
211  p = q;
212  if (dep >= RZ_RBTREE_MAX_HEIGHT) {
213  RZ_LOG_ERROR("Red-black tree depth is too big\n");
214  break;
215  }
216  path[dep++] = q;
217  if (d < 0) {
218  d = 0;
219  q = q->child[0];
220  } else {
221  d = 1;
222  q = q->child[1];
223  }
224  }
225  if (sum) {
226  sum(q);
227  while (dep) {
228  sum(path[--dep]);
229  }
230  }
231  return done;
232 }
struct tab * done
Definition: enough.c:233

References rz_rb_node_t::child, cmp(), d, d2, d3, done, g, NULL, p, path, rz_rb_node_t::red, red(), root, RZ_LOG_ERROR, RZ_RBTREE_MAX_HEIGHT, zag(), and zig_zag().

Referenced by rz_analysis_block_relocate(), rz_analysis_block_split(), rz_analysis_create_block(), rz_analysis_var_global_add(), rz_interval_tree_insert(), rz_rbtree_cont_insert(), and rz_rbtree_insert().

◆ rz_rbtree_aug_update_sum()

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 at line 235 of file rbtree.c.

235  {
236  size_t dep = 0;
238  RBNode *cur = root;
239  for (;;) {
240  if (!cur) {
241  return false;
242  }
243  if (dep >= RZ_RBTREE_MAX_HEIGHT) {
244  RZ_LOG_ERROR("Red-black tree depth is too big\n");
245  return false;
246  }
247  path[dep] = cur;
248  dep++;
249  if (cur == node) {
250  break;
251  }
252  int d = cmp(data, cur, cmp_user);
253  cur = cur->child[(d < 0) ? 0 : 1];
254  }
255 
256  for (; dep > 0; dep--) {
257  sum(path[dep - 1]);
258  }
259  return true;
260 }

References rz_rb_node_t::child, cmp(), d, path, root, RZ_LOG_ERROR, and RZ_RBTREE_MAX_HEIGHT.

Referenced by rz_analysis_block_set_size(), and rz_interval_tree_resize().

◆ rz_rbtree_cont_delete()

RZ_API bool rz_rbtree_cont_delete ( RContRBTree tree,
void *  data,
RContRBCmp  cmp,
void *  user 
)

Definition at line 443 of file rbtree.c.

443  {
444  if (!(tree && cmp && tree->root)) {
445  return false;
446  }
447  RCRBCmpWrap cmp_wrap = { cmp, tree->free, user };
448  RContRBNode data_wrap = { { { NULL, NULL }, false }, data };
449  RBNode *root_node = &tree->root->node;
450  const bool ret = rz_rbtree_aug_delete(&root_node, &data_wrap, cont_rbtree_free_cmp_wrapper, &cmp_wrap, cont_node_free, NULL, NULL);
451  if (root_node != (&tree->root->node)) {
452  tree->root = container_of(root_node, RContRBNode, node);
453  }
454  return ret;
455 }
static void cont_node_free(RBNode *node, void *user)
Definition: rbtree.c:435
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
static int cont_rbtree_free_cmp_wrapper(const void *data, const RBNode *in_tree, void *user)
Definition: rbtree.c:394
RContRBNode * root
Definition: rz_rbtree.h:54

References cmp(), cont_node_free(), cont_rbtree_free_cmp_wrapper(), container_of, rz_containing_rb_tree_t::free, rz_containing_rb_node_t::node, NULL, rz_containing_rb_tree_t::root, and rz_rbtree_aug_delete().

◆ rz_rbtree_cont_find()

RZ_API void* rz_rbtree_cont_find ( RContRBTree tree,
void *  data,
RContRBCmp  cmp,
void *  user 
)

Definition at line 457 of file rbtree.c.

457  {
458  rz_return_val_if_fail(tree && cmp, NULL);
459  if (!tree->root) {
460  return NULL;
461  }
462  RCRBCmpWrap cmp_wrap = { cmp, NULL, user };
463  // RBNode search_node = tree->root->node;
464  RBNode *result_node = rz_rbtree_find(&tree->root->node, data, cont_rbtree_search_cmp_wrapper, &cmp_wrap);
465  if (result_node) {
466  return (container_of(result_node, RContRBNode, node))->data;
467  }
468  return NULL;
469 }
RZ_API RBNode * rz_rbtree_find(RBNode *x, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:267
static int cont_rbtree_search_cmp_wrapper(const void *incoming, const RBNode *in_tree, void *user)
Definition: rbtree.c:388
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References cmp(), cont_rbtree_search_cmp_wrapper(), container_of, rz_containing_rb_node_t::node, NULL, rz_containing_rb_tree_t::root, rz_rbtree_find(), and rz_return_val_if_fail.

◆ rz_rbtree_cont_free()

RZ_API void rz_rbtree_cont_free ( RContRBTree tree)

Definition at line 471 of file rbtree.c.

471  {
472  if (tree && tree->root) {
473  rz_rbtree_free(&tree->root->node, cont_node_free, tree->free);
474  }
475  free(tree);
476 }
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *x, RBNodeFree freefn, void *user)
Definition: rbtree.c:281

References cont_node_free(), rz_containing_rb_tree_t::free, free(), rz_containing_rb_node_t::node, rz_containing_rb_tree_t::root, and rz_rbtree_free().

◆ rz_rbtree_cont_insert()

RZ_API bool rz_rbtree_cont_insert ( RContRBTree tree,
void *  data,
RContRBCmp  cmp,
void *  user 
)

Definition at line 404 of file rbtree.c.

404  {
405  rz_return_val_if_fail(tree && cmp, false);
406  if (!tree->root) {
407  tree->root = RZ_NEW0(RContRBNode);
408  if (!tree->root) {
409  RZ_LOG_ERROR("Failed to allocate new red-black tree root\n");
410  return false;
411  }
412  tree->root->data = data;
413  return true;
414  }
415  RContRBNode *incoming_node = RZ_NEW0(RContRBNode);
416  if (!incoming_node) {
417  RZ_LOG_ERROR("Failed to allocate new red-black tree node\n");
418  return false;
419  }
420  incoming_node->data = data;
421  RCRBCmpWrap cmp_wrap = { cmp, NULL, user };
422  RBNode *root_node = &tree->root->node;
423  const bool ret = rz_rbtree_aug_insert(&root_node, incoming_node,
424  &incoming_node->node, cont_rbtree_cmp_wrapper, &cmp_wrap, NULL);
425  if (root_node != (&tree->root->node)) {
426  tree->root = container_of(root_node, RContRBNode, node);
427  }
428  if (!ret) {
429  RZ_LOG_ERROR("Failed to insert new red-black tree node\n");
430  free(incoming_node);
431  }
432  return ret;
433 }
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
#define RZ_NEW0(x)
Definition: rz_types.h:284

References cmp(), cont_rbtree_cmp_wrapper(), container_of, rz_containing_rb_node_t::data, free(), rz_containing_rb_node_t::node, NULL, rz_containing_rb_tree_t::root, RZ_LOG_ERROR, RZ_NEW0, rz_rbtree_aug_insert(), and rz_return_val_if_fail.

◆ rz_rbtree_cont_new()

RZ_API RZ_OWN RContRBTree* rz_rbtree_cont_new ( void  )

Definition at line 363 of file rbtree.c.

363  {
364  return RZ_NEW0(RContRBTree);
365 }

References RZ_NEW0.

Referenced by rz_rbtree_cont_newf().

◆ rz_rbtree_cont_newf()

RZ_API RZ_OWN RContRBTree* rz_rbtree_cont_newf ( RContRBFree  f)

Definition at line 367 of file rbtree.c.

367  {
369  if (tree) {
370  tree->free = f;
371  }
372  return tree;
373 }
RZ_API RZ_OWN RContRBTree * rz_rbtree_cont_new(void)
Definition: rbtree.c:363
#define f(i)
Definition: sha256.c:46

References f, rz_containing_rb_tree_t::free, and rz_rbtree_cont_new().

◆ rz_rbtree_delete()

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 at line 263 of file rbtree.c.

263  {
264  return rz_rbtree_aug_delete(root, data, cmp, cmp_user, freefn, free_user, NULL);
265 }

References cmp(), freefn(), NULL, root, and rz_rbtree_aug_delete().

Referenced by rz_analysis_hint_unset_arch(), rz_analysis_hint_unset_bits(), rz_analysis_var_global_delete(), rz_spaces_rename(), and spaces_unset_single().

◆ rz_rbtree_find()

RZ_API RBNode* rz_rbtree_find ( RBNode x,
void *  data,
RBComparator  cmp,
void *  user 
)

Definition at line 267 of file rbtree.c.

267  {
268  while (x) {
269  int d = cmp(data, x, user);
270  if (d < 0) {
271  x = x->child[0];
272  } else if (d > 0) {
273  x = x->child[1];
274  } else {
275  return x;
276  }
277  }
278  return NULL;
279 }

References cmp(), d, NULL, and x.

Referenced by ensure_ranged_hint_record(), rz_analysis_get_block_at(), rz_analysis_var_global_get_byaddr_at(), rz_bin_pdb_get_type_by_index(), rz_rbtree_cont_find(), and rz_spaces_get().

◆ rz_rbtree_first()

RZ_API RBIter rz_rbtree_first ( RBNode tree)

Definition at line 340 of file rbtree.c.

340  {
341  return _first(tree, 0);
342 }
static RBIter _first(RBNode *x, int dir)
Definition: rbtree.c:331

References _first().

Referenced by rz_spaces_is_empty().

◆ rz_rbtree_free()

RZ_API void rz_rbtree_free ( RZ_NULLABLE RBNode x,
RBNodeFree  freefn,
void *  user 
)

Definition at line 281 of file rbtree.c.

281  {
282  if (!x) {
283  return;
284  }
285  rz_rbtree_free(x->child[0], freefn, user);
286  rz_rbtree_free(x->child[1], freefn, user);
287  freefn(x, user);
288 }

References freefn(), rz_rbtree_free(), and x.

Referenced by free_tpi_stream(), rz_analysis_free(), rz_analysis_hint_storage_fini(), rz_core_analysis_hint_list_print(), rz_core_analysis_hint_print(), rz_interval_tree_fini(), rz_rbtree_cont_free(), rz_rbtree_free(), rz_spaces_fini(), and rz_spaces_purge().

◆ rz_rbtree_insert()

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 at line 291 of file rbtree.c.

291  {
292  return rz_rbtree_aug_insert(root, data, node, cmp, user, NULL);
293 }

References cmp(), NULL, root, and rz_rbtree_aug_insert().

Referenced by ensure_ranged_hint_record(), parse_simple_type(), parse_tpi_stream(), print_addr_hint_cb(), print_arch_hint_cb(), print_bits_hint_cb(), rz_spaces_add(), and rz_spaces_rename().

◆ rz_rbtree_iter_next()

RZ_API void rz_rbtree_iter_next ( RBIter it)

Definition at line 355 of file rbtree.c.

355  {
356  _next(it, 0);
357 }
static void _next(RBIter *it, int dir)
Definition: rbtree.c:348

References _next().

Referenced by rz_interval_tree_all_at(), and rz_interval_tree_node_at_data().

◆ rz_rbtree_iter_prev()

RZ_API void rz_rbtree_iter_prev ( RBIter it)

Definition at line 359 of file rbtree.c.

359  {
360  _next(it, 1);
361 }

References _next().

◆ rz_rbtree_last()

RZ_API RBIter rz_rbtree_last ( RBNode tree)

Definition at line 344 of file rbtree.c.

344  {
345  return _first(tree, 1);
346 }

References _first().

◆ rz_rbtree_lower_bound()

RZ_API RBNode* rz_rbtree_lower_bound ( RBNode x,
void *  data,
RBComparator  cmp,
void *  user 
)

Definition at line 295 of file rbtree.c.

295  {
296  RBNode *ret = NULL;
297  while (x) {
298  int d = cmp(data, x, user);
299  if (d <= 0) {
300  ret = x;
301  x = x->child[0];
302  } else {
303  x = x->child[1];
304  }
305  }
306  return ret;
307 }

References cmp(), d, NULL, and x.

Referenced by rz_analysis_hint_del().

◆ rz_rbtree_lower_bound_forward()

RZ_API RBIter rz_rbtree_lower_bound_forward ( RBNode root,
void *  data,
RBComparator  cmp,
void *  user 
)

Definition at line 309 of file rbtree.c.

309  {
310  return bound_iter(root, data, cmp, false, user);
311 }
static RBIter bound_iter(RBNode *x, void *data, RBComparator cmp, bool upper, void *user)
Definition: rbtree.c:40

References bound_iter(), cmp(), and root.

◆ rz_rbtree_upper_bound()

RZ_API RBNode* rz_rbtree_upper_bound ( RBNode x,
void *  data,
RBComparator  cmp,
void *  user 
)

Definition at line 313 of file rbtree.c.

313  {
314  void *ret = NULL;
315  while (x) {
316  int d = cmp(data, x, user);
317  if (d < 0) {
318  x = x->child[0];
319  } else {
320  ret = x;
321  x = x->child[1];
322  }
323  }
324  return ret;
325 }

References cmp(), d, NULL, and x.

Referenced by rz_analysis_hint_arch_at(), rz_analysis_hint_bits_at(), and rz_analysis_var_global_get_byaddr_in().

◆ rz_rbtree_upper_bound_backward()

RZ_API RBIter rz_rbtree_upper_bound_backward ( RBNode root,
void *  data,
RBComparator  cmp,
void *  user 
)

Definition at line 327 of file rbtree.c.

327  {
328  return bound_iter(root, data, cmp, true, user);
329 }

References bound_iter(), cmp(), and root.

◆ zag()

static RBNode* zag ( RBNode x,
int  dir,
RBNodeSum  sum 
)
inlinestatic

Definition at line 13 of file rbtree.c.

13  {
14  RBNode *y = x->child[dir];
15  x->child[dir] = y->child[!dir];
16  y->child[!dir] = x;
17  x->red = true;
18  y->red = false;
19  if (sum) {
20  sum(x);
21  }
22  return y;
23 }

References rz_rb_node_t::child, rz_rb_node_t::red, and x.

Referenced by rz_rbtree_aug_delete(), and rz_rbtree_aug_insert().

◆ zig_zag()

static RBNode* zig_zag ( RBNode x,
int  dir,
RBNodeSum  sum 
)
inlinestatic

Definition at line 25 of file rbtree.c.

25  {
26  RBNode *y = x->child[dir], *z = y->child[!dir];
27  y->child[!dir] = z->child[dir];
28  z->child[dir] = y;
29  x->child[dir] = z->child[!dir];
30  z->child[!dir] = x;
31  x->red = y->red = true;
32  z->red = false;
33  if (sum) {
34  sum(x);
35  sum(y);
36  }
37  return z;
38 }

References rz_rb_node_t::child, rz_rb_node_t::red, and x.

Referenced by rz_rbtree_aug_delete(), and rz_rbtree_aug_insert().