list_compat.h: remove
[project/libubox.git] / avl.h
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
52 /**
53  * This element is a member of a avl-tree. It must be contained in all
54  * larger structs that should be put into a tree.
55  */
56 struct avl_node {
57   /**
58    * Linked list node for supporting easy iteration and multiple
59    * elments with the same key.
60    *
61    * this must be the first element of an avl_node to
62    * make casting for lists easier
63    */
64   struct list_head list;
65
66   /**
67    * Pointer to parent node in tree, NULL if root node
68    */
69   struct avl_node *parent;
70
71   /**
72    * Pointer to left child
73    */
74   struct avl_node *left;
75
76   /**
77    * Pointer to right child
78    */
79   struct avl_node *right;
80
81   /**
82    * pointer to key of node
83    */
84   const void *key;
85
86   /**
87    * balance state of AVL tree (0,-1,+1)
88    */
89   signed char balance;
90
91   /**
92    * true if first of a series of nodes with same key
93    */
94   bool leader;
95 };
96
97 /**
98  * Prototype for avl comparators
99  * @param k1 first key
100  * @param k2 second key
101  * @param ptr custom data for tree comparator
102  * @return +1 if k1>k2, -1 if k1<k2, 0 if k1==k2
103  */
104 typedef int (*avl_tree_comp) (const void *k1, const void *k2, void *ptr);
105
106 /**
107  * This struct is the central management part of an avl tree.
108  * One of them is necessary for each avl_tree.
109  */
110 struct avl_tree {
111   /**
112    * Head of linked list node for supporting easy iteration
113    * and multiple elments with the same key.
114    */
115   struct list_head list_head;
116
117   /**
118    * pointer to the root node of the avl tree, NULL if tree is empty
119    */
120   struct avl_node *root;
121
122   /**
123    * number of nodes in the avl tree
124    */
125   unsigned int count;
126
127   /**
128    * true if multiple nodes with the same key are
129    * allowed in the tree, false otherwise
130    */
131   bool allow_dups;
132
133   /**
134    * pointer to the tree comparator
135    *
136    * First two parameters are keys to compare,
137    * third parameter is a copy of cmp_ptr
138    */
139   avl_tree_comp comp;
140
141   /**
142    * custom pointer delivered to the tree comparator
143    */
144   void *cmp_ptr;
145 };
146
147 /**
148  * internal enum for avl_find_... macros
149  */
150 enum avl_find_mode {
151   AVL_FIND_EQUAL,
152   AVL_FIND_LESSEQUAL,
153   AVL_FIND_GREATEREQUAL
154 };
155
156 void EXPORT(avl_init)(struct avl_tree *, avl_tree_comp, bool, void *);
157 struct avl_node *EXPORT(avl_find)(const struct avl_tree *, const void *);
158 struct avl_node *EXPORT(avl_find_greaterequal)(const struct avl_tree *tree, const void *key);
159 struct avl_node *EXPORT(avl_find_lessequal)(const struct avl_tree *tree, const void *key);
160 int EXPORT(avl_insert)(struct avl_tree *, struct avl_node *);
161 void EXPORT(avl_delete)(struct avl_tree *, struct avl_node *);
162
163 /**
164  * @param tree pointer to avl-tree
165  * @param node pointer to node of the tree
166  * @return true if node is the first one of the tree, false otherwise
167  */
168 static inline bool
169 avl_is_first(struct avl_tree *tree, struct avl_node *node) {
170   return tree->list_head.next == &node->list;
171 }
172
173 /**
174  * @param tree pointer to avl-tree
175  * @param node pointer to node of the tree
176  * @return true if node is the last one of the tree, false otherwise
177  */
178 static inline bool
179 avl_is_last(struct avl_tree *tree, struct avl_node *node) {
180   return tree->list_head.prev == &node->list;
181 }
182
183 /**
184  * @param tree pointer to avl-tree
185  * @return true if the tree is empty, false otherwise
186  */
187 static inline bool
188 avl_is_empty(struct avl_tree *tree) {
189   return tree->count == 0;
190 }
191
192 /**
193  * Internal function to support returning the element from a avl tree query
194  * @param tree pointer to avl tree
195  * @param key pointer to key
196  * @param offset offset of node inside the embedded struct
197  * @param mode mode of lookup operation (less equal, equal or greater equal)
198  * @param pointer to elemen, NULL if no fitting one was found
199  */
200 static inline void *
201 __avl_find_element(const struct avl_tree *tree, const void *key, size_t offset, enum avl_find_mode mode) {
202   void *node = NULL;
203
204   switch (mode) {
205     case AVL_FIND_EQUAL:
206       node = avl_find(tree, key);
207       break;
208     case AVL_FIND_LESSEQUAL:
209       node = avl_find_lessequal(tree, key);
210       break;
211     case AVL_FIND_GREATEREQUAL:
212       node = avl_find_greaterequal(tree, key);
213       break;
214   }
215   return node == NULL ? NULL : (((char *)node) - offset);
216 }
217
218 /**
219  * @param tree pointer to avl-tree
220  * @param key pointer to key
221  * @param element pointer to a node element
222  *    (don't need to be initialized)
223  * @param node_element name of the avl_node element inside the
224  *    larger struct
225  * @return pointer to tree element with the specified key,
226  *    NULL if no element was found
227  */
228 #define avl_find_element(tree, key, element, node_element) \
229   ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_EQUAL))
230
231 /**
232  * @param tree pointer to avl-tree
233  * @param key pointer to specified key
234  * @param element pointer to a node element
235  *    (don't need to be initialized)
236  * @param node_element name of the avl_node element inside the
237  *    larger struct
238  * return pointer to last tree element with less or equal key than specified key,
239  *    NULL if no element was found
240  */
241 #define avl_find_le_element(tree, key, element, node_element) \
242   ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_LESSEQUAL))
243
244 /**
245  * @param tree pointer to avl-tree
246  * @param key pointer to specified key
247  * @param element pointer to a node element
248  *    (don't need to be initialized)
249  * @param node_element name of the avl_node element inside the
250  *    larger struct
251  * return pointer to first tree element with greater or equal key than specified key,
252  *    NULL if no element was found
253  */
254 #define avl_find_ge_element(tree, key, element, node_element) \
255   ((typeof(*(element)) *)__avl_find_element(tree, key, offsetof(typeof(*(element)), node_element), AVL_FIND_GREATEREQUAL))
256
257 /**
258  * This function must not be called for an empty tree
259  *
260  * @param tree pointer to avl-tree
261  * @param element pointer to a node element
262  *    (don't need to be initialized)
263  * @param node_member name of the avl_node element inside the
264  *    larger struct
265  * @return pointer to the first element of the avl_tree
266  *    (automatically converted to type 'element')
267  */
268 #define avl_first_element(tree, element, node_member) \
269   container_of((tree)->list_head.next, typeof(*(element)), node_member.list)
270
271 /**
272  * @param tree pointer to tree
273  * @param element pointer to a node struct that contains the avl_node
274  *    (don't need to be initialized)
275  * @param node_member name of the avl_node element inside the
276  *    larger struct
277  * @return pointer to the last element of the avl_tree
278  *    (automatically converted to type 'element')
279  */
280 #define avl_last_element(tree, element, node_member) \
281   container_of((tree)->list_head.prev, typeof(*(element)), node_member.list)
282
283 /**
284  * This function must not be called for the last element of
285  * an avl tree
286  *
287  * @param element pointer to a node of the tree
288  * @param node_member name of the avl_node element inside the
289  *    larger struct
290  * @return pointer to the node after 'element'
291  *    (automatically converted to type 'element')
292  */
293 #define avl_next_element(element, node_member) \
294   container_of((&(element)->node_member.list)->next, typeof(*(element)), node_member.list)
295
296 /**
297  * This function must not be called for the first element of
298  * an avl tree
299  *
300  * @param element pointer to a node of the tree
301  * @param node_member name of the avl_node element inside the
302  *    larger struct
303  * @return pointer to the node before 'element'
304  *    (automatically converted to type 'element')
305  */
306 #define avl_prev_element(element, node_member) \
307   container_of((&(element)->node_member.list)->prev, typeof(*(element)), node_member.list)
308
309 /**
310  * Loop over a block of elements of a tree, used similar to a for() command.
311  * This loop should not be used if elements are removed from the tree during
312  * the loop.
313  *
314  * @param first pointer to first element of loop
315  * @param last pointer to last element of loop
316  * @param element pointer to a node of the tree, this element will
317  *    contain the current node of the list during the loop
318  * @param node_member name of the avl_node element inside the
319  *    larger struct
320  */
321 #define avl_for_element_range(first, last, element, node_member) \
322   for (element = (first); \
323        element->node_member.list.prev != &(last)->node_member.list; \
324        element = avl_next_element(element, node_member))
325
326 /**
327  * Loop over a block of elements of a tree backwards, used similar to a for() command.
328  * This loop should not be used if elements are removed from the tree during
329  * the loop.
330  *
331  * @param first pointer to first element of loop
332  * @param last pointer to last element of loop
333  * @param element pointer to a node of the tree, this element will
334  *    contain the current node of the list during the loop
335  * @param node_member name of the avl_node element inside the
336  *    larger struct
337  */
338 #define avl_for_element_range_reverse(first, last, element, node_member) \
339   for (element = (last); \
340        element->node_member.list.next != &(first)->node_member.list; \
341        element = avl_prev_element(element, node_member))
342
343 /**
344  * Loop over all elements of an avl_tree, used similar to a for() command.
345  * This loop should not be used if elements are removed from the tree during
346  * the loop.
347  *
348  * @param tree pointer to avl-tree
349  * @param element pointer to a node of the tree, this element will
350  *    contain the current node of the tree during the loop
351  * @param node_member name of the avl_node element inside the
352  *    larger struct
353  */
354 #define avl_for_each_element(tree, element, node_member) \
355   avl_for_element_range(avl_first_element(tree, element, node_member), \
356                         avl_last_element(tree, element,  node_member), \
357                         element, node_member)
358
359 /**
360  * Loop over all elements of an avl_tree backwards, used similar to a for() command.
361  * This loop should not be used if elements are removed from the tree during
362  * the loop.
363  *
364  * @param tree pointer to avl-tree
365  * @param element pointer to a node of the tree, this element will
366  *    contain the current node of the tree during the loop
367  * @param node_member name of the avl_node element inside the
368  *    larger struct
369  */
370 #define avl_for_each_element_reverse(tree, element, node_member) \
371   avl_for_element_range_reverse(avl_first_element(tree, element, node_member), \
372                                 avl_last_element(tree, element,  node_member), \
373                                 element, node_member)
374
375 /**
376  * Loop over a block of elements of a tree, used similar to a for() command.
377  * This loop should not be used if elements are removed from the tree during
378  * the loop.
379  * The loop runs from the element 'first' to the end of the tree.
380  *
381  * @param tree pointer to avl-tree
382  * @param first pointer to first element of loop
383  * @param element pointer to a node of the tree, this element will
384  *    contain the current node of the list during the loop
385  * @param node_member name of the avl_node element inside the
386  *    larger struct
387  */
388 #define avl_for_element_to_last(tree, first, element, node_member) \
389   avl_for_element_range(first, avl_last_element(tree, element, node_member), element, node_member)
390
391
392 /**
393  * Loop over a block of elements of a tree backwards, used similar to a for() command.
394  * This loop should not be used if elements are removed from the tree during
395  * the loop.
396  * The loop runs from the element 'first' to the end of the tree.
397  *
398  * @param tree pointer to avl-tree
399  * @param first pointer to first element of loop
400  * @param element pointer to a node of the tree, this element will
401  *    contain the current node of the list during the loop
402  * @param node_member name of the avl_node element inside the
403  *    larger struct
404  */
405 #define avl_for_element_to_last_reverse(tree, first, element, node_member) \
406   avl_for_element_range_reverse(first, avl_last_element(tree, element, node_member), element, node_member)
407
408 /**
409  * Loop over a block of elements of a tree, used similar to a for() command.
410  * This loop should not be used if elements are removed from the tree during
411  * the loop.
412  * The loop runs from the start of the tree to the element 'last'.
413  *
414  * @param tree pointer to avl-tree
415  * @param last pointer to last element of loop
416  * @param element pointer to a node of the tree, this element will
417  *    contain the current node of the list during the loop
418  * @param node_member name of the avl_node element inside the
419  *    larger struct
420  */
421 #define avl_for_first_to_element(tree, last, element, node_member) \
422   avl_for_element_range(avl_first_element(tree, element, node_member), last, element, node_member)
423
424
425 /**
426  * Loop over a block of elements of a tree backwards, used similar to a for() command.
427  * This loop should not be used if elements are removed from the tree during
428  * the loop.
429  * The loop runs from the start of the tree to the element 'last'.
430  *
431  * @param tree pointer to avl-tree
432  * @param last pointer to last element of loop
433  * @param element pointer to a node of the tree, this element will
434  *    contain the current node of the list during the loop
435  * @param node_member name of the avl_node element inside the
436  *    larger struct
437  */
438 #define avl_for_first_to_element_reverse(tree, last, element, node_member) \
439   avl_for_element_range_reverse(avl_first_element(tree, element, node_member), last, element, node_member)
440
441 /**
442  * Loop over a block of nodes of a tree, used similar to a for() command.
443  * This loop can be used if the current element might be removed from
444  * the tree during the loop. Other elements should not be removed during
445  * the loop.
446  *
447  * @param first_element first element of loop
448  * @param last_element last element of loop
449  * @param element iterator pointer to tree element struct
450  * @param node_member name of avl_node within tree element struct
451  * @param ptr pointer to tree element struct which is used to store
452  *    the next node during the loop
453  */
454 #define avl_for_element_range_safe(first_element, last_element, element, node_member, ptr) \
455   for (element = (first_element), ptr = avl_next_element(first_element, node_member); \
456        element->node_member.list.prev != &(last_element)->node_member.list; \
457        element = ptr, ptr = avl_next_element(ptr, node_member))
458
459 /**
460  * Loop over a block of elements of a tree backwards, used similar to a for() command.
461  * This loop can be used if the current element might be removed from
462  * the tree during the loop. Other elements should not be removed during
463  * the loop.
464  *
465  * @param first_element first element of range (will be last returned by the loop)
466  * @param last_element last element of range (will be first returned by the loop)
467  * @param element iterator pointer to node element struct
468  * @param node_member name of avl_node within node element struct
469  * @param ptr pointer to node element struct which is used to store
470  *    the previous node during the loop
471  */
472 #define avl_for_element_range_reverse_safe(first_element, last_element, element, node_member, ptr) \
473   for (element = (last_element), ptr = avl_prev_element(last_element, node_member); \
474        element->node_member.list.next != &(first_element)->node_member.list; \
475        element = ptr, ptr = avl_prev_element(ptr, node_member))
476
477 /**
478  * Loop over all elements of an avl_tree, used similar to a for() command.
479  * This loop can be used if the current element might be removed from
480  * the tree during the loop. Other elements should not be removed during
481  * the loop.
482  *
483  * @param tree pointer to avl-tree
484  * @param element pointer to a node of the tree, this element will
485  *    contain the current node of the tree during the loop
486  * @param node_member name of the avl_node element inside the
487  *    larger struct
488  * @param ptr pointer to a tree element which is used to store
489  *    the next node during the loop
490  */
491 #define avl_for_each_element_safe(tree, element, node_member, ptr) \
492   avl_for_element_range_safe(avl_first_element(tree, element, node_member), \
493                              avl_last_element(tree, element, node_member), \
494                              element, node_member, ptr)
495
496 /**
497  * Loop over all elements of an avl_tree backwards, used similar to a for() command.
498  * This loop can be used if the current element might be removed from
499  * the tree during the loop. Other elements should not be removed during
500  * the loop.
501  *
502  * @param tree pointer to avl-tree
503  * @param element pointer to a node of the tree, this element will
504  *    contain the current node of the tree during the loop
505  * @param node_member name of the avl_node element inside the
506  *    larger struct
507  * @param ptr pointer to a tree element which is used to store
508  *    the next node during the loop
509  */
510 #define avl_for_each_element_reverse_safe(tree, element, node_member, ptr) \
511   avl_for_element_range_reverse_safe(avl_first_element(tree, element, node_member), \
512                                      avl_last_element(tree, element, node_member), \
513                                      element, node_member, ptr)
514
515 /**
516  * A special loop that removes all elements of the tree and cleans up the tree
517  * root. The loop body is responsible to free the node elements of the tree.
518  *
519  * This loop is much faster than a normal one for clearing the tree because it
520  * does not rebalance the tree after each removal. Do NOT use a break command
521  * inside.
522  * You can free the memory of the elements within the loop.
523  * Do NOT call avl_delete() on the elements within the loop,
524  *
525  * @param tree pointer to avl-tree
526  * @param element pointer to a node of the tree, this element will
527  *    contain the current node of the tree during the loop
528  * @param node_member name of the avl_node element inside the
529  *    larger struct
530  * @param ptr pointer to a tree element which is used to store
531  *    the next node during the loop
532  */
533 #define avl_remove_all_elements(tree, element, node_member, ptr) \
534   for (element = avl_first_element(tree, element, node_member), \
535        ptr = avl_next_element(element, node_member), \
536        INIT_LIST_HEAD(&(tree)->list_head), \
537        (tree)->root = NULL; \
538        (tree)->count > 0; \
539        element = ptr, ptr = avl_next_element(ptr, node_member), (tree)->count--)
540
541 #endif /* _AVL_H */
542
543 /*
544  * Local Variables:
545  * c-basic-offset: 2
546  * indent-tabs-mode: nil
547  * End:
548  */