blob: d0be5fcaafe8e919cd46c4624146656948fbdba9 [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>
Paul Gortmaker8bc3bcc2011-11-16 21:29:17 -050024#include <linux/export.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025
Michel Lespinassebf7ad8e2012-10-08 16:30:37 -070026#define RB_RED 0
27#define RB_BLACK 1
28
29#define rb_color(r) ((r)->__rb_parent_color & 1)
30#define rb_is_red(r) (!rb_color(r))
31#define rb_is_black(r) rb_color(r)
32#define rb_set_red(r) do { (r)->__rb_parent_color &= ~1; } while (0)
33#define rb_set_black(r) do { (r)->__rb_parent_color |= 1; } while (0)
34
35static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
36{
37 rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
38}
39static inline void rb_set_color(struct rb_node *rb, int color)
40{
41 rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
42}
43
Linus Torvalds1da177e2005-04-16 15:20:36 -070044static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
45{
46 struct rb_node *right = node->rb_right;
David Woodhouse55a98102006-04-21 13:35:51 +010047 struct rb_node *parent = rb_parent(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -070048
49 if ((node->rb_right = right->rb_left))
David Woodhouse55a98102006-04-21 13:35:51 +010050 rb_set_parent(right->rb_left, node);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051 right->rb_left = node;
52
David Woodhouse55a98102006-04-21 13:35:51 +010053 rb_set_parent(right, parent);
54
55 if (parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 {
David Woodhouse55a98102006-04-21 13:35:51 +010057 if (node == parent->rb_left)
58 parent->rb_left = right;
Linus Torvalds1da177e2005-04-16 15:20:36 -070059 else
David Woodhouse55a98102006-04-21 13:35:51 +010060 parent->rb_right = right;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061 }
62 else
63 root->rb_node = right;
David Woodhouse55a98102006-04-21 13:35:51 +010064 rb_set_parent(node, right);
Linus Torvalds1da177e2005-04-16 15:20:36 -070065}
66
67static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
68{
69 struct rb_node *left = node->rb_left;
David Woodhouse55a98102006-04-21 13:35:51 +010070 struct rb_node *parent = rb_parent(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -070071
72 if ((node->rb_left = left->rb_right))
David Woodhouse55a98102006-04-21 13:35:51 +010073 rb_set_parent(left->rb_right, node);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074 left->rb_right = node;
75
David Woodhouse55a98102006-04-21 13:35:51 +010076 rb_set_parent(left, parent);
77
78 if (parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 {
David Woodhouse55a98102006-04-21 13:35:51 +010080 if (node == parent->rb_right)
81 parent->rb_right = left;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 else
David Woodhouse55a98102006-04-21 13:35:51 +010083 parent->rb_left = left;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 }
85 else
86 root->rb_node = left;
David Woodhouse55a98102006-04-21 13:35:51 +010087 rb_set_parent(node, left);
Linus Torvalds1da177e2005-04-16 15:20:36 -070088}
89
90void rb_insert_color(struct rb_node *node, struct rb_root *root)
91{
92 struct rb_node *parent, *gparent;
93
Michel Lespinasse6d584522012-10-08 16:30:44 -070094 while (true) {
95 /*
96 * Loop invariant: node is red
97 *
98 * If there is a black parent, we are done.
99 * Otherwise, take some corrective action as we don't
100 * want a red root or two consecutive red nodes.
101 */
102 parent = rb_parent(node);
103 if (!parent) {
104 rb_set_black(node);
105 break;
106 } else if (rb_is_black(parent))
107 break;
108
David Woodhouse55a98102006-04-21 13:35:51 +0100109 gparent = rb_parent(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111 if (parent == gparent->rb_left)
112 {
113 {
114 register struct rb_node *uncle = gparent->rb_right;
David Woodhouse55a98102006-04-21 13:35:51 +0100115 if (uncle && rb_is_red(uncle))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 {
David Woodhouse55a98102006-04-21 13:35:51 +0100117 rb_set_black(uncle);
118 rb_set_black(parent);
119 rb_set_red(gparent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120 node = gparent;
121 continue;
122 }
123 }
124
Michel Lespinasse1f052862012-10-08 16:30:42 -0700125 if (parent->rb_right == node) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 __rb_rotate_left(parent, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 parent = node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 }
129
David Woodhouse55a98102006-04-21 13:35:51 +0100130 rb_set_black(parent);
131 rb_set_red(gparent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 __rb_rotate_right(gparent, root);
Michel Lespinasse1f052862012-10-08 16:30:42 -0700133 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 } else {
135 {
136 register struct rb_node *uncle = gparent->rb_left;
David Woodhouse55a98102006-04-21 13:35:51 +0100137 if (uncle && rb_is_red(uncle))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 {
David Woodhouse55a98102006-04-21 13:35:51 +0100139 rb_set_black(uncle);
140 rb_set_black(parent);
141 rb_set_red(gparent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 node = gparent;
143 continue;
144 }
145 }
146
Michel Lespinasse1f052862012-10-08 16:30:42 -0700147 if (parent->rb_left == node) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 __rb_rotate_right(parent, root);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 parent = node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 }
151
David Woodhouse55a98102006-04-21 13:35:51 +0100152 rb_set_black(parent);
153 rb_set_red(gparent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 __rb_rotate_left(gparent, root);
Michel Lespinasse1f052862012-10-08 16:30:42 -0700155 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 }
157 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158}
159EXPORT_SYMBOL(rb_insert_color);
160
161static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
162 struct rb_root *root)
163{
164 struct rb_node *other;
165
David Woodhouse55a98102006-04-21 13:35:51 +0100166 while ((!node || rb_is_black(node)) && node != root->rb_node)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 {
168 if (parent->rb_left == node)
169 {
170 other = parent->rb_right;
David Woodhouse55a98102006-04-21 13:35:51 +0100171 if (rb_is_red(other))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 {
David Woodhouse55a98102006-04-21 13:35:51 +0100173 rb_set_black(other);
174 rb_set_red(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 __rb_rotate_left(parent, root);
176 other = parent->rb_right;
177 }
David Woodhouse55a98102006-04-21 13:35:51 +0100178 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
179 (!other->rb_right || rb_is_black(other->rb_right)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 {
David Woodhouse55a98102006-04-21 13:35:51 +0100181 rb_set_red(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 node = parent;
David Woodhouse55a98102006-04-21 13:35:51 +0100183 parent = rb_parent(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 }
185 else
186 {
David Woodhouse55a98102006-04-21 13:35:51 +0100187 if (!other->rb_right || rb_is_black(other->rb_right))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 {
Wolfram Strepp55a63992009-03-31 15:23:45 -0700189 rb_set_black(other->rb_left);
David Woodhouse55a98102006-04-21 13:35:51 +0100190 rb_set_red(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 __rb_rotate_right(other, root);
192 other = parent->rb_right;
193 }
David Woodhouse2f3243a2006-06-05 20:19:05 +0100194 rb_set_color(other, rb_color(parent));
David Woodhouse55a98102006-04-21 13:35:51 +0100195 rb_set_black(parent);
Wolfram Strepp55a63992009-03-31 15:23:45 -0700196 rb_set_black(other->rb_right);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 __rb_rotate_left(parent, root);
198 node = root->rb_node;
199 break;
200 }
201 }
202 else
203 {
204 other = parent->rb_left;
David Woodhouse55a98102006-04-21 13:35:51 +0100205 if (rb_is_red(other))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 {
David Woodhouse55a98102006-04-21 13:35:51 +0100207 rb_set_black(other);
208 rb_set_red(parent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 __rb_rotate_right(parent, root);
210 other = parent->rb_left;
211 }
David Woodhouse55a98102006-04-21 13:35:51 +0100212 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
213 (!other->rb_right || rb_is_black(other->rb_right)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 {
David Woodhouse55a98102006-04-21 13:35:51 +0100215 rb_set_red(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 node = parent;
David Woodhouse55a98102006-04-21 13:35:51 +0100217 parent = rb_parent(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 }
219 else
220 {
David Woodhouse55a98102006-04-21 13:35:51 +0100221 if (!other->rb_left || rb_is_black(other->rb_left))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 {
Wolfram Strepp55a63992009-03-31 15:23:45 -0700223 rb_set_black(other->rb_right);
David Woodhouse55a98102006-04-21 13:35:51 +0100224 rb_set_red(other);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 __rb_rotate_left(other, root);
226 other = parent->rb_left;
227 }
David Woodhouse2f3243a2006-06-05 20:19:05 +0100228 rb_set_color(other, rb_color(parent));
David Woodhouse55a98102006-04-21 13:35:51 +0100229 rb_set_black(parent);
Wolfram Strepp55a63992009-03-31 15:23:45 -0700230 rb_set_black(other->rb_left);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 __rb_rotate_right(parent, root);
232 node = root->rb_node;
233 break;
234 }
235 }
236 }
237 if (node)
David Woodhouse55a98102006-04-21 13:35:51 +0100238 rb_set_black(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239}
240
241void rb_erase(struct rb_node *node, struct rb_root *root)
242{
243 struct rb_node *child, *parent;
244 int color;
245
246 if (!node->rb_left)
247 child = node->rb_right;
248 else if (!node->rb_right)
249 child = node->rb_left;
250 else
251 {
252 struct rb_node *old = node, *left;
253
254 node = node->rb_right;
255 while ((left = node->rb_left) != NULL)
256 node = left;
Wolfram Strepp16c047a2009-06-16 15:34:11 -0700257
258 if (rb_parent(old)) {
259 if (rb_parent(old)->rb_left == old)
260 rb_parent(old)->rb_left = node;
261 else
262 rb_parent(old)->rb_right = node;
263 } else
264 root->rb_node = node;
265
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266 child = node->rb_right;
David Woodhouse55a98102006-04-21 13:35:51 +0100267 parent = rb_parent(node);
David Woodhouse2f3243a2006-06-05 20:19:05 +0100268 color = rb_color(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269
David Woodhouse55a98102006-04-21 13:35:51 +0100270 if (parent == old) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 parent = node;
Wolfram Strepp4c601172009-06-16 15:34:12 -0700272 } else {
273 if (child)
274 rb_set_parent(child, parent);
David Woodhouse1975e592006-04-21 13:30:36 +0100275 parent->rb_left = child;
Wolfram Strepp4b324122009-06-16 15:34:13 -0700276
277 node->rb_right = old->rb_right;
278 rb_set_parent(old->rb_right, node);
Wolfram Strepp4c601172009-06-16 15:34:12 -0700279 }
David Woodhouse1975e592006-04-21 13:30:36 +0100280
Michel Lespinassebf7ad8e2012-10-08 16:30:37 -0700281 node->__rb_parent_color = old->__rb_parent_color;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700282 node->rb_left = old->rb_left;
David Woodhouse55a98102006-04-21 13:35:51 +0100283 rb_set_parent(old->rb_left, node);
Wolfram Strepp4b324122009-06-16 15:34:13 -0700284
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285 goto color;
286 }
287
David Woodhouse55a98102006-04-21 13:35:51 +0100288 parent = rb_parent(node);
David Woodhouse2f3243a2006-06-05 20:19:05 +0100289 color = rb_color(node);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290
291 if (child)
David Woodhouse55a98102006-04-21 13:35:51 +0100292 rb_set_parent(child, parent);
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200293 if (parent)
294 {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 if (parent->rb_left == node)
296 parent->rb_left = child;
297 else
298 parent->rb_right = child;
Pallipadi, Venkatesh17d9ddc2010-02-10 15:23:44 -0800299 }
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200300 else
301 root->rb_node = child;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700302
303 color:
304 if (color == RB_BLACK)
305 __rb_erase_color(child, parent, root);
306}
307EXPORT_SYMBOL(rb_erase);
308
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200309static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
310{
311 struct rb_node *parent;
312
313up:
314 func(node, data);
315 parent = rb_parent(node);
316 if (!parent)
317 return;
318
319 if (node == parent->rb_left && parent->rb_right)
320 func(parent->rb_right, data);
321 else if (parent->rb_left)
322 func(parent->rb_left, data);
323
324 node = parent;
325 goto up;
326}
327
328/*
329 * after inserting @node into the tree, update the tree to account for
330 * both the new entry and any damage done by rebalance
331 */
332void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
333{
334 if (node->rb_left)
335 node = node->rb_left;
336 else if (node->rb_right)
337 node = node->rb_right;
338
339 rb_augment_path(node, func, data);
340}
Andreas Gruenbacher0b6bb662011-01-26 15:55:36 +0100341EXPORT_SYMBOL(rb_augment_insert);
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200342
343/*
344 * before removing the node, find the deepest node on the rebalance path
345 * that will still be there after @node gets removed
346 */
347struct rb_node *rb_augment_erase_begin(struct rb_node *node)
348{
349 struct rb_node *deepest;
350
351 if (!node->rb_right && !node->rb_left)
352 deepest = rb_parent(node);
353 else if (!node->rb_right)
354 deepest = node->rb_left;
355 else if (!node->rb_left)
356 deepest = node->rb_right;
357 else {
358 deepest = rb_next(node);
359 if (deepest->rb_right)
360 deepest = deepest->rb_right;
361 else if (rb_parent(deepest) != node)
362 deepest = rb_parent(deepest);
363 }
364
365 return deepest;
366}
Andreas Gruenbacher0b6bb662011-01-26 15:55:36 +0100367EXPORT_SYMBOL(rb_augment_erase_begin);
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200368
369/*
370 * after removal, update the tree to account for the removed entry
371 * and any rebalance damage.
372 */
373void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
374{
375 if (node)
376 rb_augment_path(node, func, data);
377}
Andreas Gruenbacher0b6bb662011-01-26 15:55:36 +0100378EXPORT_SYMBOL(rb_augment_erase_end);
Peter Zijlstrab945d6b2010-05-29 15:31:43 +0200379
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380/*
381 * This function returns the first node (in sort order) of the tree.
382 */
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000383struct rb_node *rb_first(const struct rb_root *root)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384{
385 struct rb_node *n;
386
387 n = root->rb_node;
388 if (!n)
389 return NULL;
390 while (n->rb_left)
391 n = n->rb_left;
392 return n;
393}
394EXPORT_SYMBOL(rb_first);
395
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000396struct rb_node *rb_last(const struct rb_root *root)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700397{
398 struct rb_node *n;
399
400 n = root->rb_node;
401 if (!n)
402 return NULL;
403 while (n->rb_right)
404 n = n->rb_right;
405 return n;
406}
407EXPORT_SYMBOL(rb_last);
408
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000409struct rb_node *rb_next(const struct rb_node *node)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410{
David Woodhouse55a98102006-04-21 13:35:51 +0100411 struct rb_node *parent;
412
Michel Lespinasse4c199a92012-10-08 16:30:32 -0700413 if (RB_EMPTY_NODE(node))
Jens Axboe10fd48f2006-07-11 21:15:52 +0200414 return NULL;
415
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 /* If we have a right-hand child, go down and then left as far
417 as we can. */
418 if (node->rb_right) {
419 node = node->rb_right;
420 while (node->rb_left)
421 node=node->rb_left;
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000422 return (struct rb_node *)node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 }
424
425 /* No right-hand children. Everything down and left is
426 smaller than us, so any 'next' node must be in the general
427 direction of our parent. Go up the tree; any time the
428 ancestor is a right-hand child of its parent, keep going
429 up. First time it's a left-hand child of its parent, said
430 parent is our 'next' node. */
David Woodhouse55a98102006-04-21 13:35:51 +0100431 while ((parent = rb_parent(node)) && node == parent->rb_right)
432 node = parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
David Woodhouse55a98102006-04-21 13:35:51 +0100434 return parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435}
436EXPORT_SYMBOL(rb_next);
437
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000438struct rb_node *rb_prev(const struct rb_node *node)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
David Woodhouse55a98102006-04-21 13:35:51 +0100440 struct rb_node *parent;
441
Michel Lespinasse4c199a92012-10-08 16:30:32 -0700442 if (RB_EMPTY_NODE(node))
Jens Axboe10fd48f2006-07-11 21:15:52 +0200443 return NULL;
444
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 /* If we have a left-hand child, go down and then right as far
446 as we can. */
447 if (node->rb_left) {
448 node = node->rb_left;
449 while (node->rb_right)
450 node=node->rb_right;
Artem Bityutskiyf4b477c2009-01-10 11:12:09 +0000451 return (struct rb_node *)node;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 }
453
454 /* No left-hand children. Go up till we find an ancestor which
455 is a right-hand child of its parent */
David Woodhouse55a98102006-04-21 13:35:51 +0100456 while ((parent = rb_parent(node)) && node == parent->rb_left)
457 node = parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458
David Woodhouse55a98102006-04-21 13:35:51 +0100459 return parent;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460}
461EXPORT_SYMBOL(rb_prev);
462
463void rb_replace_node(struct rb_node *victim, struct rb_node *new,
464 struct rb_root *root)
465{
David Woodhouse55a98102006-04-21 13:35:51 +0100466 struct rb_node *parent = rb_parent(victim);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467
468 /* Set the surrounding nodes to point to the replacement */
469 if (parent) {
470 if (victim == parent->rb_left)
471 parent->rb_left = new;
472 else
473 parent->rb_right = new;
474 } else {
475 root->rb_node = new;
476 }
477 if (victim->rb_left)
David Woodhouse55a98102006-04-21 13:35:51 +0100478 rb_set_parent(victim->rb_left, new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 if (victim->rb_right)
David Woodhouse55a98102006-04-21 13:35:51 +0100480 rb_set_parent(victim->rb_right, new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 /* Copy the pointers/colour from the victim to the replacement */
483 *new = *victim;
484}
485EXPORT_SYMBOL(rb_replace_node);