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