]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - lib/rbtree.c
rbtree: adjust root color in rb_insert_color() only when necessary
[mirror_ubuntu-jammy-kernel.git] / lib / rbtree.c
CommitLineData
1da177e4
LT
1/*
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>
8bc3bcc9 24#include <linux/export.h>
1da177e4 25
bf7ad8ee
ML
26#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
1da177e4
LT
44static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
45{
46 struct rb_node *right = node->rb_right;
55a98102 47 struct rb_node *parent = rb_parent(node);
1da177e4
LT
48
49 if ((node->rb_right = right->rb_left))
55a98102 50 rb_set_parent(right->rb_left, node);
1da177e4
LT
51 right->rb_left = node;
52
55a98102
DW
53 rb_set_parent(right, parent);
54
55 if (parent)
1da177e4 56 {
55a98102
DW
57 if (node == parent->rb_left)
58 parent->rb_left = right;
1da177e4 59 else
55a98102 60 parent->rb_right = right;
1da177e4
LT
61 }
62 else
63 root->rb_node = right;
55a98102 64 rb_set_parent(node, right);
1da177e4
LT
65}
66
67static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
68{
69 struct rb_node *left = node->rb_left;
55a98102 70 struct rb_node *parent = rb_parent(node);
1da177e4
LT
71
72 if ((node->rb_left = left->rb_right))
55a98102 73 rb_set_parent(left->rb_right, node);
1da177e4
LT
74 left->rb_right = node;
75
55a98102
DW
76 rb_set_parent(left, parent);
77
78 if (parent)
1da177e4 79 {
55a98102
DW
80 if (node == parent->rb_right)
81 parent->rb_right = left;
1da177e4 82 else
55a98102 83 parent->rb_left = left;
1da177e4
LT
84 }
85 else
86 root->rb_node = left;
55a98102 87 rb_set_parent(node, left);
1da177e4
LT
88}
89
90void rb_insert_color(struct rb_node *node, struct rb_root *root)
91{
92 struct rb_node *parent, *gparent;
93
6d58452d
ML
94 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
55a98102 109 gparent = rb_parent(parent);
1da177e4
LT
110
111 if (parent == gparent->rb_left)
112 {
113 {
114 register struct rb_node *uncle = gparent->rb_right;
55a98102 115 if (uncle && rb_is_red(uncle))
1da177e4 116 {
55a98102
DW
117 rb_set_black(uncle);
118 rb_set_black(parent);
119 rb_set_red(gparent);
1da177e4
LT
120 node = gparent;
121 continue;
122 }
123 }
124
1f052865 125 if (parent->rb_right == node) {
1da177e4 126 __rb_rotate_left(parent, root);
1da177e4 127 parent = node;
1da177e4
LT
128 }
129
55a98102
DW
130 rb_set_black(parent);
131 rb_set_red(gparent);
1da177e4 132 __rb_rotate_right(gparent, root);
1f052865 133 break;
1da177e4
LT
134 } else {
135 {
136 register struct rb_node *uncle = gparent->rb_left;
55a98102 137 if (uncle && rb_is_red(uncle))
1da177e4 138 {
55a98102
DW
139 rb_set_black(uncle);
140 rb_set_black(parent);
141 rb_set_red(gparent);
1da177e4
LT
142 node = gparent;
143 continue;
144 }
145 }
146
1f052865 147 if (parent->rb_left == node) {
1da177e4 148 __rb_rotate_right(parent, root);
1da177e4 149 parent = node;
1da177e4
LT
150 }
151
55a98102
DW
152 rb_set_black(parent);
153 rb_set_red(gparent);
1da177e4 154 __rb_rotate_left(gparent, root);
1f052865 155 break;
1da177e4
LT
156 }
157 }
1da177e4
LT
158}
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
55a98102 166 while ((!node || rb_is_black(node)) && node != root->rb_node)
1da177e4
LT
167 {
168 if (parent->rb_left == node)
169 {
170 other = parent->rb_right;
55a98102 171 if (rb_is_red(other))
1da177e4 172 {
55a98102
DW
173 rb_set_black(other);
174 rb_set_red(parent);
1da177e4
LT
175 __rb_rotate_left(parent, root);
176 other = parent->rb_right;
177 }
55a98102
DW
178 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
179 (!other->rb_right || rb_is_black(other->rb_right)))
1da177e4 180 {
55a98102 181 rb_set_red(other);
1da177e4 182 node = parent;
55a98102 183 parent = rb_parent(node);
1da177e4
LT
184 }
185 else
186 {
55a98102 187 if (!other->rb_right || rb_is_black(other->rb_right))
1da177e4 188 {
55a63998 189 rb_set_black(other->rb_left);
55a98102 190 rb_set_red(other);
1da177e4
LT
191 __rb_rotate_right(other, root);
192 other = parent->rb_right;
193 }
2f3243ae 194 rb_set_color(other, rb_color(parent));
55a98102 195 rb_set_black(parent);
55a63998 196 rb_set_black(other->rb_right);
1da177e4
LT
197 __rb_rotate_left(parent, root);
198 node = root->rb_node;
199 break;
200 }
201 }
202 else
203 {
204 other = parent->rb_left;
55a98102 205 if (rb_is_red(other))
1da177e4 206 {
55a98102
DW
207 rb_set_black(other);
208 rb_set_red(parent);
1da177e4
LT
209 __rb_rotate_right(parent, root);
210 other = parent->rb_left;
211 }
55a98102
DW
212 if ((!other->rb_left || rb_is_black(other->rb_left)) &&
213 (!other->rb_right || rb_is_black(other->rb_right)))
1da177e4 214 {
55a98102 215 rb_set_red(other);
1da177e4 216 node = parent;
55a98102 217 parent = rb_parent(node);
1da177e4
LT
218 }
219 else
220 {
55a98102 221 if (!other->rb_left || rb_is_black(other->rb_left))
1da177e4 222 {
55a63998 223 rb_set_black(other->rb_right);
55a98102 224 rb_set_red(other);
1da177e4
LT
225 __rb_rotate_left(other, root);
226 other = parent->rb_left;
227 }
2f3243ae 228 rb_set_color(other, rb_color(parent));
55a98102 229 rb_set_black(parent);
55a63998 230 rb_set_black(other->rb_left);
1da177e4
LT
231 __rb_rotate_right(parent, root);
232 node = root->rb_node;
233 break;
234 }
235 }
236 }
237 if (node)
55a98102 238 rb_set_black(node);
1da177e4
LT
239}
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;
16c047ad
WS
257
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
1da177e4 266 child = node->rb_right;
55a98102 267 parent = rb_parent(node);
2f3243ae 268 color = rb_color(node);
1da177e4 269
55a98102 270 if (parent == old) {
1da177e4 271 parent = node;
4c601178
WS
272 } else {
273 if (child)
274 rb_set_parent(child, parent);
1975e593 275 parent->rb_left = child;
4b324126
WS
276
277 node->rb_right = old->rb_right;
278 rb_set_parent(old->rb_right, node);
4c601178 279 }
1975e593 280
bf7ad8ee 281 node->__rb_parent_color = old->__rb_parent_color;
1da177e4 282 node->rb_left = old->rb_left;
55a98102 283 rb_set_parent(old->rb_left, node);
4b324126 284
1da177e4
LT
285 goto color;
286 }
287
55a98102 288 parent = rb_parent(node);
2f3243ae 289 color = rb_color(node);
1da177e4
LT
290
291 if (child)
55a98102 292 rb_set_parent(child, parent);
b945d6b2
PZ
293 if (parent)
294 {
1da177e4
LT
295 if (parent->rb_left == node)
296 parent->rb_left = child;
297 else
298 parent->rb_right = child;
17d9ddc7 299 }
b945d6b2
PZ
300 else
301 root->rb_node = child;
1da177e4
LT
302
303 color:
304 if (color == RB_BLACK)
305 __rb_erase_color(child, parent, root);
306}
307EXPORT_SYMBOL(rb_erase);
308
b945d6b2
PZ
309static 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}
0b6bb66d 341EXPORT_SYMBOL(rb_augment_insert);
b945d6b2
PZ
342
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}
0b6bb66d 367EXPORT_SYMBOL(rb_augment_erase_begin);
b945d6b2
PZ
368
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}
0b6bb66d 378EXPORT_SYMBOL(rb_augment_erase_end);
b945d6b2 379
1da177e4
LT
380/*
381 * This function returns the first node (in sort order) of the tree.
382 */
f4b477c4 383struct rb_node *rb_first(const struct rb_root *root)
1da177e4
LT
384{
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
f4b477c4 396struct rb_node *rb_last(const struct rb_root *root)
1da177e4
LT
397{
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
f4b477c4 409struct rb_node *rb_next(const struct rb_node *node)
1da177e4 410{
55a98102
DW
411 struct rb_node *parent;
412
4c199a93 413 if (RB_EMPTY_NODE(node))
10fd48f2
JA
414 return NULL;
415
1da177e4
LT
416 /* 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;
f4b477c4 422 return (struct rb_node *)node;
1da177e4
LT
423 }
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. */
55a98102
DW
431 while ((parent = rb_parent(node)) && node == parent->rb_right)
432 node = parent;
1da177e4 433
55a98102 434 return parent;
1da177e4
LT
435}
436EXPORT_SYMBOL(rb_next);
437
f4b477c4 438struct rb_node *rb_prev(const struct rb_node *node)
1da177e4 439{
55a98102
DW
440 struct rb_node *parent;
441
4c199a93 442 if (RB_EMPTY_NODE(node))
10fd48f2
JA
443 return NULL;
444
1da177e4
LT
445 /* 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;
f4b477c4 451 return (struct rb_node *)node;
1da177e4
LT
452 }
453
454 /* No left-hand children. Go up till we find an ancestor which
455 is a right-hand child of its parent */
55a98102
DW
456 while ((parent = rb_parent(node)) && node == parent->rb_left)
457 node = parent;
1da177e4 458
55a98102 459 return parent;
1da177e4
LT
460}
461EXPORT_SYMBOL(rb_prev);
462
463void rb_replace_node(struct rb_node *victim, struct rb_node *new,
464 struct rb_root *root)
465{
55a98102 466 struct rb_node *parent = rb_parent(victim);
1da177e4
LT
467
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)
55a98102 478 rb_set_parent(victim->rb_left, new);
1da177e4 479 if (victim->rb_right)
55a98102 480 rb_set_parent(victim->rb_right, new);
1da177e4
LT
481
482 /* Copy the pointers/colour from the victim to the replacement */
483 *new = *victim;
484}
485EXPORT_SYMBOL(rb_replace_node);