diff options
Diffstat (limited to 'include/linux/rbtree.h')
-rw-r--r-- | include/linux/rbtree.h | 119 |
1 files changed, 13 insertions, 106 deletions
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index 033b507b33b1..0022c1bb1e26 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h | |||
@@ -23,72 +23,7 @@ | |||
23 | I know it's not the cleaner way, but in C (not in C++) to get | 23 | I know it's not the cleaner way, but in C (not in C++) to get |
24 | performances and genericity... | 24 | performances and genericity... |
25 | 25 | ||
26 | Some example of insert and search follows here. The search is a plain | 26 | See Documentation/rbtree.txt for documentation and samples. |
27 | normal search over an ordered tree. The insert instead must be implemented | ||
28 | in two steps: First, the code must insert the element in order as a red leaf | ||
29 | in the tree, and then the support library function rb_insert_color() must | ||
30 | be called. Such function will do the not trivial work to rebalance the | ||
31 | rbtree, if necessary. | ||
32 | |||
33 | ----------------------------------------------------------------------- | ||
34 | static inline struct page * rb_search_page_cache(struct inode * inode, | ||
35 | unsigned long offset) | ||
36 | { | ||
37 | struct rb_node * n = inode->i_rb_page_cache.rb_node; | ||
38 | struct page * page; | ||
39 | |||
40 | while (n) | ||
41 | { | ||
42 | page = rb_entry(n, struct page, rb_page_cache); | ||
43 | |||
44 | if (offset < page->offset) | ||
45 | n = n->rb_left; | ||
46 | else if (offset > page->offset) | ||
47 | n = n->rb_right; | ||
48 | else | ||
49 | return page; | ||
50 | } | ||
51 | return NULL; | ||
52 | } | ||
53 | |||
54 | static inline struct page * __rb_insert_page_cache(struct inode * inode, | ||
55 | unsigned long offset, | ||
56 | struct rb_node * node) | ||
57 | { | ||
58 | struct rb_node ** p = &inode->i_rb_page_cache.rb_node; | ||
59 | struct rb_node * parent = NULL; | ||
60 | struct page * page; | ||
61 | |||
62 | while (*p) | ||
63 | { | ||
64 | parent = *p; | ||
65 | page = rb_entry(parent, struct page, rb_page_cache); | ||
66 | |||
67 | if (offset < page->offset) | ||
68 | p = &(*p)->rb_left; | ||
69 | else if (offset > page->offset) | ||
70 | p = &(*p)->rb_right; | ||
71 | else | ||
72 | return page; | ||
73 | } | ||
74 | |||
75 | rb_link_node(node, parent, p); | ||
76 | |||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | static inline struct page * rb_insert_page_cache(struct inode * inode, | ||
81 | unsigned long offset, | ||
82 | struct rb_node * node) | ||
83 | { | ||
84 | struct page * ret; | ||
85 | if ((ret = __rb_insert_page_cache(inode, offset, node))) | ||
86 | goto out; | ||
87 | rb_insert_color(node, &inode->i_rb_page_cache); | ||
88 | out: | ||
89 | return ret; | ||
90 | } | ||
91 | ----------------------------------------------------------------------- | ||
92 | */ | 27 | */ |
93 | 28 | ||
94 | #ifndef _LINUX_RBTREE_H | 29 | #ifndef _LINUX_RBTREE_H |
@@ -97,63 +32,35 @@ static inline struct page * rb_insert_page_cache(struct inode * inode, | |||
97 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
98 | #include <linux/stddef.h> | 33 | #include <linux/stddef.h> |
99 | 34 | ||
100 | struct rb_node | 35 | struct rb_node { |
101 | { | 36 | unsigned long __rb_parent_color; |
102 | unsigned long rb_parent_color; | ||
103 | #define RB_RED 0 | ||
104 | #define RB_BLACK 1 | ||
105 | struct rb_node *rb_right; | 37 | struct rb_node *rb_right; |
106 | struct rb_node *rb_left; | 38 | struct rb_node *rb_left; |
107 | } __attribute__((aligned(sizeof(long)))); | 39 | } __attribute__((aligned(sizeof(long)))); |
108 | /* The alignment might seem pointless, but allegedly CRIS needs it */ | 40 | /* The alignment might seem pointless, but allegedly CRIS needs it */ |
109 | 41 | ||
110 | struct rb_root | 42 | struct rb_root { |
111 | { | ||
112 | struct rb_node *rb_node; | 43 | struct rb_node *rb_node; |
113 | }; | 44 | }; |
114 | 45 | ||
115 | 46 | ||
116 | #define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) | 47 | #define rb_parent(r) ((struct rb_node *)((r)->__rb_parent_color & ~3)) |
117 | #define rb_color(r) ((r)->rb_parent_color & 1) | ||
118 | #define rb_is_red(r) (!rb_color(r)) | ||
119 | #define rb_is_black(r) rb_color(r) | ||
120 | #define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) | ||
121 | #define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) | ||
122 | |||
123 | static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) | ||
124 | { | ||
125 | rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; | ||
126 | } | ||
127 | static inline void rb_set_color(struct rb_node *rb, int color) | ||
128 | { | ||
129 | rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; | ||
130 | } | ||
131 | 48 | ||
132 | #define RB_ROOT (struct rb_root) { NULL, } | 49 | #define RB_ROOT (struct rb_root) { NULL, } |
133 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) | 50 | #define rb_entry(ptr, type, member) container_of(ptr, type, member) |
134 | 51 | ||
135 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) | 52 | #define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) |
136 | #define RB_EMPTY_NODE(node) (rb_parent(node) == node) | 53 | |
137 | #define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) | 54 | /* 'empty' nodes are nodes that are known not to be inserted in an rbree */ |
55 | #define RB_EMPTY_NODE(node) \ | ||
56 | ((node)->__rb_parent_color == (unsigned long)(node)) | ||
57 | #define RB_CLEAR_NODE(node) \ | ||
58 | ((node)->__rb_parent_color = (unsigned long)(node)) | ||
138 | 59 | ||
139 | static inline void rb_init_node(struct rb_node *rb) | ||
140 | { | ||
141 | rb->rb_parent_color = 0; | ||
142 | rb->rb_right = NULL; | ||
143 | rb->rb_left = NULL; | ||
144 | RB_CLEAR_NODE(rb); | ||
145 | } | ||
146 | 60 | ||
147 | extern void rb_insert_color(struct rb_node *, struct rb_root *); | 61 | extern void rb_insert_color(struct rb_node *, struct rb_root *); |
148 | extern void rb_erase(struct rb_node *, struct rb_root *); | 62 | extern void rb_erase(struct rb_node *, struct rb_root *); |
149 | 63 | ||
150 | typedef void (*rb_augment_f)(struct rb_node *node, void *data); | ||
151 | |||
152 | extern void rb_augment_insert(struct rb_node *node, | ||
153 | rb_augment_f func, void *data); | ||
154 | extern struct rb_node *rb_augment_erase_begin(struct rb_node *node); | ||
155 | extern void rb_augment_erase_end(struct rb_node *node, | ||
156 | rb_augment_f func, void *data); | ||
157 | 64 | ||
158 | /* Find logical next and previous nodes in a tree */ | 65 | /* Find logical next and previous nodes in a tree */ |
159 | extern struct rb_node *rb_next(const struct rb_node *); | 66 | extern struct rb_node *rb_next(const struct rb_node *); |
@@ -168,7 +75,7 @@ extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, | |||
168 | static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, | 75 | static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, |
169 | struct rb_node ** rb_link) | 76 | struct rb_node ** rb_link) |
170 | { | 77 | { |
171 | node->rb_parent_color = (unsigned long )parent; | 78 | node->__rb_parent_color = (unsigned long)parent; |
172 | node->rb_left = node->rb_right = NULL; | 79 | node->rb_left = node->rb_right = NULL; |
173 | 80 | ||
174 | *rb_link = node; | 81 | *rb_link = node; |