Rizin
unix-like reverse engineering framework and cli tools
rz_intervaltree.h File Reference
#include "rz_rbtree.h"
#include "../rz_types.h"

Go to the source code of this file.

Classes

struct  rz_interval_node_t
 
struct  rz_interval_tree_t
 

Macros

#define rz_interval_tree_foreach(tree, it, dat)    for ((it) = rz_rbtree_first(&(tree)->root->node); rz_rbtree_iter_has(&it) && (dat = rz_interval_tree_iter_get(&it)->data); rz_rbtree_iter_next(&(it)))
 
#define rz_interval_tree_foreach_prev(tree, it, dat)    for ((it) = rz_rbtree_last(&(tree)->root->node); rz_rbtree_iter_has(&it) && (dat = rz_rbtree_iter_get(&it, RzIntervalNode, node)->data); rz_rbtree_iter_prev(&(it)))
 

Typedefs

typedef struct rz_interval_node_t RzIntervalNode
 
typedef void(* RzIntervalNodeFree) (void *data)
 
typedef struct rz_interval_tree_t RzIntervalTree
 
typedef bool(* RzIntervalIterCb) (RzIntervalNode *node, void *user)
 
typedef RBIter RzIntervalTreeIter
 

Functions

RZ_API void rz_interval_tree_init (RzIntervalTree *tree, RzIntervalNodeFree free)
 
RZ_API void rz_interval_tree_fini (RzIntervalTree *tree)
 
RZ_API bool rz_interval_tree_insert (RzIntervalTree *tree, ut64 start, ut64 end, void *data)
 
RZ_API bool rz_interval_tree_delete (RzIntervalTree *tree, RzIntervalNode *node, bool free)
 
RZ_API bool rz_interval_tree_resize (RzIntervalTree *tree, RzIntervalNode *node, ut64 new_start, ut64 new_end)
 
RZ_API RBIter rz_interval_tree_first_at (RzIntervalTree *tree, ut64 start)
 
RZ_API RzIntervalNoderz_interval_tree_node_at (RzIntervalTree *tree, ut64 start)
 
RZ_API RzIntervalNoderz_interval_tree_node_at_data (RzIntervalTree *tree, ut64 start, void *data)
 
static void * rz_interval_tree_at (RzIntervalTree *tree, ut64 start)
 
RZ_API bool rz_interval_tree_all_at (RzIntervalTree *tree, ut64 start, RzIntervalIterCb cb, void *user)
 
RZ_API bool rz_interval_tree_all_in (RzIntervalTree *tree, ut64 value, bool end_inclusive, RzIntervalIterCb cb, void *user)
 
RZ_API bool rz_interval_tree_all_intersect (RzIntervalTree *tree, ut64 start, ut64 end, bool end_inclusive, RzIntervalIterCb cb, void *user)
 
static RzIntervalNoderz_interval_tree_iter_get (RzIntervalTreeIter *it)
 
static bool rz_interval_tree_empty (RzIntervalTree *tree)
 

Macro Definition Documentation

◆ rz_interval_tree_foreach

#define rz_interval_tree_foreach (   tree,
  it,
  dat 
)     for ((it) = rz_rbtree_first(&(tree)->root->node); rz_rbtree_iter_has(&it) && (dat = rz_interval_tree_iter_get(&it)->data); rz_rbtree_iter_next(&(it)))

Definition at line 95 of file rz_intervaltree.h.

◆ rz_interval_tree_foreach_prev

#define rz_interval_tree_foreach_prev (   tree,
  it,
  dat 
)     for ((it) = rz_rbtree_last(&(tree)->root->node); rz_rbtree_iter_has(&it) && (dat = rz_rbtree_iter_get(&it, RzIntervalNode, node)->data); rz_rbtree_iter_prev(&(it)))

Definition at line 98 of file rz_intervaltree.h.

Typedef Documentation

◆ RzIntervalIterCb

typedef bool(* RzIntervalIterCb) (RzIntervalNode *node, void *user)

Definition at line 72 of file rz_intervaltree.h.

◆ RzIntervalNode

◆ RzIntervalNodeFree

typedef void(* RzIntervalNodeFree) (void *data)

Definition at line 31 of file rz_intervaltree.h.

