libubox
C utility functions for OpenWrt.
avl.h
Go to the documentation of this file.
1 /*
2  * PacketBB handler library (see RFC 5444)
3  * Copyright (c) 2010 Henning Rogge <hrogge@googlemail.com>
4  * Original OLSRd implementation by Hannes Gredler <hannes@gredler.at>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org/git for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  */
40 
41 #ifndef _AVL_H
42 #define _AVL_H
43 
44 #include <stddef.h>
45 #include <stdbool.h>
46 
47 #include "list.h"
48 
49 /* Support for OLSR.org linker symbol export */
50 #define EXPORT(sym) sym
51 
56 struct avl_node {
64  struct list_head list;
65 
69  struct avl_node *parent;
70 
74  struct avl_node *left;
75 
79  struct avl_node *right;
80 
84  const void *key;
85 
89  signed char balance;
90 
94  bool leader;
95 };
96 
104 typedef int (*avl_tree_comp) (const void *k1, const void *k2, void *ptr);
105 
110 struct avl_tree {
115  struct list_head list_head;
116 
120  struct avl_node *root;
121 
125  unsigned int count;
126 
132 
140 
144  void *cmp_ptr;
145 };
146 
154 };
155 
156 #define AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr) \
157  { \
158  .list_head = LIST_HEAD_INIT(_name.list_head), \
159  .comp = _comp, \
160  .allow_dups = _allow_dups, \
161  .cmp_ptr = _cmp_ptr \
162  }
163 
164 #define AVL_TREE(_name, _comp, _allow_dups, _cmp_ptr) \
165  struct avl_tree _name = \
166  AVL_TREE_INIT(_name, _comp, _allow_dups, _cmp_ptr)
167 
168 void EXPORT(avl_init)(struct avl_tree *, avl_tree_comp, bool, void *);
169 struct avl_node *EXPORT(avl_find)(const struct avl_tree *, const void *);
170 struct avl_node *EXPORT(avl_find_greaterequal)(const struct avl_tree *tree, const void *key);
171 struct avl_node *EXPORT(avl_find_lessequal)(const struct avl_tree *tree, const void *key);
172 int EXPORT(avl_insert)(struct avl_tree *, struct avl_node *);
173 void EXPORT(avl_delete)(struct avl_tree *, struct avl_node *);
174 
180 static inline bool
181 avl_is_first(struct avl_tree *tree, struct avl_node *node) {
182  return tree->list_head.next == &node->list;
183 }
184 
190 static inline bool
191 avl_is_last(struct avl_tree *tree, struct avl_node *node) {
192  return tree->list_head.prev == &node->list;
193 }
194 
199 static inline bool
200 avl_is_empty(struct avl_tree *tree) {
201  return tree->count == 0;
202 }
203 
212 static inline void *
213 __avl_find_element(const struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode) {
214  void *node = NULL;
215 
216  switch (mode) {
217  case AVL_FIND_EQUAL:
218  node = avl_find(tree, key);
219  break;
220  case AVL_FIND_LESSEQUAL:
221  node = avl_find_lessequal(tree, key);
222  break;
224  node = avl_find_greaterequal(tree, key);
225  break;
226  }
227  return node == NULL ? NULL : (((char *)node) - offset);
228 }
229 
240 #define avl_find_element(tree, key, element, node_element) \
241  ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_EQUAL))
242 
253 #define avl_find_le_element(tree, key, element, node_element) \
254  ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_LESSEQUAL))
255 
266 #define avl_find_ge_element(tree, key, element, node_element) \
267  ((__typeof__(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_GREATEREQUAL))
268 
280 #define avl_first_element(tree, element, node_member) \
281  container_of((tree)->list_head.next, __typeof__(*(element)), node_member.list)
282 
292 #define avl_last_element(tree, element, node_member) \
293  container_of((tree)->list_head.prev, __typeof__(*(element)), node_member.list)
294 
305 #define avl_next_element(element, node_member) \
306  container_of((&(element)->node_member.list)->next, __typeof__(*(element)), node_member.list)
307 
318 #define avl_prev_element(element, node_member) \
319  container_of((&(element)->node_member.list)->prev, __typeof__(*(element)), node_member.list)
320 
333 #define avl_for_element_range(first, last, element, node_member) \
334  for (element = (first); \
335  element->node_member.list.prev != &(last)->node_member.list; \
336  element = avl_next_element(element, node_member))
337 
350 #define avl_for_element_range_reverse(first, last, element, node_member) \
351  for (element = (last); \
352  element->node_member.list.next != &(first)->node_member.list; \
353  element = avl_prev_element(element, node_member))
354 
366 #define avl_for_each_element(tree, element, node_member) \
367  avl_for_element_range(avl_first_element(tree, element, node_member), \
368  avl_last_element(tree, element, node_member), \
369  element, node_member)
370 
382 #define avl_for_each_element_reverse(tree, element, node_member) \
383  avl_for_element_range_reverse(avl_first_element(tree, element, node_member), \
384  avl_last_element(tree, element, node_member), \
385  element, node_member)
386 
400 #define avl_for_element_to_last(tree, first, element, node_member) \
401  avl_for_element_range(first, avl_last_element(tree, element, node_member), element, node_member)
402 
403 
417 #define avl_for_element_to_last_reverse(tree, first, element, node_member) \
418  avl_for_element_range_reverse(first, avl_last_element(tree, element, node_member), element, node_member)
419 
433 #define avl_for_first_to_element(tree, last, element, node_member) \
434  avl_for_element_range(avl_first_element(tree, element, node_member), last, element, node_member)
435 
436 
450 #define avl_for_first_to_element_reverse(tree, last, element, node_member) \
451  avl_for_element_range_reverse(avl_first_element(tree, element, node_member), last, element, node_member)
452 
466 #define avl_for_element_range_safe(first_element, last_element, element, node_member, ptr) \
467  for (element = (first_element), ptr = avl_next_element(first_element, node_member); \
468  element->node_member.list.prev != &(last_element)->node_member.list; \
469  element = ptr, ptr = avl_next_element(ptr, node_member))
470 
484 #define avl_for_element_range_reverse_safe(first_element, last_element, element, node_member, ptr) \
485  for (element = (last_element), ptr = avl_prev_element(last_element, node_member); \
486  element->node_member.list.next != &(first_element)->node_member.list; \
487  element = ptr, ptr = avl_prev_element(ptr, node_member))
488 
503 #define avl_for_each_element_safe(tree, element, node_member, ptr) \
504  avl_for_element_range_safe(avl_first_element(tree, element, node_member), \
505  avl_last_element(tree, element, node_member), \
506  element, node_member, ptr)
507 
522 #define avl_for_each_element_reverse_safe(tree, element, node_member, ptr) \
523  avl_for_element_range_reverse_safe(avl_first_element(tree, element, node_member), \
524  avl_last_element(tree, element, node_member), \
525  element, node_member, ptr)
526 
545 #define avl_remove_all_elements(tree, element, node_member, ptr) \
546  for (element = avl_first_element(tree, element, node_member), \
547  ptr = avl_next_element(element, node_member), \
548  INIT_LIST_HEAD(&(tree)->list_head), \
549  (tree)->root = NULL; \
550  (tree)->count > 0; \
551  element = ptr, ptr = avl_next_element(ptr, node_member), (tree)->count--)
552 
553 #endif /* _AVL_H */
554 
555 /*
556  * Local Variables:
557  * c-basic-offset: 2
558  * indent-tabs-mode: nil
559  * End:
560  */
int avl_insert(struct avl_tree *, struct avl_node *)
Definition: avl.c:220
#define EXPORT(sym)
Definition: avl.h:50
avl_find_mode
Definition: avl.h:150
@ AVL_FIND_EQUAL
Definition: avl.h:151
@ AVL_FIND_LESSEQUAL
Definition: avl.h:152
@ AVL_FIND_GREATEREQUAL
Definition: avl.h:153
static bool avl_is_empty(struct avl_tree *tree)
Definition: avl.h:200
static bool avl_is_first(struct avl_tree *tree, struct avl_node *node)
Definition: avl.h:181
void avl_init(struct avl_tree *, avl_tree_comp, bool, void *)
Definition: avl.c:92
static bool avl_is_last(struct avl_tree *tree, struct avl_node *node)
Definition: avl.h:191
struct avl_node * avl_find_lessequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:137
int(* avl_tree_comp)(const void *k1, const void *k2, void *ptr)
Definition: avl.h:104
struct avl_node * avl_find(const struct avl_tree *, const void *)
Definition: avl.c:115
static void * __avl_find_element(const struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode)
Definition: avl.h:213
struct avl_node * avl_find_greaterequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:179
void avl_delete(struct avl_tree *, struct avl_node *)
Definition: avl.c:307
Definition: avl.h:56
struct avl_node * left
Definition: avl.h:74
signed char balance
Definition: avl.h:89
bool leader
Definition: avl.h:94
struct avl_node * right
Definition: avl.h:79
const void * key
Definition: avl.h:84
struct avl_node * parent
Definition: avl.h:69
struct list_head list
Definition: avl.h:64
Definition: avl.h:110
unsigned int count
Definition: avl.h:125
struct list_head list_head
Definition: avl.h:115
struct avl_node * root
Definition: avl.h:120
bool allow_dups
Definition: avl.h:131
void * cmp_ptr
Definition: avl.h:144
avl_tree_comp comp
Definition: avl.h:139
Definition: list.h:53
struct list_head * next
Definition: list.h:54
struct list_head * prev
Definition: list.h:55
Definition: test-avl.c:13