libubox
C utility functions for OpenWrt.
avl.c
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 #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 
59 static inline int avl_max(int x, int y) {
60  return x > y ? x : y;
61 }
62 
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 
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 
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 
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 
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 
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 
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 *
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  */
struct avl_node * avl_find(const struct avl_tree *tree, const void *key)
Definition: avl.c:115
static int avl_min(int x, int y)
Definition: avl.c:71
static void post_insert(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:443
static struct avl_node * avl_find_rec(struct avl_node *node, const void *key, avl_tree_comp comp, void *ptr, int *cmp_result)
Definition: avl.c:354
static void avl_remove(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:505
static void avl_rotate_left(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:411
static struct avl_node * avl_next(struct avl_node *node)
Definition: avl.c:102
static struct avl_node * avl_local_min(struct avl_node *node)
Definition: avl.c:574
static int avl_max(int x, int y)
Definition: avl.c:59
struct avl_node * avl_find_lessequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:137
static void avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
Definition: avl.c:491
static void avl_rotate_right(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:379
int avl_insert(struct avl_tree *tree, struct avl_node *new)
Definition: avl.c:220
static void avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
Definition: avl.c:498
static void avl_post_delete(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:512
static void avl_delete_worker(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:594
struct avl_node * avl_find_greaterequal(const struct avl_tree *tree, const void *key)
Definition: avl.c:179
void avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
Definition: avl.c:92
void avl_delete(struct avl_tree *tree, struct avl_node *node)
Definition: avl.c:307
int(* avl_tree_comp)(const void *k1, const void *k2, void *ptr)
Definition: avl.h:104
static bool list_is_first(const struct list_head *list, const struct list_head *head)
Definition: list.h:75
static void list_add_tail(struct list_head *_new, struct list_head *head)
Definition: list.h:165
static void list_add(struct list_head *_new, struct list_head *head)
Definition: list.h:159
static void list_del(struct list_head *entry)
Definition: list.h:96
static bool list_is_last(const struct list_head *list, const struct list_head *head)
Definition: list.h:82
#define list_entry(ptr, type, field)
Definition: list.h:120
static void INIT_LIST_HEAD(struct list_head *list)
Definition: list.h:63
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: test-avl.c:13