◆ RzIntervalTree

◆ RzIntervalTreeIter

Definition at line 85 of file rz_intervaltree.h.

Function Documentation

◆ rz_interval_tree_all_at()

RZ_API bool rz_interval_tree_all_at ( RzIntervalTree tree,
ut64  start,
RzIntervalIterCb  cb,
void *  user 
)

Definition at line 221 of file intervaltree.c.

221  {
223  bool ret = true;
224  while (rz_rbtree_iter_has(&it)) {
225  RzIntervalNode *intervalnode = rz_rbtree_iter_get(&it, RzIntervalNode, node);
226  if (intervalnode->start != start) {
227  break;
228  }
229  ret = cb(intervalnode, user);
230  if (!ret) {
231  break;
232  }
233  rz_rbtree_iter_next(&it);
234  }
235  return ret;
236 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
RZ_API RBIter rz_interval_tree_first_at(RzIntervalTree *tree, ut64 start)
Definition: intervaltree.c:183
#define rz_rbtree_iter_get(it, struc, rb)
Definition: rz_rbtree.h:85
#define rz_rbtree_iter_has(it)
Definition: rz_rbtree.h:87
RZ_API void rz_rbtree_iter_next(RBIter *it)
Definition: rbtree.c:355
static const char * cb[]
Definition: z80_tab.h:176

References cb, rz_interval_tree_first_at(), rz_rbtree_iter_get, rz_rbtree_iter_has, rz_rbtree_iter_next(), rz_interval_node_t::start, and start.

Referenced by collect_nodes_at(), and find_node_at().

◆ rz_interval_tree_all_in()

RZ_API bool rz_interval_tree_all_in ( RzIntervalTree tree,
ut64  value,
bool  end_inclusive,
RzIntervalIterCb  cb,
void *  user 
)

Definition at line 262 of file intervaltree.c.

262  {
263  // all in! 🂡
264  return rz_interval_node_all_in(tree->root, value, end_inclusive, cb, user);
265 }
static int value
Definition: cmd_api.c:93
RZ_API bool rz_interval_node_all_in(RzIntervalNode *node, ut64 value, bool end_inclusive, RzIntervalIterCb cb, void *user)
Definition: intervaltree.c:238
RzIntervalNode * root

References cb, rz_interval_tree_t::root, rz_interval_node_all_in(), and value.

Referenced by collect_nodes_in(), find_node_in(), and rz_reg_filter_items_covered().

◆ rz_interval_tree_all_intersect()

RZ_API bool rz_interval_tree_all_intersect ( RzIntervalTree tree,
ut64  start,
ut64  end,
bool  end_inclusive,
RzIntervalIterCb  cb,
void *  user 
)

Definition at line 291 of file intervaltree.c.

291  {
292  return rz_interval_node_all_intersect(tree->root, start, end, end_inclusive, cb, user);
293 }
static bool rz_interval_node_all_intersect(RzIntervalNode *node, ut64 start, ut64 end, bool end_inclusive, RzIntervalIterCb cb, void *user)
Definition: intervaltree.c:267

References cb, test_evm::end, rz_interval_tree_t::root, rz_interval_node_all_intersect(), and start.

Referenced by collect_nodes_intersect().

◆ rz_interval_tree_at()

static void* rz_interval_tree_at ( RzIntervalTree tree,
ut64  start 
)
inlinestatic

Definition at line 67 of file rz_intervaltree.h.

67  {
69  return node ? node->data : NULL;
70 }
#define NULL
Definition: cris-opc.c:27
RZ_API RzIntervalNode * rz_interval_tree_node_at(RzIntervalTree *tree, ut64 start)
Definition: intervaltree.c:169

References rz_interval_node_t::data, NULL, rz_interval_tree_node_at(), and start.

◆ rz_interval_tree_delete()

RZ_API bool rz_interval_tree_delete ( RzIntervalTree tree,
RzIntervalNode node,
bool  free 
)

Definition at line 139 of file intervaltree.c.

139  {
140  RBNode *root = &tree->root->node;
141  RBIter path_cache = { 0 };
142  bool r = rz_rbtree_aug_delete(&root, node, cmp_exact_node, &path_cache, interval_node_free, free ? tree->free : NULL, node_max);
143  tree->root = unwrap(root);
144  return r;
145 }
#define r
Definition: crypto_rc6.c:12
int root
Definition: enough.c:226
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
#define unwrap(rbnode)
Definition: intervaltree.c:7
static int cmp_exact_node(const void *incoming, const RBNode *in_tree, void *user)
Definition: intervaltree.c:36
static void node_max(RBNode *node)
Definition: intervaltree.c:9
static void interval_node_free(RBNode *node, void *user)
Definition: intervaltree.c:106
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
RzIntervalNodeFree free

References cmp_exact_node(), rz_interval_tree_t::free, free(), interval_node_free(), rz_interval_node_t::node, node_max(), NULL, r, rz_interval_tree_t::root, root, rz_rbtree_aug_delete(), and unwrap.

Referenced by del(), and rz_interval_tree_resize().

◆ rz_interval_tree_empty()

static bool rz_interval_tree_empty ( RzIntervalTree tree)
inlinestatic

Definition at line 91 of file rz_intervaltree.h.

91  {
92  return tree->root == NULL;
93 }

References NULL, and rz_interval_tree_t::root.

Referenced by rz_serialize_analysis_meta_save().

◆ rz_interval_tree_fini()

RZ_API void rz_interval_tree_fini ( RzIntervalTree tree)

Definition at line 114 of file intervaltree.c.

114  {
115  if (!tree || !tree->root) {
116  return;
117  }
119 }
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281

References rz_interval_tree_t::free, interval_node_free(), rz_interval_node_t::node, rz_interval_tree_t::root, and rz_rbtree_free().

Referenced by rz_analysis_free(), rz_analysis_purge(), rz_meta_rebase(), and rz_reg_filter_items_covered().

◆ rz_interval_tree_first_at()

RZ_API RBIter rz_interval_tree_first_at ( RzIntervalTree tree,
ut64  start 
)

Definition at line 183 of file intervaltree.c.

183  {
184  RBIter it = { 0 };
185 
186  // Find the topmost node matching start so we have a sub-tree with all entries that we want to find.
187  RzIntervalNode *top_intervalnode = rz_interval_tree_node_at(tree, start);
188  if (!top_intervalnode) {
189  return it;
190  }
191 
192  // If there are more nodes with the same key, they can be in both children.
193  RBNode *node = &top_intervalnode->node;
194  while (node) {
195  if (start <= unwrap(node)->start) {
196  it.path[it.len++] = node;
197  node = node->child[0];
198  } else {
199  node = node->child[1];
200  }
201  }
202 
203  return it;
204 }
RZ_API RzIntervalNode * rz_interval_tree_node_at(RzIntervalTree *tree, ut64 start)
Definition: intervaltree.c:169
RBNode * path[RZ_RBTREE_MAX_HEIGHT]
Definition: rz_rbtree.h:43
struct rz_rb_node_t * child[2]
Definition: rz_rbtree.h:20

References rz_rb_node_t::child, rz_rb_iter_t::len, rz_interval_node_t::node, rz_rb_iter_t::path, rz_interval_tree_node_at(), start, and unwrap.

Referenced by rz_interval_tree_all_at(), and rz_interval_tree_node_at_data().

◆ rz_interval_tree_init()

RZ_API void rz_interval_tree_init ( RzIntervalTree tree,
RzIntervalNodeFree  free 
)

Definition at line 101 of file intervaltree.c.

101  {
102  tree->root = NULL;
103  tree->free = free;
104 }

References rz_interval_tree_t::free, free(), NULL, and rz_interval_tree_t::root.

Referenced by rz_analysis_new(), rz_analysis_purge(), rz_meta_rebase(), and rz_reg_filter_items_covered().

◆ rz_interval_tree_insert()

RZ_API bool rz_interval_tree_insert ( RzIntervalTree tree,
ut64  start,
ut64  end,
void *  data 
)

Definition at line 121 of file intervaltree.c.

121  {
122  rz_return_val_if_fail(end >= start, false);
124  if (!node) {
125  return false;
126  }
127  node->start = start;
128  node->end = end;
129  node->data = data;
130  RBNode *root = tree->root ? &tree->root->node : NULL;
131  bool r = rz_rbtree_aug_insert(&root, &start, &node->node, cmp, NULL, node_max);
132  tree->root = unwrap(root);
133  if (!r) {
134  free(node);
135  }
136  return r;
137 }
static int cmp(const void *incoming, const RBNode *in_tree, void *user)
Definition: intervaltree.c:23
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
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(), rz_interval_node_t::data, rz_interval_node_t::end, test_evm::end, free(), rz_interval_node_t::node, node_max(), NULL, r, rz_interval_tree_t::root, root, RZ_NEW0, rz_rbtree_aug_insert(), rz_return_val_if_fail, rz_interval_node_t::start, start, and unwrap.

Referenced by meta_load_cb(), meta_set(), rz_interval_tree_resize(), rz_meta_rebase(), and rz_reg_filter_items_covered().

◆ rz_interval_tree_iter_get()

◆ rz_interval_tree_node_at()

RZ_API RzIntervalNode* rz_interval_tree_node_at ( RzIntervalTree tree,
ut64  start 
)

Definition at line 169 of file intervaltree.c.

169  {
170  RzIntervalNode *node = tree->root;
171  while (node) {
172  if (start < node->start) {
173  node = unwrap(node->node.child[0]);
174  } else if (start > node->start) {
175  node = unwrap(node->node.child[1]);
176  } else {
177  return node;
178  }
179  }
180  return NULL;
181 }

References rz_rb_node_t::child, rz_interval_node_t::node, NULL, rz_interval_tree_t::root, rz_interval_node_t::start, start, and unwrap.

Referenced by rz_interval_tree_at(), and rz_interval_tree_first_at().

◆ rz_interval_tree_node_at_data()

RZ_API RzIntervalNode* rz_interval_tree_node_at_data ( RzIntervalTree tree,
ut64  start,
void *  data 
)

Definition at line 206 of file intervaltree.c.

206  {
208  while (rz_rbtree_iter_has(&it)) {
209  RzIntervalNode *intervalnode = rz_rbtree_iter_get(&it, RzIntervalNode, node);
210  if (intervalnode->start != start) {
211  break;
212  }
213  if (intervalnode->data == data) {
214  return intervalnode;
215  }
216  rz_rbtree_iter_next(&it);
217  }
218  return NULL;
219 }

References rz_interval_node_t::data, NULL, rz_interval_tree_first_at(), rz_rbtree_iter_get, rz_rbtree_iter_has, rz_rbtree_iter_next(), rz_interval_node_t::start, and start.

◆ rz_interval_tree_resize()

RZ_API bool rz_interval_tree_resize ( RzIntervalTree tree,
RzIntervalNode node,
ut64  new_start,
ut64  new_end 
)

Definition at line 147 of file intervaltree.c.

147  {
148  rz_return_val_if_fail(new_end >= new_start, false);
149  if (node->start != new_start) {
150  // Start change means the tree needs a different structure
151  void *data = node->data;
152  if (!rz_interval_tree_delete(tree, node, false)) {
153  return false;
154  }
155  return rz_interval_tree_insert(tree, new_start, new_end, data);
156  }
157  if (node->end != new_end) {
158  // Only end change just needs the updated augmented max value to be propagated upwards
159  node->end = new_end;
160  RBIter path_cache = { 0 };
161  return rz_rbtree_aug_update_sum(&tree->root->node, node, &node->node, cmp_exact_node, &path_cache, node_max);
162  }
163  // no change
164  return true;
165 }
RZ_API bool rz_interval_tree_delete(RzIntervalTree *tree, RzIntervalNode *node, bool free)
Definition: intervaltree.c:139
RZ_API bool rz_interval_tree_insert(RzIntervalTree *tree, ut64 start, ut64 end, void *data)
Definition: intervaltree.c:121
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

References cmp_exact_node(), rz_interval_node_t::data, rz_interval_node_t::end, rz_interval_node_t::node, node_max(), rz_interval_tree_t::root, rz_interval_tree_delete(), rz_interval_tree_insert(), rz_rbtree_aug_update_sum(), rz_return_val_if_fail, and rz_interval_node_t::start.

Referenced by meta_set().