add a cmake file for the examples and add the binaries to .gitignore
[project/libubox.git] / avl.c
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 #include <stdbool.h>
42 #include <stddef.h>
43 #include <stdint.h>
44 #include <time.h>
45 #include <string.h>
46
47 #include "avl.h"
48 #include "list.h"
49
50 #define list_merge(_head, _list) list_merge(_list, _head)
51 #define list_is_last(_head, _list) list_is_last(_list, _head)
52 #define list_is_first(_head, _list) list_is_first(_list, _head)
53
54 /**
55  * internal type save inline function to calculate the maximum of
56  * to integers without macro implementation.
57  *
58  * @param x first parameter of maximum function
59  * @param y second parameter of maximum function
60  * @return largest integer of both parameters
61  */
62 static inline int avl_max(int x, int y) {
63   return x > y ? x : y;
64 }
65
66 /**
67  * internal type save inline function to calculate the minimum of
68  * to integers without macro implementation.
69  *
70  * @param x first parameter of minimum function
71  * @param y second parameter of minimum function
72  * @return smallest integer of both parameters
73  */
74 static inline int avl_min(int x, int y) {
75   return x < y ? x : y;
76 }
77
78 static struct avl_node *
79 avl_find_rec(struct avl_node *node, const void *key, avl_tree_comp comp, void *ptr, int *cmp_result);
80 static void avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node);
81 static void avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node);
82 static void post_insert(struct avl_tree *tree, struct avl_node *node);
83 static void avl_delete_worker(struct avl_tree *tree, struct avl_node *node);
84 static void avl_remove(struct avl_tree *tree, struct avl_node *node);
85
86 /**
87  * Initialize a new avl_tree struct
88  * @param tree pointer to avl-tree
89  * @param comp pointer to comparator for the tree
90  * @param allow_dups true if the tree allows multiple
91  *   elements with the same
92  * @param ptr custom parameter for comparator
93  */
94 void
95 avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
96 {
97   list_init_head(&tree->list_head);
98   tree->root = NULL;
99   tree->count = 0;
100   tree->comp = comp;
101   tree->allow_dups = allow_dups;
102   tree->cmp_ptr = ptr;
103 }
104
105 /**
106  * Finds a node in an avl-tree with a certain key
107  * @param tree pointer to avl-tree
108  * @param key pointer to key
109  * @return pointer to avl-node with key, NULL if no node with
110  *    this key exists.
111  */
112 struct avl_node *
113 avl_find(const struct avl_tree *tree, const void *key)
114 {
115   struct avl_node *node;
116   int diff;
117
118   if (tree->root == NULL)
119     return NULL;
120
121   node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
122
123   return diff == 0 ? node : NULL;
124 }
125
126 /**
127  * Finds the last node in an avl-tree with a key less or equal
128  * than the specified key
129  * @param tree pointer to avl-tree
130  * @param key pointer to specified key
131  * @return pointer to avl-node, NULL if no node with
132  *    key less or equal specified key exists.
133  */
134 struct avl_node *
135 avl_find_lessequal(const struct avl_tree *tree, const void *key) {
136   struct avl_node *node, *next;
137   int diff;
138
139   if (tree->root == NULL)
140     return NULL;
141
142   node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
143
144   /* go left as long as key<node.key */
145   while (diff < 0) {
146     if (list_is_first(&tree->list_head, &node->list)) {
147       return NULL;
148     }
149
150     node = (struct avl_node *)node->list.prev;
151     diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
152   }
153
154   /* go right as long as key>=next_node.key */
155   next = node;
156   while (diff >= 0) {
157     node = next;
158     if (list_is_last(&tree->list_head, &node->list)) {
159       break;
160     }
161
162     next = (struct avl_node *)node->list.next;
163     diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
164   }
165   return node;
166 }
167
168 /**
169  * Finds the first node in an avl-tree with a key greater or equal
170  * than the specified key
171  * @param tree pointer to avl-tree
172  * @param key pointer to specified key
173  * @return pointer to avl-node, NULL if no node with
174  *    key greater or equal specified key exists.
175  */
176 struct avl_node *
177 avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
178   struct avl_node *node, *next;
179   int diff;
180
181   if (tree->root == NULL)
182     return NULL;
183
184   node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
185
186   /* go right as long as key>node.key */
187   while (diff > 0) {
188     if (list_is_last(&tree->list_head, &node->list)) {
189       return NULL;
190     }
191
192     node = (struct avl_node *)node->list.next;
193     diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
194   }
195
196   /* go left as long as key<=next_node.key */
197   next = node;
198   while (diff <= 0) {
199     node = next;
200     if (list_is_first(&tree->list_head, &node->list)) {
201       break;
202     }
203
204     next = (struct avl_node *)node->list.prev;
205     diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
206   }
207   return node;
208 }
209
210 /**
211  * Inserts an avl_node into a tree
212  * @param tree pointer to tree
213  * @param new pointer to node
214  * @return 0 if node was inserted successfully, -1 if it was not inserted
215  *   because of a key collision
216  */
217 int
218 avl_insert(struct avl_tree *tree, struct avl_node *new)
219 {
220   struct avl_node *node, *next, *last;
221   int diff;
222
223   new->parent = NULL;
224
225   new->left = NULL;
226   new->right = NULL;
227
228   new->balance = 0;
229   new->leader = true;
230
231   if (tree->root == NULL) {
232     list_add_head(&tree->list_head, &new->list);
233     tree->root = new;
234     tree->count = 1;
235     return 0;
236   }
237
238   node = avl_find_rec(tree->root, new->key, tree->comp, tree->cmp_ptr, &diff);
239
240   last = node;
241
242   while (!list_is_last(&tree->list_head, &last->list)) {
243     next = list_next_element(last, list);
244     if (next->leader) {
245       break;
246     }
247     last = next;
248   }
249
250   diff = (*tree->comp) (new->key, node->key, tree->cmp_ptr);
251
252   if (diff == 0) {
253     if (!tree->allow_dups)
254       return -1;
255
256     new->leader = 0;
257
258     avl_insert_after(tree, last, new);
259     return 0;
260   }
261
262   if (node->balance == 1) {
263     avl_insert_before(tree, node, new);
264
265     node->balance = 0;
266     new->parent = node;
267     node->left = new;
268     return 0;
269   }
270
271   if (node->balance == -1) {
272     avl_insert_after(tree, last, new);
273
274     node->balance = 0;
275     new->parent = node;
276     node->right = new;
277     return 0;
278   }
279
280   if (diff < 0) {
281     avl_insert_before(tree, node, new);
282
283     node->balance = -1;
284     new->parent = node;
285     node->left = new;
286     post_insert(tree, node);
287     return 0;
288   }
289
290   avl_insert_after(tree, last, new);
291
292   node->balance = 1;
293   new->parent = node;
294   node->right = new;
295   post_insert(tree, node);
296   return 0;
297 }
298
299 /**
300  * Remove a node from an avl tree
301  * @param tree pointer to tree
302  * @param node pointer to node
303  */
304 void
305 avl_delete(struct avl_tree *tree, struct avl_node *node)
306 {
307   struct avl_node *next;
308   struct avl_node *parent;
309   struct avl_node *left;
310   struct avl_node *right;
311   if (node->leader) {
312     if (tree->allow_dups
313         && !list_is_last(&tree->list_head, &node->list)
314         && !(next = list_next_element(node, list))->leader) {
315       next->leader = true;
316       next->balance = node->balance;
317
318       parent = node->parent;
319       left = node->left;
320       right = node->right;
321
322       next->parent = parent;
323       next->left = left;
324       next->right = right;
325
326       if (parent == NULL)
327         tree->root = next;
328
329       else {
330         if (node == parent->left)
331           parent->left = next;
332
333         else
334           parent->right = next;
335       }
336
337       if (left != NULL)
338         left->parent = next;
339
340       if (right != NULL)
341         right->parent = next;
342     }
343
344     else
345       avl_delete_worker(tree, node);
346   }
347
348   avl_remove(tree, node);
349 }
350
351 static struct avl_node *
352 avl_find_rec(struct avl_node *node, const void *key, avl_tree_comp comp, void *cmp_ptr, int *cmp_result)
353 {
354   int diff;
355
356   diff = (*comp) (key, node->key, cmp_ptr);
357   *cmp_result = diff;
358
359   if (diff < 0) {
360     if (node->left != NULL)
361       return avl_find_rec(node->left, key, comp, cmp_ptr, cmp_result);
362
363     return node;
364   }
365
366   if (diff > 0) {
367     if (node->right != NULL)
368       return avl_find_rec(node->right, key, comp, cmp_ptr, cmp_result);
369
370     return node;
371   }
372
373   return node;
374 }
375
376 static void
377 avl_rotate_right(struct avl_tree *tree, struct avl_node *node)
378 {
379   struct avl_node *left, *parent;
380
381   left = node->left;
382   parent = node->parent;
383
384   left->parent = parent;
385   node->parent = left;
386
387   if (parent == NULL)
388     tree->root = left;
389
390   else {
391     if (parent->left == node)
392       parent->left = left;
393
394     else
395       parent->right = left;
396   }
397
398   node->left = left->right;
399   left->right = node;
400
401   if (node->left != NULL)
402     node->left->parent = node;
403
404   node->balance += 1 - avl_min(left->balance, 0);
405   left->balance += 1 + avl_max(node->balance, 0);
406 }
407
408 static void
409 avl_rotate_left(struct avl_tree *tree, struct avl_node *node)
410 {
411   struct avl_node *right, *parent;
412
413   right = node->right;
414   parent = node->parent;
415
416   right->parent = parent;
417   node->parent = right;
418
419   if (parent == NULL)
420     tree->root = right;
421
422   else {
423     if (parent->left == node)
424       parent->left = right;
425
426     else
427       parent->right = right;
428   }
429
430   node->right = right->left;
431   right->left = node;
432
433   if (node->right != NULL)
434     node->right->parent = node;
435
436   node->balance -= 1 + avl_max(right->balance, 0);
437   right->balance -= 1 - avl_min(node->balance, 0);
438 }
439
440 static void
441 post_insert(struct avl_tree *tree, struct avl_node *node)
442 {
443   struct avl_node *parent = node->parent;
444
445   if (parent == NULL)
446     return;
447
448   if (node == parent->left) {
449     parent->balance--;
450
451     if (parent->balance == 0)
452       return;
453
454     if (parent->balance == -1) {
455       post_insert(tree, parent);
456       return;
457     }
458
459     if (node->balance == -1) {
460       avl_rotate_right(tree, parent);
461       return;
462     }
463
464     avl_rotate_left(tree, node);
465     avl_rotate_right(tree, node->parent->parent);
466     return;
467   }
468
469   parent->balance++;
470
471   if (parent->balance == 0)
472     return;
473
474   if (parent->balance == 1) {
475     post_insert(tree, parent);
476     return;
477   }
478
479   if (node->balance == 1) {
480     avl_rotate_left(tree, parent);
481     return;
482   }
483
484   avl_rotate_right(tree, node);
485   avl_rotate_left(tree, node->parent->parent);
486 }
487
488 static void
489 avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
490 {
491   list_add_before(&pos_node->list, &node->list);
492   tree->count++;
493 }
494
495 static void
496 avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
497 {
498   list_add_after(&pos_node->list, &node->list);
499   tree->count++;
500 }
501
502 static void
503 avl_remove(struct avl_tree *tree, struct avl_node *node)
504 {
505   list_remove(&node->list);
506   tree->count--;
507 }
508
509 static void
510 avl_post_delete(struct avl_tree *tree, struct avl_node *node)
511 {
512   struct avl_node *parent;
513
514   if ((parent = node->parent) == NULL)
515     return;
516
517   if (node == parent->left) {
518     parent->balance++;
519
520     if (parent->balance == 0) {
521       avl_post_delete(tree, parent);
522       return;
523     }
524
525     if (parent->balance == 1)
526       return;
527
528     if (parent->right->balance == 0) {
529       avl_rotate_left(tree, parent);
530       return;
531     }
532
533     if (parent->right->balance == 1) {
534       avl_rotate_left(tree, parent);
535       avl_post_delete(tree, parent->parent);
536       return;
537     }
538
539     avl_rotate_right(tree, parent->right);
540     avl_rotate_left(tree, parent);
541     avl_post_delete(tree, parent->parent);
542     return;
543   }
544
545   parent->balance--;
546
547   if (parent->balance == 0) {
548     avl_post_delete(tree, parent);
549     return;
550   }
551
552   if (parent->balance == -1)
553     return;
554
555   if (parent->left->balance == 0) {
556     avl_rotate_right(tree, parent);
557     return;
558   }
559
560   if (parent->left->balance == -1) {
561     avl_rotate_right(tree, parent);
562     avl_post_delete(tree, parent->parent);
563     return;
564   }
565
566   avl_rotate_left(tree, parent->left);
567   avl_rotate_right(tree, parent);
568   avl_post_delete(tree, parent->parent);
569 }
570
571 static struct avl_node *
572 avl_local_min(struct avl_node *node)
573 {
574   while (node->left != NULL)
575     node = node->left;
576
577   return node;
578 }
579
580 #if 0
581 static struct avl_node *
582 avl_local_max(struct avl_node *node)
583 {
584   while (node->right != NULL)
585     node = node->right;
586
587   return node;
588 }
589 #endif
590
591 static void
592 avl_delete_worker(struct avl_tree *tree, struct avl_node *node)
593 {
594   struct avl_node *parent, *min;
595
596   parent = node->parent;
597
598   if (node->left == NULL && node->right == NULL) {
599     if (parent == NULL) {
600       tree->root = NULL;
601       return;
602     }
603
604     if (parent->left == node) {
605       parent->left = NULL;
606       parent->balance++;
607
608       if (parent->balance == 1)
609         return;
610
611       if (parent->balance == 0) {
612         avl_post_delete(tree, parent);
613         return;
614       }
615
616       if (parent->right->balance == 0) {
617         avl_rotate_left(tree, parent);
618         return;
619       }
620
621       if (parent->right->balance == 1) {
622         avl_rotate_left(tree, parent);
623         avl_post_delete(tree, parent->parent);
624         return;
625       }
626
627       avl_rotate_right(tree, parent->right);
628       avl_rotate_left(tree, parent);
629       avl_post_delete(tree, parent->parent);
630       return;
631     }
632
633     if (parent->right == node) {
634       parent->right = NULL;
635       parent->balance--;
636
637       if (parent->balance == -1)
638         return;
639
640       if (parent->balance == 0) {
641         avl_post_delete(tree, parent);
642         return;
643       }
644
645       if (parent->left->balance == 0) {
646         avl_rotate_right(tree, parent);
647         return;
648       }
649
650       if (parent->left->balance == -1) {
651         avl_rotate_right(tree, parent);
652         avl_post_delete(tree, parent->parent);
653         return;
654       }
655
656       avl_rotate_left(tree, parent->left);
657       avl_rotate_right(tree, parent);
658       avl_post_delete(tree, parent->parent);
659       return;
660     }
661   }
662
663   if (node->left == NULL) {
664     if (parent == NULL) {
665       tree->root = node->right;
666       node->right->parent = NULL;
667       return;
668     }
669
670     node->right->parent = parent;
671
672     if (parent->left == node)
673       parent->left = node->right;
674
675     else
676       parent->right = node->right;
677
678     avl_post_delete(tree, node->right);
679     return;
680   }
681
682   if (node->right == NULL) {
683     if (parent == NULL) {
684       tree->root = node->left;
685       node->left->parent = NULL;
686       return;
687     }
688
689     node->left->parent = parent;
690
691     if (parent->left == node)
692       parent->left = node->left;
693
694     else
695       parent->right = node->left;
696
697     avl_post_delete(tree, node->left);
698     return;
699   }
700
701   min = avl_local_min(node->right);
702   avl_delete_worker(tree, min);
703   parent = node->parent;
704
705   min->balance = node->balance;
706   min->parent = parent;
707   min->left = node->left;
708   min->right = node->right;
709
710   if (min->left != NULL)
711     min->left->parent = min;
712
713   if (min->right != NULL)
714     min->right->parent = min;
715
716   if (parent == NULL) {
717     tree->root = min;
718     return;
719   }
720
721   if (parent->left == node) {
722     parent->left = min;
723     return;
724   }
725
726   parent->right = min;
727 }
728
729 /*
730  * Local Variables:
731  * c-basic-offset: 2
732  * indent-tabs-mode: nil
733  * End:
734  */