1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/rbtree.h>
23#include <linux/module.h>
24
25static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
26{
27 rb_node_t * right = node->rb_right;
28
29 if ((node->rb_right = right->rb_left))
30 right->rb_left->rb_parent = node;
31 right->rb_left = node;
32
33 if ((right->rb_parent = node->rb_parent))
34 {
35 if (node == node->rb_parent->rb_left)
36 node->rb_parent->rb_left = right;
37 else
38 node->rb_parent->rb_right = right;
39 }
40 else
41 root->rb_node = right;
42 node->rb_parent = right;
43}
44
45static void __rb_rotate_right(rb_node_t * node, rb_root_t * root)
46{
47 rb_node_t * left = node->rb_left;
48
49 if ((node->rb_left = left->rb_right))
50 left->rb_right->rb_parent = node;
51 left->rb_right = node;
52
53 if ((left->rb_parent = node->rb_parent))
54 {
55 if (node == node->rb_parent->rb_right)
56 node->rb_parent->rb_right = left;
57 else
58 node->rb_parent->rb_left = left;
59 }
60 else
61 root->rb_node = left;
62 node->rb_parent = left;
63}
64
65void rb_insert_color(rb_node_t * node, rb_root_t * root)
66{
67 rb_node_t * parent, * gparent;
68
69 while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
70 {
71 gparent = parent->rb_parent;
72
73 if (parent == gparent->rb_left)
74 {
75 {
76 register rb_node_t * uncle = gparent->rb_right;
77 if (uncle && uncle->rb_color == RB_RED)
78 {
79 uncle->rb_color = RB_BLACK;
80 parent->rb_color = RB_BLACK;
81 gparent->rb_color = RB_RED;
82 node = gparent;
83 continue;
84 }
85 }
86
87 if (parent->rb_right == node)
88 {
89 register rb_node_t * tmp;
90 __rb_rotate_left(parent, root);
91 tmp = parent;
92 parent = node;
93 node = tmp;
94 }
95
96 parent->rb_color = RB_BLACK;
97 gparent->rb_color = RB_RED;
98 __rb_rotate_right(gparent, root);
99 } else {
100 {
101 register rb_node_t * uncle = gparent->rb_left;
102 if (uncle && uncle->rb_color == RB_RED)
103 {
104 uncle->rb_color = RB_BLACK;
105 parent->rb_color = RB_BLACK;
106 gparent->rb_color = RB_RED;
107 node = gparent;
108 continue;
109 }
110 }
111
112 if (parent->rb_left == node)
113 {
114 register rb_node_t * tmp;
115 __rb_rotate_right(parent, root);
116 tmp = parent;
117 parent = node;
118 node = tmp;
119 }
120
121 parent->rb_color = RB_BLACK;
122 gparent->rb_color = RB_RED;
123 __rb_rotate_left(gparent, root);
124 }
125 }
126
127 root->rb_node->rb_color = RB_BLACK;
128}
129EXPORT_SYMBOL(rb_insert_color);
130
131static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
132 rb_root_t * root)
133{
134 rb_node_t * other;
135
136 while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
137 {
138 if (parent->rb_left == node)
139 {
140 other = parent->rb_right;
141 if (other->rb_color == RB_RED)
142 {
143 other->rb_color = RB_BLACK;
144 parent->rb_color = RB_RED;
145 __rb_rotate_left(parent, root);
146 other = parent->rb_right;
147 }
148 if ((!other->rb_left ||
149 other->rb_left->rb_color == RB_BLACK)
150 && (!other->rb_right ||
151 other->rb_right->rb_color == RB_BLACK))
152 {
153 other->rb_color = RB_RED;
154 node = parent;
155 parent = node->rb_parent;
156 }
157 else
158 {
159 if (!other->rb_right ||
160 other->rb_right->rb_color == RB_BLACK)
161 {
162 register rb_node_t * o_left;
163 if ((o_left = other->rb_left))
164 o_left->rb_color = RB_BLACK;
165 other->rb_color = RB_RED;
166 __rb_rotate_right(other, root);
167 other = parent->rb_right;
168 }
169 other->rb_color = parent->rb_color;
170 parent->rb_color = RB_BLACK;
171 if (other->rb_right)
172 other->rb_right->rb_color = RB_BLACK;
173 __rb_rotate_left(parent, root);
174 node = root->rb_node;
175 break;
176 }
177 }
178 else
179 {
180 other = parent->rb_left;
181 if (other->rb_color == RB_RED)
182 {
183 other->rb_color = RB_BLACK;
184 parent->rb_color = RB_RED;
185 __rb_rotate_right(parent, root);
186 other = parent->rb_left;
187 }
188 if ((!other->rb_left ||
189 other->rb_left->rb_color == RB_BLACK)
190 && (!other->rb_right ||
191 other->rb_right->rb_color == RB_BLACK))
192 {
193 other->rb_color = RB_RED;
194 node = parent;
195 parent = node->rb_parent;
196 }
197 else
198 {
199 if (!other->rb_left ||
200 other->rb_left->rb_color == RB_BLACK)
201 {
202 register rb_node_t * o_right;
203 if ((o_right = other->rb_right))
204 o_right->rb_color = RB_BLACK;
205 other->rb_color = RB_RED;
206 __rb_rotate_left(other, root);
207 other = parent->rb_left;
208 }
209 other->rb_color = parent->rb_color;
210 parent->rb_color = RB_BLACK;
211 if (other->rb_left)
212 other->rb_left->rb_color = RB_BLACK;
213 __rb_rotate_right(parent, root);
214 node = root->rb_node;
215 break;
216 }
217 }
218 }
219 if (node)
220 node->rb_color = RB_BLACK;
221}
222
223void rb_erase(rb_node_t * node, rb_root_t * root)
224{
225 rb_node_t * child, * parent;
226 int color;
227
228 if (!node->rb_left)
229 child = node->rb_right;
230 else if (!node->rb_right)
231 child = node->rb_left;
232 else
233 {
234 rb_node_t * old = node, * left;
235
236 node = node->rb_right;
237 while ((left = node->rb_left))
238 node = left;
239 child = node->rb_right;
240 parent = node->rb_parent;
241 color = node->rb_color;
242
243 if (child)
244 child->rb_parent = parent;
245 if (parent)
246 {
247 if (parent->rb_left == node)
248 parent->rb_left = child;
249 else
250 parent->rb_right = child;
251 }
252 else
253 root->rb_node = child;
254
255 if (node->rb_parent == old)
256 parent = node;
257 node->rb_parent = old->rb_parent;
258 node->rb_color = old->rb_color;
259 node->rb_right = old->rb_right;
260 node->rb_left = old->rb_left;
261
262 if (old->rb_parent)
263 {
264 if (old->rb_parent->rb_left == old)
265 old->rb_parent->rb_left = node;
266 else
267 old->rb_parent->rb_right = node;
268 } else
269 root->rb_node = node;
270
271 old->rb_left->rb_parent = node;
272 if (old->rb_right)
273 old->rb_right->rb_parent = node;
274 goto color;
275 }
276
277 parent = node->rb_parent;
278 color = node->rb_color;
279
280 if (child)
281 child->rb_parent = parent;
282 if (parent)
283 {
284 if (parent->rb_left == node)
285 parent->rb_left = child;
286 else
287 parent->rb_right = child;
288 }
289 else
290 root->rb_node = child;
291
292 color:
293 if (color == RB_BLACK)
294 __rb_erase_color(child, parent, root);
295}
296EXPORT_SYMBOL(rb_erase);
297