]> git.karo-electronics.de Git - karo-tx-linux.git/blob - lib/rbtree.c
rbtree: low level optimizations in __rb_erase_color()
[karo-tx-linux.git] / lib / rbtree.c
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>
24 #include <linux/export.h>
25
26 /*
27  * red-black trees properties:  http://en.wikipedia.org/wiki/Rbtree
28  *
29  *  1) A node is either red or black
30  *  2) The root is black
31  *  3) All leaves (NULL) are black
32  *  4) Both children of every red node are black
33  *  5) Every simple path from root to leaves contains the same number
34  *     of black nodes.
35  *
36  *  4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two
37  *  consecutive red nodes in a path and every red node is therefore followed by
38  *  a black. So if B is the number of black nodes on every simple path (as per
39  *  5), then the longest possible path due to 4 is 2B.
40  *
41  *  We shall indicate color with case, where black nodes are uppercase and red
42  *  nodes will be lowercase. Unknown color nodes shall be drawn as red within
43  *  parentheses and have some accompanying text comment.
44  */
45
46 #define RB_RED          0
47 #define RB_BLACK        1
48
49 #define rb_color(r)   ((r)->__rb_parent_color & 1)
50 #define rb_is_red(r)   (!rb_color(r))
51 #define rb_is_black(r) rb_color(r)
52
53 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
54 {
55         rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
56 }
57
58 static inline void rb_set_parent_color(struct rb_node *rb,
59                                        struct rb_node *p, int color)
60 {
61         rb->__rb_parent_color = (unsigned long)p | color;
62 }
63
64 static inline struct rb_node *rb_red_parent(struct rb_node *red)
65 {
66         return (struct rb_node *)red->__rb_parent_color;
67 }
68
69 /*
70  * Helper function for rotations:
71  * - old's parent and color get assigned to new
72  * - old gets assigned new as a parent and 'color' as a color.
73  */
74 static inline void
75 __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
76                         struct rb_root *root, int color)
77 {
78         struct rb_node *parent = rb_parent(old);
79         new->__rb_parent_color = old->__rb_parent_color;
80         rb_set_parent_color(old, new, color);
81         if (parent) {
82                 if (parent->rb_left == old)
83                         parent->rb_left = new;
84                 else
85                         parent->rb_right = new;
86         } else
87                 root->rb_node = new;
88 }
89
90 void rb_insert_color(struct rb_node *node, struct rb_root *root)
91 {
92         struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
93
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                 if (!parent) {
103                         rb_set_parent_color(node, NULL, RB_BLACK);
104                         break;
105                 } else if (rb_is_black(parent))
106                         break;
107
108                 gparent = rb_red_parent(parent);
109
110                 if (parent == gparent->rb_left) {
111                         tmp = gparent->rb_right;
112                         if (tmp && rb_is_red(tmp)) {
113                                 /*
114                                  * Case 1 - color flips
115                                  *
116                                  *       G            g
117                                  *      / \          / \
118                                  *     p   u  -->   P   U
119                                  *    /            /
120                                  *   n            N
121                                  *
122                                  * However, since g's parent might be red, and
123                                  * 4) does not allow this, we need to recurse
124                                  * at g.
125                                  */
126                                 rb_set_parent_color(tmp, gparent, RB_BLACK);
127                                 rb_set_parent_color(parent, gparent, RB_BLACK);
128                                 node = gparent;
129                                 parent = rb_parent(node);
130                                 rb_set_parent_color(node, parent, RB_RED);
131                                 continue;
132                         }
133
134                         if (parent->rb_right == node) {
135                                 /*
136                                  * Case 2 - left rotate at parent
137                                  *
138                                  *      G             G
139                                  *     / \           / \
140                                  *    p   U  -->    n   U
141                                  *     \           /
142                                  *      n         p
143                                  *
144                                  * This still leaves us in violation of 4), the
145                                  * continuation into Case 3 will fix that.
146                                  */
147                                 parent->rb_right = tmp = node->rb_left;
148                                 node->rb_left = parent;
149                                 if (tmp)
150                                         rb_set_parent_color(tmp, parent,
151                                                             RB_BLACK);
152                                 rb_set_parent_color(parent, node, RB_RED);
153                                 parent = node;
154                         }
155
156                         /*
157                          * Case 3 - right rotate at gparent
158                          *
159                          *        G           P
160                          *       / \         / \
161                          *      p   U  -->  n   g
162                          *     /                 \
163                          *    n                   U
164                          */
165                         gparent->rb_left = tmp = parent->rb_right;
166                         parent->rb_right = gparent;
167                         if (tmp)
168                                 rb_set_parent_color(tmp, gparent, RB_BLACK);
169                         __rb_rotate_set_parents(gparent, parent, root, RB_RED);
170                         break;
171                 } else {
172                         tmp = gparent->rb_left;
173                         if (tmp && rb_is_red(tmp)) {
174                                 /* Case 1 - color flips */
175                                 rb_set_parent_color(tmp, gparent, RB_BLACK);
176                                 rb_set_parent_color(parent, gparent, RB_BLACK);
177                                 node = gparent;
178                                 parent = rb_parent(node);
179                                 rb_set_parent_color(node, parent, RB_RED);
180                                 continue;
181                         }
182
183                         if (parent->rb_left == node) {
184                                 /* Case 2 - right rotate at parent */
185                                 parent->rb_left = tmp = node->rb_right;
186                                 node->rb_right = parent;
187                                 if (tmp)
188                                         rb_set_parent_color(tmp, parent,
189                                                             RB_BLACK);
190                                 rb_set_parent_color(parent, node, RB_RED);
191                                 parent = node;
192                         }
193
194                         /* Case 3 - left rotate at gparent */
195                         gparent->rb_right = tmp = parent->rb_left;
196                         parent->rb_left = gparent;
197                         if (tmp)
198                                 rb_set_parent_color(tmp, gparent, RB_BLACK);
199                         __rb_rotate_set_parents(gparent, parent, root, RB_RED);
200                         break;
201                 }
202         }
203 }
204 EXPORT_SYMBOL(rb_insert_color);
205
206 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
207                              struct rb_root *root)
208 {
209         struct rb_node *sibling, *tmp1, *tmp2;
210
211         while (true) {
212                 /*
213                  * Loop invariant: all leaf paths going through node have a
214                  * black node count that is 1 lower than other leaf paths.
215                  *
216                  * If node is red, we can flip it to black to adjust.
217                  * If node is the root, all leaf paths go through it.
218                  * Otherwise, we need to adjust the tree through color flips
219                  * and tree rotations as per one of the 4 cases below.
220                  */
221                 if (node && rb_is_red(node)) {
222                         rb_set_parent_color(node, parent, RB_BLACK);
223                         break;
224                 } else if (!parent) {
225                         break;
226                 } else if (parent->rb_left == node) {
227                         sibling = parent->rb_right;
228                         if (rb_is_red(sibling)) {
229                                 /*
230                                  * Case 1 - left rotate at parent
231                                  *
232                                  *     P               S
233                                  *    / \             / \
234                                  *   N   s    -->    p   Sr
235                                  *      / \         / \
236                                  *     Sl  Sr      N   Sl
237                                  */
238                                 parent->rb_right = tmp1 = sibling->rb_left;
239                                 sibling->rb_left = parent;
240                                 rb_set_parent_color(tmp1, parent, RB_BLACK);
241                                 __rb_rotate_set_parents(parent, sibling, root,
242                                                         RB_RED);
243                                 sibling = tmp1;
244                         }
245                         tmp1 = sibling->rb_right;
246                         if (!tmp1 || rb_is_black(tmp1)) {
247                                 tmp2 = sibling->rb_left;
248                                 if (!tmp2 || rb_is_black(tmp2)) {
249                                         /*
250                                          * Case 2 - sibling color flip
251                                          * (p could be either color here)
252                                          *
253                                          *    (p)           (p)
254                                          *    / \           / \
255                                          *   N   S    -->  N   s
256                                          *      / \           / \
257                                          *     Sl  Sr        Sl  Sr
258                                          *
259                                          * This leaves us violating 5), so
260                                          * recurse at p. If p is red, the
261                                          * recursion will just flip it to black
262                                          * and exit. If coming from Case 1,
263                                          * p is known to be red.
264                                          */
265                                         rb_set_parent_color(sibling, parent,
266                                                             RB_RED);
267                                         node = parent;
268                                         parent = rb_parent(node);
269                                         continue;
270                                 }
271                                 /*
272                                  * Case 3 - right rotate at sibling
273                                  * (p could be either color here)
274                                  *
275                                  *   (p)           (p)
276                                  *   / \           / \
277                                  *  N   S    -->  N   Sl
278                                  *     / \             \
279                                  *    sl  Sr            s
280                                  *                       \
281                                  *                        Sr
282                                  */
283                                 sibling->rb_left = tmp1 = tmp2->rb_right;
284                                 tmp2->rb_right = sibling;
285                                 parent->rb_right = tmp2;
286                                 if (tmp1)
287                                         rb_set_parent_color(tmp1, sibling,
288                                                             RB_BLACK);
289                                 tmp1 = sibling;
290                                 sibling = tmp2;
291                         }
292                         /*
293                          * Case 4 - left rotate at parent + color flips
294                          * (p and sl could be either color here.
295                          *  After rotation, p becomes black, s acquires
296                          *  p's color, and sl keeps its color)
297                          *
298                          *      (p)             (s)
299                          *      / \             / \
300                          *     N   S     -->   P   Sr
301                          *        / \         / \
302                          *      (sl) sr      N  (sl)
303                          */
304                         parent->rb_right = tmp2 = sibling->rb_left;
305                         sibling->rb_left = parent;
306                         rb_set_parent_color(tmp1, sibling, RB_BLACK);
307                         if (tmp2)
308                                 rb_set_parent(tmp2, parent);
309                         __rb_rotate_set_parents(parent, sibling, root,
310                                                 RB_BLACK);
311                         break;
312                 } else {
313                         sibling = parent->rb_left;
314                         if (rb_is_red(sibling)) {
315                                 /* Case 1 - right rotate at parent */
316                                 parent->rb_left = tmp1 = sibling->rb_right;
317                                 sibling->rb_right = parent;
318                                 rb_set_parent_color(tmp1, parent, RB_BLACK);
319                                 __rb_rotate_set_parents(parent, sibling, root,
320                                                         RB_RED);
321                                 sibling = tmp1;
322                         }
323                         tmp1 = sibling->rb_left;
324                         if (!tmp1 || rb_is_black(tmp1)) {
325                                 tmp2 = sibling->rb_right;
326                                 if (!tmp2 || rb_is_black(tmp2)) {
327                                         /* Case 2 - sibling color flip */
328                                         rb_set_parent_color(sibling, parent,
329                                                             RB_RED);
330                                         node = parent;
331                                         parent = rb_parent(node);
332                                         continue;
333                                 }
334                                 /* Case 3 - right rotate at sibling */
335                                 sibling->rb_right = tmp1 = tmp2->rb_left;
336                                 tmp2->rb_left = sibling;
337                                 parent->rb_left = tmp2;
338                                 if (tmp1)
339                                         rb_set_parent_color(tmp1, sibling,
340                                                             RB_BLACK);
341                                 tmp1 = sibling;
342                                 sibling = tmp2;
343                         }
344                         /* Case 4 - left rotate at parent + color flips */
345                         parent->rb_left = tmp2 = sibling->rb_right;
346                         sibling->rb_right = parent;
347                         rb_set_parent_color(tmp1, sibling, RB_BLACK);
348                         if (tmp2)
349                                 rb_set_parent(tmp2, parent);
350                         __rb_rotate_set_parents(parent, sibling, root,
351                                                 RB_BLACK);
352                         break;
353                 }
354         }
355 }
356
357 void rb_erase(struct rb_node *node, struct rb_root *root)
358 {
359         struct rb_node *child, *parent;
360         int color;
361
362         if (!node->rb_left)
363                 child = node->rb_right;
364         else if (!node->rb_right)
365                 child = node->rb_left;
366         else
367         {
368                 struct rb_node *old = node, *left;
369
370                 node = node->rb_right;
371                 while ((left = node->rb_left) != NULL)
372                         node = left;
373
374                 if (rb_parent(old)) {
375                         if (rb_parent(old)->rb_left == old)
376                                 rb_parent(old)->rb_left = node;
377                         else
378                                 rb_parent(old)->rb_right = node;
379                 } else
380                         root->rb_node = node;
381
382                 child = node->rb_right;
383                 parent = rb_parent(node);
384                 color = rb_color(node);
385
386                 if (parent == old) {
387                         parent = node;
388                 } else {
389                         if (child)
390                                 rb_set_parent(child, parent);
391                         parent->rb_left = child;
392
393                         node->rb_right = old->rb_right;
394                         rb_set_parent(old->rb_right, node);
395                 }
396
397                 node->__rb_parent_color = old->__rb_parent_color;
398                 node->rb_left = old->rb_left;
399                 rb_set_parent(old->rb_left, node);
400
401                 goto color;
402         }
403
404         parent = rb_parent(node);
405         color = rb_color(node);
406
407         if (child)
408                 rb_set_parent(child, parent);
409         if (parent)
410         {
411                 if (parent->rb_left == node)
412                         parent->rb_left = child;
413                 else
414                         parent->rb_right = child;
415         }
416         else
417                 root->rb_node = child;
418
419  color:
420         if (color == RB_BLACK)
421                 __rb_erase_color(child, parent, root);
422 }
423 EXPORT_SYMBOL(rb_erase);
424
425 static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
426 {
427         struct rb_node *parent;
428
429 up:
430         func(node, data);
431         parent = rb_parent(node);
432         if (!parent)
433                 return;
434
435         if (node == parent->rb_left && parent->rb_right)
436                 func(parent->rb_right, data);
437         else if (parent->rb_left)
438                 func(parent->rb_left, data);
439
440         node = parent;
441         goto up;
442 }
443
444 /*
445  * after inserting @node into the tree, update the tree to account for
446  * both the new entry and any damage done by rebalance
447  */
448 void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
449 {
450         if (node->rb_left)
451                 node = node->rb_left;
452         else if (node->rb_right)
453                 node = node->rb_right;
454
455         rb_augment_path(node, func, data);
456 }
457 EXPORT_SYMBOL(rb_augment_insert);
458
459 /*
460  * before removing the node, find the deepest node on the rebalance path
461  * that will still be there after @node gets removed
462  */
463 struct rb_node *rb_augment_erase_begin(struct rb_node *node)
464 {
465         struct rb_node *deepest;
466
467         if (!node->rb_right && !node->rb_left)
468                 deepest = rb_parent(node);
469         else if (!node->rb_right)
470                 deepest = node->rb_left;
471         else if (!node->rb_left)
472                 deepest = node->rb_right;
473         else {
474                 deepest = rb_next(node);
475                 if (deepest->rb_right)
476                         deepest = deepest->rb_right;
477                 else if (rb_parent(deepest) != node)
478                         deepest = rb_parent(deepest);
479         }
480
481         return deepest;
482 }
483 EXPORT_SYMBOL(rb_augment_erase_begin);
484
485 /*
486  * after removal, update the tree to account for the removed entry
487  * and any rebalance damage.
488  */
489 void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
490 {
491         if (node)
492                 rb_augment_path(node, func, data);
493 }
494 EXPORT_SYMBOL(rb_augment_erase_end);
495
496 /*
497  * This function returns the first node (in sort order) of the tree.
498  */
499 struct rb_node *rb_first(const struct rb_root *root)
500 {
501         struct rb_node  *n;
502
503         n = root->rb_node;
504         if (!n)
505                 return NULL;
506         while (n->rb_left)
507                 n = n->rb_left;
508         return n;
509 }
510 EXPORT_SYMBOL(rb_first);
511
512 struct rb_node *rb_last(const struct rb_root *root)
513 {
514         struct rb_node  *n;
515
516         n = root->rb_node;
517         if (!n)
518                 return NULL;
519         while (n->rb_right)
520                 n = n->rb_right;
521         return n;
522 }
523 EXPORT_SYMBOL(rb_last);
524
525 struct rb_node *rb_next(const struct rb_node *node)
526 {
527         struct rb_node *parent;
528
529         if (RB_EMPTY_NODE(node))
530                 return NULL;
531
532         /* If we have a right-hand child, go down and then left as far
533            as we can. */
534         if (node->rb_right) {
535                 node = node->rb_right; 
536                 while (node->rb_left)
537                         node=node->rb_left;
538                 return (struct rb_node *)node;
539         }
540
541         /* No right-hand children.  Everything down and left is
542            smaller than us, so any 'next' node must be in the general
543            direction of our parent. Go up the tree; any time the
544            ancestor is a right-hand child of its parent, keep going
545            up. First time it's a left-hand child of its parent, said
546            parent is our 'next' node. */
547         while ((parent = rb_parent(node)) && node == parent->rb_right)
548                 node = parent;
549
550         return parent;
551 }
552 EXPORT_SYMBOL(rb_next);
553
554 struct rb_node *rb_prev(const struct rb_node *node)
555 {
556         struct rb_node *parent;
557
558         if (RB_EMPTY_NODE(node))
559                 return NULL;
560
561         /* If we have a left-hand child, go down and then right as far
562            as we can. */
563         if (node->rb_left) {
564                 node = node->rb_left; 
565                 while (node->rb_right)
566                         node=node->rb_right;
567                 return (struct rb_node *)node;
568         }
569
570         /* No left-hand children. Go up till we find an ancestor which
571            is a right-hand child of its parent */
572         while ((parent = rb_parent(node)) && node == parent->rb_left)
573                 node = parent;
574
575         return parent;
576 }
577 EXPORT_SYMBOL(rb_prev);
578
579 void rb_replace_node(struct rb_node *victim, struct rb_node *new,
580                      struct rb_root *root)
581 {
582         struct rb_node *parent = rb_parent(victim);
583
584         /* Set the surrounding nodes to point to the replacement */
585         if (parent) {
586                 if (victim == parent->rb_left)
587                         parent->rb_left = new;
588                 else
589                         parent->rb_right = new;
590         } else {
591                 root->rb_node = new;
592         }
593         if (victim->rb_left)
594                 rb_set_parent(victim->rb_left, new);
595         if (victim->rb_right)
596                 rb_set_parent(victim->rb_right, new);
597
598         /* Copy the pointers/colour from the victim to the replacement */
599         *new = *victim;
600 }
601 EXPORT_SYMBOL(rb_replace_node);