1c0937300SAndre Przywara /*
2c0937300SAndre Przywara Red Black Trees
3c0937300SAndre Przywara (C) 1999 Andrea Arcangeli <andrea@suse.de>
4c0937300SAndre Przywara
5c0937300SAndre Przywara This program is free software; you can redistribute it and/or modify
6c0937300SAndre Przywara it under the terms of the GNU General Public License as published by
7c0937300SAndre Przywara the Free Software Foundation; either version 2 of the License, or
8c0937300SAndre Przywara (at your option) any later version.
9c0937300SAndre Przywara
10c0937300SAndre Przywara This program is distributed in the hope that it will be useful,
11c0937300SAndre Przywara but WITHOUT ANY WARRANTY; without even the implied warranty of
12c0937300SAndre Przywara MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13c0937300SAndre Przywara GNU General Public License for more details.
14c0937300SAndre Przywara
15c0937300SAndre Przywara You should have received a copy of the GNU General Public License
16c0937300SAndre Przywara along with this program; if not, write to the Free Software
17c0937300SAndre Przywara Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18c0937300SAndre Przywara
19c0937300SAndre Przywara linux/include/linux/rbtree.h
20c0937300SAndre Przywara
21c0937300SAndre Przywara To use rbtrees you'll have to implement your own insert and search cores.
22c0937300SAndre Przywara This will avoid us to use callbacks and to drop drammatically performances.
23c0937300SAndre Przywara I know it's not the cleaner way, but in C (not in C++) to get
24c0937300SAndre Przywara performances and genericity...
25c0937300SAndre Przywara
26c0937300SAndre Przywara See Documentation/rbtree.txt for documentation and samples.
27c0937300SAndre Przywara */
28c0937300SAndre Przywara
29c0937300SAndre Przywara #ifndef _LINUX_RBTREE_H
30c0937300SAndre Przywara #define _LINUX_RBTREE_H
31c0937300SAndre Przywara
32c0937300SAndre Przywara #include <linux/kernel.h>
33c0937300SAndre Przywara #include <linux/stddef.h>
34c0937300SAndre Przywara
35c0937300SAndre Przywara struct rb_node {
36c0937300SAndre Przywara unsigned long __rb_parent_color;
37c0937300SAndre Przywara struct rb_node *rb_right;
38c0937300SAndre Przywara struct rb_node *rb_left;
39c0937300SAndre Przywara } __attribute__((aligned(sizeof(long))));
40c0937300SAndre Przywara /* The alignment might seem pointless, but allegedly CRIS needs it */
41c0937300SAndre Przywara
42c0937300SAndre Przywara struct rb_root {
43c0937300SAndre Przywara struct rb_node *rb_node;
44c0937300SAndre Przywara };
45c0937300SAndre Przywara
46c0937300SAndre Przywara
47c0937300SAndre Przywara #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3))
48c0937300SAndre Przywara
49*15542babSAndre Przywara #define RB_ROOT { NULL, }
50c0937300SAndre Przywara #define rb_entry(ptr, type, member) container_of(ptr, type, member)
51c0937300SAndre Przywara
52c0937300SAndre Przywara #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
53c0937300SAndre Przywara
54c0937300SAndre Przywara /* 'empty' nodes are nodes that are known not to be inserted in an rbtree */
55c0937300SAndre Przywara #define RB_EMPTY_NODE(node) \
56c0937300SAndre Przywara ((node)->__rb_parent_color == (unsigned long)(node))
57c0937300SAndre Przywara #define RB_CLEAR_NODE(node) \
58c0937300SAndre Przywara ((node)->__rb_parent_color = (unsigned long)(node))
59c0937300SAndre Przywara
60c0937300SAndre Przywara
61c0937300SAndre Przywara extern void rb_insert_color(struct rb_node *, struct rb_root *);
62c0937300SAndre Przywara extern void rb_erase(struct rb_node *, struct rb_root *);
63c0937300SAndre Przywara
64c0937300SAndre Przywara
65c0937300SAndre Przywara /* Find logical next and previous nodes in a tree */
66c0937300SAndre Przywara extern struct rb_node *rb_next(const struct rb_node *);
67c0937300SAndre Przywara extern struct rb_node *rb_prev(const struct rb_node *);
68c0937300SAndre Przywara extern struct rb_node *rb_first(const struct rb_root *);
69c0937300SAndre Przywara extern struct rb_node *rb_last(const struct rb_root *);
70c0937300SAndre Przywara
71c0937300SAndre Przywara /* Postorder iteration - always visit the parent after its children */
72c0937300SAndre Przywara extern struct rb_node *rb_first_postorder(const struct rb_root *);
73c0937300SAndre Przywara extern struct rb_node *rb_next_postorder(const struct rb_node *);
74c0937300SAndre Przywara
75c0937300SAndre Przywara /* Fast replacement of a single node without remove/rebalance/add/rebalance */
76c0937300SAndre Przywara extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
77c0937300SAndre Przywara struct rb_root *root);
78c0937300SAndre Przywara
rb_link_node(struct rb_node * node,struct rb_node * parent,struct rb_node ** rb_link)79c0937300SAndre Przywara static inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
80c0937300SAndre Przywara struct rb_node ** rb_link)
81c0937300SAndre Przywara {
82c0937300SAndre Przywara node->__rb_parent_color = (unsigned long)parent;
83c0937300SAndre Przywara node->rb_left = node->rb_right = NULL;
84c0937300SAndre Przywara
85c0937300SAndre Przywara *rb_link = node;
86c0937300SAndre Przywara }
87c0937300SAndre Przywara
88c0937300SAndre Przywara #define rb_entry_safe(ptr, type, member) \
89c0937300SAndre Przywara ({ typeof(ptr) ____ptr = (ptr); \
90c0937300SAndre Przywara ____ptr ? rb_entry(____ptr, type, member) : NULL; \
91c0937300SAndre Przywara })
92c0937300SAndre Przywara
93c0937300SAndre Przywara /**
94c0937300SAndre Przywara * rbtree_postorder_for_each_entry_safe - iterate over rb_root in post order of
95c0937300SAndre Przywara * given type safe against removal of rb_node entry
96c0937300SAndre Przywara *
97c0937300SAndre Przywara * @pos: the 'type *' to use as a loop cursor.
98c0937300SAndre Przywara * @n: another 'type *' to use as temporary storage
99c0937300SAndre Przywara * @root: 'rb_root *' of the rbtree.
100c0937300SAndre Przywara * @field: the name of the rb_node field within 'type'.
101c0937300SAndre Przywara */
102c0937300SAndre Przywara #define rbtree_postorder_for_each_entry_safe(pos, n, root, field) \
103c0937300SAndre Przywara for (pos = rb_entry_safe(rb_first_postorder(root), typeof(*pos), field); \
104c0937300SAndre Przywara pos && ({ n = rb_entry_safe(rb_next_postorder(&pos->field), \
105c0937300SAndre Przywara typeof(*pos), field); 1; }); \
106c0937300SAndre Przywara pos = n)
107c0937300SAndre Przywara
108c0937300SAndre Przywara #endif /* _LINUX_RBTREE_H */
109