Rizin
unix-like reverse engineering framework and cli tools
skiplist.c File Reference
#include <rz_skiplist.h>

Go to the source code of this file.

Macros

#define SKIPLIST_MAX_DEPTH   31
 

Functions

static RzSkipListNoderz_skiplist_node_new (void *data, int level)
 
static void rz_skiplist_node_free (RzSkipList *list, RzSkipListNode *node)
 
static void init_head (RzSkipListNode *head)
 
static RzSkipListNodefind_insertpoint (RzSkipList *list, void *data, RzSkipListNode **updates, bool by_data)
 
static bool delete_element (RzSkipList *list, void *data, bool by_data)
 
RZ_API RzSkipListrz_skiplist_new (RzListFree freefn, RzListComparator comparefn)
 
RZ_API void rz_skiplist_purge (RzSkipList *list)
 
RZ_API void rz_skiplist_free (RzSkipList *list)
 
RZ_API RzSkipListNoderz_skiplist_insert (RzSkipList *list, void *data)
 
RZ_API bool rz_skiplist_delete (RzSkipList *list, void *data)
 
RZ_API bool rz_skiplist_delete_node (RzSkipList *list, RzSkipListNode *node)
 
RZ_API RzSkipListNoderz_skiplist_find (RzSkipList *list, void *data)
 
RZ_API RzSkipListNoderz_skiplist_find_geq (RzSkipList *list, void *data)
 
RZ_API RzSkipListNoderz_skiplist_find_leq (RzSkipList *list, void *data)
 
RZ_API void rz_skiplist_join (RzSkipList *l1, RzSkipList *l2)
 
RZ_API void * rz_skiplist_get_first (RzSkipList *list)
 
RZ_API void * rz_skiplist_get_n (RzSkipList *list, int n)
 
RZ_API void * rz_skiplist_get_geq (RzSkipList *list, void *data)
 
RZ_API void * rz_skiplist_get_leq (RzSkipList *list, void *data)
 
RZ_API bool rz_skiplist_empty (RzSkipList *list)
 
RZ_API RzListrz_skiplist_to_list (RzSkipList *list)
 

Macro Definition Documentation

◆ SKIPLIST_MAX_DEPTH

#define SKIPLIST_MAX_DEPTH   31

Definition at line 12 of file skiplist.c.

Function Documentation

◆ delete_element()

static bool delete_element ( RzSkipList list,
void *  data,
bool  by_data 
)
static

Definition at line 73 of file skiplist.c.

73  {
74  int i;
76 
77  // locate delete points in the lists of all levels
78  x = find_insertpoint(list, data, update, by_data);
79  // do nothing if the element is not present in the list
80  if (x == list->head || list->compare(x->data, data) != 0) {
81  return false;
82  }
83 
84  // update forward links for all `update` points,
85  // by removing the element from the list in each level
86  for (i = 0; i <= list->list_level; i++) {
87  if (update[i]->forward[i] != x) {
88  break;
89  }
90  update[i]->forward[i] = x->forward[i];
91  }
93 
94  // update the level of the list
95  while ((list->list_level > 0) &&
96  (list->head->forward[list->list_level] == list->head)) {
97  list->list_level--;
98  }
99  list->size--;
100  return true;
101 }
lzma_index ** i
Definition: index.h:629
static bool update(RzCrypto *cry, const ut8 *buf, int len)
Definition: crypto_aes.c:92
static void list(RzEgg *egg)
Definition: rz-gg.c:52
int x
Definition: mipsasm.c:20
static void rz_skiplist_node_free(RzSkipList *list, RzSkipListNode *node)
Definition: skiplist.c:28
#define SKIPLIST_MAX_DEPTH
Definition: skiplist.c:12
static RzSkipListNode * find_insertpoint(RzSkipList *list, void *data, RzSkipListNode **updates, bool by_data)
Definition: skiplist.c:51

References find_insertpoint(), i, list(), rz_skiplist_node_free(), SKIPLIST_MAX_DEPTH, update(), and x.

Referenced by rz_skiplist_delete(), and rz_skiplist_delete_node().

◆ find_insertpoint()

