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>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 * Visit http://www.olsr.org/git for more information.
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.
52 * internal type save inline function to calculate the maximum of
53 * to integers without macro implementation.
55 * @param x first parameter of maximum function
56 * @param y second parameter of maximum function
57 * @return largest integer of both parameters
59 static inline int avl_max(int x, int y) {
64 * internal type save inline function to calculate the minimum of
65 * to integers without macro implementation.
67 * @param x first parameter of minimum function
68 * @param y second parameter of minimum function
69 * @return smallest integer of both parameters
71 static inline int avl_min(int x, int y) {
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);
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
92 avl_init(struct avl_tree *tree, avl_tree_comp comp, bool allow_dups, void *ptr)
94 INIT_LIST_HEAD(&tree->list_head);
98 tree->allow_dups = allow_dups;
102 static inline struct avl_node *avl_next(struct avl_node *node)
104 return list_entry(node->list.next, struct avl_node, list);
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
115 avl_find(const struct avl_tree *tree, const void *key)
117 struct avl_node *node;
120 if (tree->root == NULL)
123 node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
125 return diff == 0 ? node : NULL;
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.
137 avl_find_lessequal(const struct avl_tree *tree, const void *key) {
138 struct avl_node *node, *next;
141 if (tree->root == NULL)
144 node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
146 /* go left as long as key<node.key */
148 if (list_is_first(&node->list, &tree->list_head)) {
152 node = (struct avl_node *)node->list.prev;
153 diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
156 /* go right as long as key>=next_node.key */
160 if (list_is_last(&node->list, &tree->list_head)) {
164 next = (struct avl_node *)node->list.next;
165 diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
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.
179 avl_find_greaterequal(const struct avl_tree *tree, const void *key) {
180 struct avl_node *node, *next;
183 if (tree->root == NULL)
186 node = avl_find_rec(tree->root, key, tree->comp, tree->cmp_ptr, &diff);
188 /* go right as long as key>node.key */
190 if (list_is_last(&node->list, &tree->list_head)) {
194 node = (struct avl_node *)node->list.next;
195 diff = (*tree->comp) (key, node->key, tree->cmp_ptr);
198 /* go left as long as key<=next_node.key */
202 if (list_is_first(&node->list, &tree->list_head)) {
206 next = (struct avl_node *)node->list.prev;
207 diff = (*tree->comp) (key, next->key, tree->cmp_ptr);
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
220 avl_insert(struct avl_tree *tree, struct avl_node *new)
222 struct avl_node *node, *next, *last;
233 if (tree->root == NULL) {
234 list_add(&new->list, &tree->list_head);
240 node = avl_find_rec(tree->root, new->key, tree->comp, tree->cmp_ptr, &diff);
244 while (!list_is_last(&last->list, &tree->list_head)) {
245 next = avl_next(last);
252 diff = (*tree->comp) (new->key, node->key, tree->cmp_ptr);
255 if (!tree->allow_dups)
260 avl_insert_after(tree, last, new);
264 if (node->balance == 1) {
265 avl_insert_before(tree, node, new);
273 if (node->balance == -1) {
274 avl_insert_after(tree, last, new);
283 avl_insert_before(tree, node, new);
288 post_insert(tree, node);
292 avl_insert_after(tree, last, new);
297 post_insert(tree, node);
302 * Remove a node from an avl tree
303 * @param tree pointer to tree
304 * @param node pointer to node
307 avl_delete(struct avl_tree *tree, struct avl_node *node)
309 struct avl_node *next;
310 struct avl_node *parent;
311 struct avl_node *left;
312 struct avl_node *right;
315 && !list_is_last(&node->list, &tree->list_head)
316 && !(next = avl_next(node))->leader) {
318 next->balance = node->balance;
320 parent = node->parent;
324 next->parent = parent;
332 if (node == parent->left)
336 parent->right = next;
343 right->parent = next;
347 avl_delete_worker(tree, node);
350 avl_remove(tree, node);
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)
358 diff = (*comp) (key, node->key, cmp_ptr);
362 if (node->left != NULL)
363 return avl_find_rec(node->left, key, comp, cmp_ptr, cmp_result);
369 if (node->right != NULL)
370 return avl_find_rec(node->right, key, comp, cmp_ptr, cmp_result);
379 avl_rotate_right(struct avl_tree *tree, struct avl_node *node)
381 struct avl_node *left, *parent;
384 parent = node->parent;
386 left->parent = parent;
393 if (parent->left == node)
397 parent->right = left;
400 node->left = left->right;
403 if (node->left != NULL)
404 node->left->parent = node;
406 node->balance += 1 - avl_min(left->balance, 0);
407 left->balance += 1 + avl_max(node->balance, 0);
411 avl_rotate_left(struct avl_tree *tree, struct avl_node *node)
413 struct avl_node *right, *parent;
416 parent = node->parent;
418 right->parent = parent;
419 node->parent = right;
425 if (parent->left == node)
426 parent->left = right;
429 parent->right = right;
432 node->right = right->left;
435 if (node->right != NULL)
436 node->right->parent = node;
438 node->balance -= 1 + avl_max(right->balance, 0);
439 right->balance -= 1 - avl_min(node->balance, 0);
443 post_insert(struct avl_tree *tree, struct avl_node *node)
445 struct avl_node *parent = node->parent;
450 if (node == parent->left) {
453 if (parent->balance == 0)
456 if (parent->balance == -1) {
457 post_insert(tree, parent);
461 if (node->balance == -1) {
462 avl_rotate_right(tree, parent);
466 avl_rotate_left(tree, node);
467 avl_rotate_right(tree, node->parent->parent);
473 if (parent->balance == 0)
476 if (parent->balance == 1) {
477 post_insert(tree, parent);
481 if (node->balance == 1) {
482 avl_rotate_left(tree, parent);
486 avl_rotate_right(tree, node);
487 avl_rotate_left(tree, node->parent->parent);
491 avl_insert_before(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
493 list_add_tail(&node->list, &pos_node->list);
498 avl_insert_after(struct avl_tree *tree, struct avl_node *pos_node, struct avl_node *node)
500 list_add(&node->list, &pos_node->list);
505 avl_remove(struct avl_tree *tree, struct avl_node *node)
507 list_del(&node->list);
512 avl_post_delete(struct avl_tree *tree, struct avl_node *node)
514 struct avl_node *parent;
516 if ((parent = node->parent) == NULL)
519 if (node == parent->left) {
522 if (parent->balance == 0) {
523 avl_post_delete(tree, parent);
527 if (parent->balance == 1)
530 if (parent->right->balance == 0) {
531 avl_rotate_left(tree, parent);
535 if (parent->right->balance == 1) {
536 avl_rotate_left(tree, parent);
537 avl_post_delete(tree, parent->parent);
541 avl_rotate_right(tree, parent->right);
542 avl_rotate_left(tree, parent);
543 avl_post_delete(tree, parent->parent);
549 if (parent->balance == 0) {
550 avl_post_delete(tree, parent);
554 if (parent->balance == -1)
557 if (parent->left->balance == 0) {
558 avl_rotate_right(tree, parent);
562 if (parent->left->balance == -1) {
563 avl_rotate_right(tree, parent);
564 avl_post_delete(tree, parent->parent);
568 avl_rotate_left(tree, parent->left);
569 avl_rotate_right(tree, parent);
570 avl_post_delete(tree, parent->parent);
573 static struct avl_node *
574 avl_local_min(struct avl_node *node)
576 while (node->left != NULL)
583 static struct avl_node *
584 avl_local_max(struct avl_node *node)
586 while (node->right != NULL)
594 avl_delete_worker(struct avl_tree *tree, struct avl_node *node)
596 struct avl_node *parent, *min;
598 parent = node->parent;
600 if (node->left == NULL && node->right == NULL) {
601 if (parent == NULL) {
606 if (parent->left == node) {
610 if (parent->balance == 1)
613 if (parent->balance == 0) {
614 avl_post_delete(tree, parent);
618 if (parent->right->balance == 0) {
619 avl_rotate_left(tree, parent);
623 if (parent->right->balance == 1) {
624 avl_rotate_left(tree, parent);
625 avl_post_delete(tree, parent->parent);
629 avl_rotate_right(tree, parent->right);
630 avl_rotate_left(tree, parent);
631 avl_post_delete(tree, parent->parent);
635 if (parent->right == node) {
636 parent->right = NULL;
639 if (parent->balance == -1)
642 if (parent->balance == 0) {
643 avl_post_delete(tree, parent);
647 if (parent->left->balance == 0) {
648 avl_rotate_right(tree, parent);
652 if (parent->left->balance == -1) {
653 avl_rotate_right(tree, parent);
654 avl_post_delete(tree, parent->parent);
658 avl_rotate_left(tree, parent->left);
659 avl_rotate_right(tree, parent);
660 avl_post_delete(tree, parent->parent);
665 if (node->left == NULL) {
666 if (parent == NULL) {
667 tree->root = node->right;
668 node->right->parent = NULL;
673 node->right->parent = parent;
675 if (parent->left == node)
676 parent->left = node->right;
679 parent->right = node->right;
681 avl_post_delete(tree, node->right);
685 if (node->right == NULL) {
686 if (parent == NULL) {
687 tree->root = node->left;
688 node->left->parent = NULL;
692 node->left->parent = parent;
694 if (parent->left == node)
695 parent->left = node->left;
698 parent->right = node->left;
700 avl_post_delete(tree, node->left);
704 min = avl_local_min(node->right);
705 avl_delete_worker(tree, min);
706 parent = node->parent;
708 min->balance = node->balance;
709 min->parent = parent;
710 min->left = node->left;
711 min->right = node->right;
713 if (min->left != NULL)
714 min->left->parent = min;
716 if (min->right != NULL)
717 min->right->parent = min;
719 if (parent == NULL) {
724 if (parent->left == node) {
735 * indent-tabs-mode: nil