blob: 86b21badf009af706ad5365689cf95f3cb45ef84 [file] [log] [blame]
Willy Tarreaud59d22e2007-01-07 00:18:48 +01001/*
2 Red Black Trees
3 (C) 1999 Andrea Arcangeli <andrea@suse.de>
4 (C) 2002 David Woodhouse <dwmw2@infradead.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 linux/lib/rbtree.c
21*/
22
23/*
24#include <linux/rbtree.h>
25#include <linux/module.h>
26*/
27
28#include <stdlib.h>
29#include <common/rbtree.h>
30
31static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
32{
33 struct rb_node *right = node->rb_right;
34
35 if ((node->rb_right = right->rb_left))
36 right->rb_left->rb_parent = node;
37 right->rb_left = node;
38
39 if ((right->rb_parent = node->rb_parent))
40 {
41 if (node == node->rb_parent->rb_left)
42 node->rb_parent->rb_left = right;
43 else
44 node->rb_parent->rb_right = right;
45 }
46 else
47 root->rb_node = right;
48 node->rb_parent = right;
49}
50
51static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
52{
53 struct rb_node *left = node->rb_left;
54
55 if ((node->rb_left = left->rb_right))
56 left->rb_right->rb_parent = node;
57 left->rb_right = node;
58
59 if ((left->rb_parent = node->rb_parent))
60 {
61 if (node == node->rb_parent->rb_right)
62 node->rb_parent->rb_right = left;
63 else
64 node->rb_parent->rb_left = left;
65 }
66 else
67 root->rb_node = left;
68 node->rb_parent = left;
69}
70
71void rb_insert_color(struct rb_node *node, struct rb_root *root)
72{
73 struct rb_node *parent, *gparent;
74
75 while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
76 {
77 gparent = parent->rb_parent;
78
79 if (parent == gparent->rb_left)
80 {
81 {
82 register struct rb_node *uncle = gparent->rb_right;
83 if (uncle && uncle->rb_color == RB_RED)
84 {
85 uncle->rb_color = RB_BLACK;
86 parent->rb_color = RB_BLACK;
87 gparent->rb_color = RB_RED;
88 node = gparent;
89 continue;
90 }
91 }
92
93 if (parent->rb_right == node)
94 {
95 register struct rb_node *tmp;
96 __rb_rotate_left(parent, root);
97 tmp = parent;
98 parent = node;
99 node = tmp;
100 }
101
102 parent->rb_color = RB_BLACK;
103 gparent->rb_color = RB_RED;
104 __rb_rotate_right(gparent, root);
105 } else {
106 {
107 register struct rb_node *uncle = gparent->rb_left;
108 if (uncle && uncle->rb_color == RB_RED)
109 {
110 uncle->rb_color = RB_BLACK;
111 parent->rb_color = RB_BLACK;
112 gparent->rb_color = RB_RED;
113 node = gparent;
114 continue;
115 }
116 }
117
118 if (parent->rb_left == node)
119 {
120 register struct rb_node *tmp;
121 __rb_rotate_right(parent, root);
122 tmp = parent;
123 parent = node;
124 node = tmp;
125 }
126
127 parent->rb_color = RB_BLACK;
128 gparent->rb_color = RB_RED;
129 __rb_rotate_left(gparent, root);
130 }
131 }
132
133 root->rb_node->rb_color = RB_BLACK;
134}
135// EXPORT_SYMBOL(rb_insert_color);
136
137static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
138 struct rb_root *root)
139{
140 struct rb_node *other;
141
142 while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
143 {
144 if (parent->rb_left == node)
145 {
146 other = parent->rb_right;
147 if (other->rb_color == RB_RED)
148 {
149 other->rb_color = RB_BLACK;
150 parent->rb_color = RB_RED;
151 __rb_rotate_left(parent, root);
152 other = parent->rb_right;
153 }
154 if ((!other->rb_left ||
155 other->rb_left->rb_color == RB_BLACK)
156 && (!other->rb_right ||
157 other->rb_right->rb_color == RB_BLACK))
158 {
159 other->rb_color = RB_RED;
160 node = parent;
161 parent = node->rb_parent;
162 }
163 else
164 {
165 if (!other->rb_right ||
166 other->rb_right->rb_color == RB_BLACK)
167 {
168 register struct rb_node *o_left;
169 if ((o_left = other->rb_left))
170 o_left->rb_color = RB_BLACK;
171 other->rb_color = RB_RED;
172 __rb_rotate_right(other, root);
173 other = parent->rb_right;
174 }
175 other->rb_color = parent->rb_color;
176 parent->rb_color = RB_BLACK;
177 if (other->rb_right)
178 other->rb_right->rb_color = RB_BLACK;
179 __rb_rotate_left(parent, root);
180 node = root->rb_node;
181 break;
182 }
183 }
184 else
185 {
186 other = parent->rb_left;
187 if (other->rb_color == RB_RED)
188 {
189 other->rb_color = RB_BLACK;
190 parent->rb_color = RB_RED;
191 __rb_rotate_right(parent, root);
192 other = parent->rb_left;
193 }
194 if ((!other->rb_left ||
195 other->rb_left->rb_color == RB_BLACK)
196 && (!other->rb_right ||
197 other->rb_right->rb_color == RB_BLACK))
198 {
199 other->rb_color = RB_RED;
200 node = parent;
201 parent = node->rb_parent;
202 }
203 else
204 {
205 if (!other->rb_left ||
206 other->rb_left->rb_color == RB_BLACK)
207 {
208 register struct rb_node *o_right;
209 if ((o_right = other->rb_right))
210 o_right->rb_color = RB_BLACK;
211 other->rb_color = RB_RED;
212 __rb_rotate_left(other, root);
213 other = parent->rb_left;
214 }
215 other->rb_color = parent->rb_color;
216 parent->rb_color = RB_BLACK;
217 if (other->rb_left)
218 other->rb_left->rb_color = RB_BLACK;
219 __rb_rotate_right(parent, root);
220 node = root->rb_node;
221 break;
222 }
223 }
224 }
225 if (node)
226 node->rb_color = RB_BLACK;
227}
228
229void rb_erase(struct rb_node *node, struct rb_root *root)
230{
231 struct rb_node *child, *parent;
232 int color;
233
234 if (!node->rb_left)
235 child = node->rb_right;
236 else if (!node->rb_right)
237 child = node->rb_left;
238 else
239 {
240 struct rb_node *old = node, *left;
241
242 node = node->rb_right;
243 while ((left = node->rb_left) != NULL)
244 node = left;
245 child = node->rb_right;
246 parent = node->rb_parent;
247 color = node->rb_color;
248
249 if (child)
250 child->rb_parent = parent;
251 if (parent)
252 {
253 if (parent->rb_left == node)
254 parent->rb_left = child;
255 else
256 parent->rb_right = child;
257 }
258 else
259 root->rb_node = child;
260
261 if (node->rb_parent == old)
262 parent = node;
263 node->rb_parent = old->rb_parent;
264 node->rb_color = old->rb_color;
265 node->rb_right = old->rb_right;
266 node->rb_left = old->rb_left;
267
268 if (old->rb_parent)
269 {
270 if (old->rb_parent->rb_left == old)
271 old->rb_parent->rb_left = node;
272 else
273 old->rb_parent->rb_right = node;
274 } else
275 root->rb_node = node;
276
277 old->rb_left->rb_parent = node;
278 if (old->rb_right)
279 old->rb_right->rb_parent = node;
280 goto color;
281 }
282
283 parent = node->rb_parent;
284 color = node->rb_color;
285
286 if (child)
287 child->rb_parent = parent;
288 if (parent)
289 {
290 if (parent->rb_left == node)
291 parent->rb_left = child;
292 else
293 parent->rb_right = child;
294 }
295 else
296 root->rb_node = child;
297
298 color:
299 if (color == RB_BLACK)
300 __rb_erase_color(child, parent, root);
301}
302// EXPORT_SYMBOL(rb_erase);
303
304/*
305 * This function returns the first node (in sort order) of the tree.
306 */
307struct rb_node *rb_first(struct rb_root *root)
308{
309 struct rb_node *n;
310
311 n = root->rb_node;
312 if (!n)
313 return NULL;
314 while (n->rb_left)
315 n = n->rb_left;
316 return n;
317}
318// EXPORT_SYMBOL(rb_first);
319
320struct rb_node *rb_last(struct rb_root *root)
321{
322 struct rb_node *n;
323
324 n = root->rb_node;
325 if (!n)
326 return NULL;
327 while (n->rb_right)
328 n = n->rb_right;
329 return n;
330}
331// EXPORT_SYMBOL(rb_last);
332
333struct rb_node *rb_next(struct rb_node *node)
334{
335 /* If we have a right-hand child, go down and then left as far
336 as we can. */
337 if (node->rb_right) {
338 node = node->rb_right;
339 while (node->rb_left)
340 node=node->rb_left;
341 return node;
342 }
343
344 /* No right-hand children. Everything down and left is
345 smaller than us, so any 'next' node must be in the general
346 direction of our parent. Go up the tree; any time the
347 ancestor is a right-hand child of its parent, keep going
348 up. First time it's a left-hand child of its parent, said
349 parent is our 'next' node. */
350 while (node->rb_parent && node == node->rb_parent->rb_right)
351 node = node->rb_parent;
352
353 return node->rb_parent;
354}
355// EXPORT_SYMBOL(rb_next);
356
357struct rb_node *rb_prev(struct rb_node *node)
358{
359 /* If we have a left-hand child, go down and then right as far
360 as we can. */
361 if (node->rb_left) {
362 node = node->rb_left;
363 while (node->rb_right)
364 node=node->rb_right;
365 return node;
366 }
367
368 /* No left-hand children. Go up till we find an ancestor which
369 is a right-hand child of its parent */
370 while (node->rb_parent && node == node->rb_parent->rb_left)
371 node = node->rb_parent;
372
373 return node->rb_parent;
374}
375// EXPORT_SYMBOL(rb_prev);
376
377void rb_replace_node(struct rb_node *victim, struct rb_node *new,
378 struct rb_root *root)
379{
380 struct rb_node *parent = victim->rb_parent;
381
382 /* Set the surrounding nodes to point to the replacement */
383 if (parent) {
384 if (victim == parent->rb_left)
385 parent->rb_left = new;
386 else
387 parent->rb_right = new;
388 } else {
389 root->rb_node = new;
390 }
391 if (victim->rb_left)
392 victim->rb_left->rb_parent = new;
393 if (victim->rb_right)
394 victim->rb_right->rb_parent = new;
395
396 /* Copy the pointers/colour from the victim to the replacement */
397 *new = *victim;
398}
399// EXPORT_SYMBOL(rb_replace_node);