static RzSkipListNode* find_insertpoint ( RzSkipList list,
void *  data,
RzSkipListNode **  updates,
bool  by_data 
)
static

Definition at line 51 of file skiplist.c.

51  {
52  RzSkipListNode *x = list->head;
53  int i;
54 
55  for (i = list->list_level; i >= 0; i--) {
56  if (by_data) {
57  while (x->forward[i] != list->head && list->compare(x->forward[i]->data, data) < 0) {
58  x = x->forward[i];
59  }
60  } else {
61  while (x->forward[i] != list->head && x->forward[i] != data) {
62  x = x->forward[i];
63  }
64  }
65  if (updates) {
66  updates[i] = x;
67  }
68  }
69  x = x->forward[0];
70  return x;
71 }

References i, list(), and x.

Referenced by delete_element(), rz_skiplist_find(), rz_skiplist_find_geq(), and rz_skiplist_insert().

◆ init_head()

static void init_head ( RzSkipListNode head)
static

Definition at line 38 of file skiplist.c.

38  {
39  int i;
40  for (i = 0; i <= SKIPLIST_MAX_DEPTH; i++) {
41  head->forward[i] = head;
42  }
43 }

References test-lz4-versions::head, i, and SKIPLIST_MAX_DEPTH.

Referenced by rz_skiplist_new(), and rz_skiplist_purge().

◆ rz_skiplist_delete()

RZ_API bool rz_skiplist_delete ( RzSkipList list,
void *  data 
)

Definition at line 201 of file skiplist.c.

201  {
202  return delete_element(list, data, true);
203 }
static bool delete_element(RzSkipList *list, void *data, bool by_data)
Definition: skiplist.c:73

References delete_element(), and list().

Referenced by remove_offsetmap().

◆ rz_skiplist_delete_node()

RZ_API bool rz_skiplist_delete_node ( RzSkipList list,
RzSkipListNode node 
)

Definition at line 206 of file skiplist.c.

206  {
207  return delete_element(list, node, false);
208 }

References delete_element(), and list().

◆ rz_skiplist_empty()

RZ_API bool rz_skiplist_empty ( RzSkipList list)

Definition at line 284 of file skiplist.c.

284  {
285  return list->size == 0;
286 }

References list().

◆ rz_skiplist_find()

RZ_API RzSkipListNode* rz_skiplist_find ( RzSkipList list,
void *  data 
)

Definition at line 210 of file skiplist.c.

210  {
211  RzSkipListNode *x = find_insertpoint(list, data, NULL, true);
212  if (x != list->head && list->compare(x->data, data) == 0) {
213  return x;
214  }
215  return NULL;
216 }
#define NULL
Definition: cris-opc.c:27

References find_insertpoint(), list(), NULL, and x.

Referenced by get_category_t(), and get_class_t().

◆ rz_skiplist_find_geq()

RZ_API RzSkipListNode* rz_skiplist_find_geq ( RzSkipList list,
void *  data 
)

Definition at line 218 of file skiplist.c.

218  {
219  RzSkipListNode *x = find_insertpoint(list, data, NULL, true);
220  return x != list->head ? x : NULL;
221 }

References find_insertpoint(), list(), NULL, and x.

Referenced by rz_skiplist_get_geq().

◆ rz_skiplist_find_leq()

RZ_API RzSkipListNode* rz_skiplist_find_leq ( RzSkipList list,
void *  data 
)

Definition at line 223 of file skiplist.c.

223  {
224  RzSkipListNode *x = list->head;
225  int i;
226 
227  for (i = list->list_level; i >= 0; i--) {
228  while (x->forward[i] != list->head && list->compare(x->forward[i]->data, data) <= 0) {
229  x = x->forward[i];
230  }
231  }
232  return x != list->head ? x : NULL;
233 }

References i, list(), NULL, and x.

Referenced by rz_skiplist_get_leq().

◆ rz_skiplist_free()

RZ_API void rz_skiplist_free ( RzSkipList list)

Definition at line 145 of file skiplist.c.

