blob: 63473e04f18a881628d33797e53aae00ada8ff34 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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#include <linux/rbtree.h>
24#include <linux/module.h>
25
26static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
27{
28 struct rb_node *right = node->rb_right;
29
30 if ((node->rb_right = right->rb_left))
31 right->rb_left->rb_parent = node;
32 right->rb_left = node;
33
34 if ((right->rb_parent = node->rb_parent))
35 {
36 if (node == node->rb_parent->rb_left)
37 node->rb_parent->rb_left = right;
38 else
39 node->rb_parent->rb_right = right;
40 }
41 else
42 root->rb_node = right;
43 node->rb_parent = right;
44}
45
46static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
47{
48 struct rb_node *left = node->rb_left;
49
50 if ((node->rb_left = left->rb_right))
51 left->rb_right->rb_parent = node;
52 left->rb_right = node;
53
54 if ((left->rb_parent = node->rb_parent))
55 {
56 if (node == node->rb_parent->rb_right)
57 node->rb_parent->rb_right = left;
58 else
59 node->rb_parent->rb_left = left;
60 }
61 else
62 root->rb_node = left;
63 node->rb_parent = left;
64}
65
66void rb_insert_color(struct rb_node *node, struct rb_root *root)
67{
68 struct rb_node *parent, *gparent;
69
70 while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
71 {
72 gparent = parent->rb_parent;
73
74 if (parent == gparent->rb_left)
75 {
76 {
77 register struct rb_node *uncle = gparent->rb_right;
78 if (uncle && uncle->rb_color == RB_RED)
79 {
80 uncle->rb_color = RB_BLACK;
81 parent->rb_color = RB_BLACK;
82 gparent->rb_color = RB_RED;
83 node = gparent;
84 continue;
85 }
86 }
87
88 if (parent->rb_right == node)
89 {
90 register struct rb_node *tmp;
91 __rb_rotate_left(parent, root);
92 tmp = parent;
93 parent = node;
94 node = tmp;
95 }
96
97 parent->rb_color = RB_BLACK;
98 gparent->rb_color = RB_RED;
99 __rb_rotate_right(gparent, root);
100 } else {
101 {
102 register struct rb_node *uncle = gparent->rb_left;
103 if (uncle && uncle->rb_color == RB_RED)
104 {
105 uncle->rb_color = RB_BLACK;
106 parent->rb_color = RB_BLACK;
107 gparent->rb_color = RB_RED;
108 node = gparent;
109 continue;
110 }
111 }
112
113 if (parent->rb_left == node)
114 {
115 register struct rb_node *tmp;
116 __rb_rotate_right(parent, root);
117 tmp = parent;
118 parent = node;
119 node = tmp;
120 }
121
122 parent->rb_color = RB_BLACK;
123 gparent->rb_color = RB_RED;
124 __rb_rotate_left(gparent, root);
125 }
126 }
127
128 root->rb_node->rb_color = RB_BLACK;
129}
130EXPORT_SYMBOL(rb_insert_color);
131
132static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
133 struct rb_root *root)
134{
135 struct rb_node *other;
136
137 while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
138 {
139 if (parent->rb_left == node)
140 {
141 other = parent->rb_right;
142 if (other->rb_color == RB_RED)
143 {
144 other->rb_color = RB_BLACK;
145 parent->rb_color = RB_RED;
146 __rb_rotate_left(parent, root);
147 other = parent->rb_right;
148 }
149 if ((!other->rb_left ||
150 other->rb_left->rb_color == RB_BLACK)
151 && (!other->rb_right ||
152 other->rb_right->rb_color == RB_BLACK))
153 {
154 other->rb_color = RB_RED;
155 node = parent;
156 parent = node->rb_parent;
157 }
158 else
159 {
160 if (!other->rb_right ||
161 other->rb_right->rb_color == RB_BLACK)
162 {
163 register struct rb_node *o_left;
164 if ((o_left = other->rb_left))
165 o_left->rb_color = RB_BLACK;
166 other->rb_color = RB_RED;
167 __rb_rotate_right(other, root);
168 other = parent->rb_right;
169 }
170 other->rb_color = parent->rb_color;
171 parent->rb_color = RB_BLACK;
172 if (other->rb_right)
173 other->rb_right->rb_color = RB_BLACK;
174 __rb_rotate_left(parent, root);
175 node = root->rb_node;
176 break;
177 }
178 }
179 else
180 {
181 other = parent->rb_left;
182 if (other->rb_color == RB_RED)
183 {
184 other->rb_color = RB_BLACK;
185 parent->rb_color = RB_RED;
186 __rb_rotate_right(parent, root);
187 other = parent->rb_left;
188 }
189 if ((!other->rb_left ||
190 other->rb_left->rb_color == RB_BLACK)
191 && (!other->rb_right ||
192 other->rb_right->rb_color == RB_BLACK))
193 {
194 other->rb_color = RB_RED;
195 node = parent;
196 parent = node->rb_parent;
197 }
198 else
199 {
200 if (!other->rb_left ||
201 other->rb_left->rb_color == RB_BLACK)
202 {
203 register struct rb_node *o_right;
204 if ((o_right = other->rb_right))
205 o_right->rb_color = RB_BLACK;
206 other->rb_color = RB_RED;
207 __rb_rotate_left(other, root);
208 other = parent->rb_left;
209 }
210 other->rb_color = parent->rb_color;
211 parent->rb_color = RB_BLACK;
212 if (other->rb_left)
213 other->rb_left->rb_color = RB_BLACK;
214 __rb_rotate_right(parent, root);
215 node = root->rb_node;
216 break;
217 }
218 }
219 }
220 if (node)
221 node->rb_color = RB_BLACK;
222}
223
224void rb_erase(struct rb_node *node, struct rb_root *root)
225{
226 struct rb_node *child, *parent;
227 int color;
228
229 if (!node->rb_left)
230 child = node->rb_right;
231 else if (!node->rb_right)
232 child = node->rb_left;
233 else
234 {
235 struct rb_node *old = node, *left;
236
237 node = node->rb_right;
238 while ((left = node->rb_left) != NULL)
239 node = left;
240 child = node->rb_right;
241 parent = node->rb_parent;
242 color = node->rb_color;
243
244 if (child)
245 child->rb_parent = parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246
David Woodhouse1975e592006-04-21 13:30:36 +0100247 if (node->rb_parent == old) {
248 parent->rb_right = child;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249 parent = node;
David Woodhouse1975e592006-04-21 13:30:36 +0100250 } else
251 parent->rb_left = child;
252
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 node->rb_parent = old->rb_parent;
254 node->rb_color = old->rb_color;
255 node->rb_right = old->rb_right;
256 node->rb_left = old->rb_left;
257
258 if (old->rb_parent)
259 {
260 if (old->rb_parent->rb_left == old)
261 old->rb_parent->rb_left = node;
262 else
263 old->rb_parent->rb_right = node;
264 } else
265 root->rb_node = node;
266
267 old->rb_left->rb_parent = node;
268 if (old->rb_right)
269 old->rb_right->rb_parent = node;
270 goto color;
271 }
272
273 parent = node->rb_parent;
274 color = node->rb_color;
275
276 if (child)
277 child->rb_parent = parent;
278 if (parent)
279 {
280 if (parent->rb_left == node)
281 parent->rb_left = child;
282 else
283 parent->rb_right = child;
284 }
285 else
286 root->rb_node = child;
287
288 color:
289 if (color == RB_BLACK)
290 __rb_erase_color(child, parent, root);
291}
292EXPORT_SYMBOL(rb_erase);
293
294/*
295 * This function returns the first node (in sort order) of the tree.
296 */
297struct rb_node *rb_first(struct rb_root *root)
298{
299 struct rb_node *n;
300
301 n = root->rb_node;
302 if (!n)
303 return NULL;
304 while (n->rb_left)
305 n = n->rb_left;
306 return n;
307}
308EXPORT_SYMBOL(rb_first);
309
310struct rb_node *rb_last(struct rb_root *root)
311{
312 struct rb_node *n;
313
314 n = root->rb_node;
315 if (!n)
316 return NULL;
317 while (n->rb_right)
318 n = n->rb_right;
319 return n;
320}
321EXPORT_SYMBOL(rb_last);
322
323struct rb_node *rb_next(struct rb_node *node)
324{
325 /* If we have a right-hand child, go down and then left as far
326 as we can. */
327 if (node->rb_right) {
328 node = node->rb_right;
329 while (node->rb_left)
330 node=node->rb_left;
331 return node;
332 }
333
334 /* No right-hand children. Everything down and left is
335 smaller than us, so any 'next' node must be in the general
336 direction of our parent. Go up the tree; any time the
337 ancestor is a right-hand child of its parent, keep going
338 up. First time it's a left-hand child of its parent, said
339 parent is our 'next' node. */
340 while (node->rb_parent && node == node->rb_parent->rb_right)
341 node = node->rb_parent;
342
343 return node->rb_parent;
344}
345EXPORT_SYMBOL(rb_next);
346
347struct rb_node *rb_prev(struct rb_node *node)
348{
349 /* If we have a left-hand child, go down and then right as far
350 as we can. */
351 if (node->rb_left) {
352 node = node->rb_left;
353 while (node->rb_right)
354 node=node->rb_right;
355 return node;
356 }
357
358 /* No left-hand children. Go up till we find an ancestor which
359 is a right-hand child of its parent */
360 while (node->rb_parent && node == node->rb_parent->rb_left)
361 node = node->rb_parent;
362
363 return node->rb_parent;
364}
365EXPORT_SYMBOL(rb_prev);
366
367void rb_replace_node(struct rb_node *victim, struct rb_node *new,
368 struct rb_root *root)
369{
370 struct rb_node *parent = victim->rb_parent;
371
372 /* Set the surrounding nodes to point to the replacement */
373 if (parent) {
374 if (victim == parent->rb_left)
375 parent->rb_left = new;
376 else
377 parent->rb_right = new;
378 } else {
379 root->rb_node = new;
380 }
381 if (victim->rb_left)
382 victim->rb_left->rb_parent = new;
383 if (victim->rb_right)
384 victim->rb_right->rb_parent = new;
385
386 /* Copy the pointers/colour from the victim to the replacement */
387 *new = *victim;
388}
389EXPORT_SYMBOL(rb_replace_node);