145  {
146  if (!list) {
147  return;
148  }
151  free(list);
152 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_skiplist_purge(RzSkipList *list)
Definition: skiplist.c:128

References free(), list(), rz_skiplist_node_free(), and rz_skiplist_purge().

Referenced by get_relocs(), mach0_free(), and rz_flag_free().

◆ rz_skiplist_get_first()

RZ_API void* rz_skiplist_get_first ( RzSkipList list)

Definition at line 248 of file skiplist.c.

248  {
249  if (!list) {
250  return NULL;
251  }
252  RzSkipListNode *res = list->head->forward[0];
253  return res == list->head ? NULL : res->data;
254 }

References rz_skiplist_node_t::data, list(), and NULL.

◆ rz_skiplist_get_geq()

RZ_API void* rz_skiplist_get_geq ( RzSkipList list,
void *  data 
)

Definition at line 273 of file skiplist.c.

273  {
275  return x ? x->data : NULL;
276 }
RZ_API RzSkipListNode * rz_skiplist_find_geq(RzSkipList *list, void *data)
Definition: skiplist.c:218

References list(), NULL, rz_skiplist_find_geq(), and x.

Referenced by rz_flag_get_nearest_list().

◆ rz_skiplist_get_leq()

RZ_API void* rz_skiplist_get_leq ( RzSkipList list,
void *  data 
)

Definition at line 278 of file skiplist.c.

278  {
280  return x ? x->data : NULL;
281 }
RZ_API RzSkipListNode * rz_skiplist_find_leq(RzSkipList *list, void *data)
Definition: skiplist.c:223

References list(), NULL, rz_skiplist_find_leq(), and x.

Referenced by rz_flag_get_nearest_list().

◆ rz_skiplist_get_n()

RZ_API void* rz_skiplist_get_n ( RzSkipList list,
int  n 
)

Definition at line 257 of file skiplist.c.

257  {
258  int count = 0;
259  RzSkipListNode *node;
260  void *data;
261  if (!list || n < 0) {
262  return NULL;
263  }
264  rz_skiplist_foreach (list, node, data) {
265  if (count == n) {
266  return data;
267  }
268  ++count;
269  }
270  return NULL;
271 }
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 count
Definition: sflib.h:98
int n
Definition: mipsasm.c:19
#define rz_skiplist_foreach(list, it, pos)
Definition: rz_skiplist.h:48

References count, list(), n, NULL, and rz_skiplist_foreach.

◆ rz_skiplist_insert()

RZ_API RzSkipListNode* rz_skiplist_insert ( RzSkipList list,
void *  data 
)

Definition at line 156 of file skiplist.c.

156  {
158  RzSkipListNode *x;
159  int i, x_level, new_level;
160 
161  // locate insertion points in the lists of all levels
162  x = find_insertpoint(list, data, update, true);
163  // check whether the element is already in the list
164  if (x != list->head && !list->compare(x->data, data)) {
165  return x;
166  }
167 
168  // randomly choose the number of levels the new node will be put in
169  for (x_level = 0; rand() < RAND_MAX / 2 && x_level < SKIPLIST_MAX_DEPTH; x_level++) {
170  ;
171  }
172 
173  // update the `update` array with default values when the current node
174  // has a level greater than the current one
175  new_level = list->list_level;
176  if (x_level > list->list_level) {
177  for (i = list->list_level + 1; i <= x_level; i++) {
178  update[i] = list->head;
179  }
180  new_level = x_level;
181  }
182 
183  x = rz_skiplist_node_new(data, x_level);
184  if (!x) {
185  return NULL;
186  }
187 
188  // update forward links for all `update` points,
189  // by inserting the new element in the list in each level
190  for (i = 0; i <= x_level; i++) {
191  x->forward[i] = update[i]->forward[i];
192  update[i]->forward[i] = x;
193  }
194 
195  list->list_level = new_level;
196  list->size++;
197  return x;
198 }
static RzSkipListNode * rz_skiplist_node_new(void *data, int level)
Definition: skiplist.c:14

References find_insertpoint(), i, list(), NULL, rz_skiplist_node_new(), SKIPLIST_MAX_DEPTH, update(), and x.

Referenced by flags_at_offset(), get_relocs(), parse_relocation_info(), and rz_skiplist_join().

◆ rz_skiplist_join()

RZ_API void rz_skiplist_join ( RzSkipList l1,
RzSkipList l2 
)

Definition at line 236 of file skiplist.c.

236  {
237  RzSkipListNode *it;
238  void *data;
239 
240  rz_skiplist_foreach (l2, it, data) {
241  (void)rz_skiplist_insert(l1, data);
242  }
243 
244  rz_skiplist_purge(l2);
245 }
RZ_API RzSkipListNode * rz_skiplist_insert(RzSkipList *list, void *data)
Definition: skiplist.c:156

References rz_skiplist_foreach, rz_skiplist_insert(), and rz_skiplist_purge().

◆ rz_skiplist_new()

RZ_API RzSkipList* rz_skiplist_new ( RzListFree  freefn,
RzListComparator  comparefn 
)

Definition at line 107 of file skiplist.c.

107  {
109  if (!list) {
110  return NULL;
111  }
112 
114  if (!list->head) {
115  free(list);
116  return NULL;
117  }
118 
119  init_head(list->head);
120  list->list_level = 0;
121  list->size = 0;
122  list->freefn = freefn;
123  list->compare = comparefn;
124  return list;
125 }
static void freefn(HtName_(Ht) *ht, HT_(Kv) *kv)
Definition: ht_inc.c:46
#define RZ_NEW0(x)
Definition: rz_types.h:284
static void init_head(RzSkipListNode *head)
Definition: skiplist.c:38

References free(), freefn(), init_head(), list(), NULL, RZ_NEW0, rz_skiplist_node_new(), and SKIPLIST_MAX_DEPTH.

Referenced by get_relocs(), and rz_flag_new().

◆ rz_skiplist_node_free()

static void rz_skiplist_node_free ( RzSkipList list,
RzSkipListNode node 
)
static

Definition at line 28 of file skiplist.c.

28  {
29  if (node) {
30  if (list->freefn && node->data) {
31  list->freefn(node->data);
32  }
33  free(node->forward);
34  free(node);
35  }
36 }
struct rz_skiplist_node_t ** forward
Definition: rz_skiplist.h:16

References rz_skiplist_node_t::data, rz_skiplist_node_t::forward, free(), and list().

Referenced by delete_element(), rz_skiplist_free(), and rz_skiplist_purge().

◆ rz_skiplist_node_new()

static RzSkipListNode* rz_skiplist_node_new ( void *  data,
int  level 
)
static

Definition at line 14 of file skiplist.c.

14  {
16  if (!res) {
17  return NULL;
18  }
19  res->forward = RZ_NEWS0(RzSkipListNode *, level + 1);
20  if (!res->forward) {
21  free(res);
22  return NULL;
23  }
24  res->data = data;
25  return res;
26 }
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
static int level
Definition: vmenus.c:2424

References rz_skiplist_node_t::data, rz_skiplist_node_t::forward, free(), level, NULL, RZ_NEW0, and RZ_NEWS0.

Referenced by rz_skiplist_insert(), and rz_skiplist_new().

◆ rz_skiplist_purge()

RZ_API void rz_skiplist_purge ( RzSkipList list)

Definition at line 128 of file skiplist.c.

128  {
129  RzSkipListNode *n;
130  if (!list) {
131  return;
132  }
133  n = list->head->forward[0];
134  while (n != list->head) {
135  RzSkipListNode *x = n;
136  n = n->forward[0];
138  }
139  init_head(list->head);
140  list->size = 0;
141  list->list_level = 0;
142 }

References init_head(), list(), n, rz_skiplist_node_free(), and x.

Referenced by rz_flag_unset_all(), rz_skiplist_free(), and rz_skiplist_join().

◆ rz_skiplist_to_list()

RZ_API RzList* rz_skiplist_to_list ( RzSkipList list)

Definition at line 292 of file skiplist.c.

292  {
293  RzList *res = rz_list_new();
294  RzSkipListNode *n;
295  void *data;
296 
297  rz_skiplist_foreach (list, n, data) {
298  rz_list_append(res, data);
299  }
300 
301  return res;
302 }
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288

References list(), n, rz_list_append(), rz_list_new(), and rz_skiplist_foreach.