13f735377SArnaldo Carvalho de Melo /* 23f735377SArnaldo Carvalho de Melo Red Black Trees 33f735377SArnaldo Carvalho de Melo (C) 1999 Andrea Arcangeli <andrea@suse.de> 43f735377SArnaldo Carvalho de Melo (C) 2002 David Woodhouse <dwmw2@infradead.org> 53f735377SArnaldo Carvalho de Melo (C) 2012 Michel Lespinasse <walken@google.com> 63f735377SArnaldo Carvalho de Melo 73f735377SArnaldo Carvalho de Melo This program is free software; you can redistribute it and/or modify 83f735377SArnaldo Carvalho de Melo it under the terms of the GNU General Public License as published by 93f735377SArnaldo Carvalho de Melo the Free Software Foundation; either version 2 of the License, or 103f735377SArnaldo Carvalho de Melo (at your option) any later version. 113f735377SArnaldo Carvalho de Melo 123f735377SArnaldo Carvalho de Melo This program is distributed in the hope that it will be useful, 133f735377SArnaldo Carvalho de Melo but WITHOUT ANY WARRANTY; without even the implied warranty of 143f735377SArnaldo Carvalho de Melo MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 153f735377SArnaldo Carvalho de Melo GNU General Public License for more details. 163f735377SArnaldo Carvalho de Melo 173f735377SArnaldo Carvalho de Melo You should have received a copy of the GNU General Public License 183f735377SArnaldo Carvalho de Melo along with this program; if not, write to the Free Software 193f735377SArnaldo Carvalho de Melo Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 203f735377SArnaldo Carvalho de Melo 213f735377SArnaldo Carvalho de Melo linux/lib/rbtree.c 223f735377SArnaldo Carvalho de Melo */ 233f735377SArnaldo Carvalho de Melo 243f735377SArnaldo Carvalho de Melo #include <linux/rbtree_augmented.h> 25*3aef2cadSDavidlohr Bueso #include <linux/export.h> 263f735377SArnaldo Carvalho de Melo 273f735377SArnaldo Carvalho de Melo /* 283f735377SArnaldo Carvalho de Melo * red-black trees properties: http://en.wikipedia.org/wiki/Rbtree 293f735377SArnaldo Carvalho de Melo * 303f735377SArnaldo Carvalho de Melo * 1) A node is either red or black 313f735377SArnaldo Carvalho de Melo * 2) The root is black 323f735377SArnaldo Carvalho de Melo * 3) All leaves (NULL) are black 333f735377SArnaldo Carvalho de Melo * 4) Both children of every red node are black 343f735377SArnaldo Carvalho de Melo * 5) Every simple path from root to leaves contains the same number 353f735377SArnaldo Carvalho de Melo * of black nodes. 363f735377SArnaldo Carvalho de Melo * 373f735377SArnaldo Carvalho de Melo * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two 383f735377SArnaldo Carvalho de Melo * consecutive red nodes in a path and every red node is therefore followed by 393f735377SArnaldo Carvalho de Melo * a black. So if B is the number of black nodes on every simple path (as per 403f735377SArnaldo Carvalho de Melo * 5), then the longest possible path due to 4 is 2B. 413f735377SArnaldo Carvalho de Melo * 423f735377SArnaldo Carvalho de Melo * We shall indicate color with case, where black nodes are uppercase and red 433f735377SArnaldo Carvalho de Melo * nodes will be lowercase. Unknown color nodes shall be drawn as red within 443f735377SArnaldo Carvalho de Melo * parentheses and have some accompanying text comment. 453f735377SArnaldo Carvalho de Melo */ 463f735377SArnaldo Carvalho de Melo 47*3aef2cadSDavidlohr Bueso /* 48*3aef2cadSDavidlohr Bueso * Notes on lockless lookups: 49*3aef2cadSDavidlohr Bueso * 50*3aef2cadSDavidlohr Bueso * All stores to the tree structure (rb_left and rb_right) must be done using 51*3aef2cadSDavidlohr Bueso * WRITE_ONCE(). And we must not inadvertently cause (temporary) loops in the 52*3aef2cadSDavidlohr Bueso * tree structure as seen in program order. 53*3aef2cadSDavidlohr Bueso * 54*3aef2cadSDavidlohr Bueso * These two requirements will allow lockless iteration of the tree -- not 55*3aef2cadSDavidlohr Bueso * correct iteration mind you, tree rotations are not atomic so a lookup might 56*3aef2cadSDavidlohr Bueso * miss entire subtrees. 57*3aef2cadSDavidlohr Bueso * 58*3aef2cadSDavidlohr Bueso * But they do guarantee that any such traversal will only see valid elements 59*3aef2cadSDavidlohr Bueso * and that it will indeed complete -- does not get stuck in a loop. 60*3aef2cadSDavidlohr Bueso * 61*3aef2cadSDavidlohr Bueso * It also guarantees that if the lookup returns an element it is the 'correct' 62*3aef2cadSDavidlohr Bueso * one. But not returning an element does _NOT_ mean it's not present. 63*3aef2cadSDavidlohr Bueso * 64*3aef2cadSDavidlohr Bueso * NOTE: 65*3aef2cadSDavidlohr Bueso * 66*3aef2cadSDavidlohr Bueso * Stores to __rb_parent_color are not important for simple lookups so those 67*3aef2cadSDavidlohr Bueso * are left undone as of now. Nor did I check for loops involving parent 68*3aef2cadSDavidlohr Bueso * pointers. 69*3aef2cadSDavidlohr Bueso */ 70*3aef2cadSDavidlohr Bueso 713f735377SArnaldo Carvalho de Melo static inline void rb_set_black(struct rb_node *rb) 723f735377SArnaldo Carvalho de Melo { 733f735377SArnaldo Carvalho de Melo rb->__rb_parent_color |= RB_BLACK; 743f735377SArnaldo Carvalho de Melo } 753f735377SArnaldo Carvalho de Melo 763f735377SArnaldo Carvalho de Melo static inline struct rb_node *rb_red_parent(struct rb_node *red) 773f735377SArnaldo Carvalho de Melo { 783f735377SArnaldo Carvalho de Melo return (struct rb_node *)red->__rb_parent_color; 793f735377SArnaldo Carvalho de Melo } 803f735377SArnaldo Carvalho de Melo 813f735377SArnaldo Carvalho de Melo /* 823f735377SArnaldo Carvalho de Melo * Helper function for rotations: 833f735377SArnaldo Carvalho de Melo * - old's parent and color get assigned to new 843f735377SArnaldo Carvalho de Melo * - old gets assigned new as a parent and 'color' as a color. 853f735377SArnaldo Carvalho de Melo */ 863f735377SArnaldo Carvalho de Melo static inline void 873f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, 883f735377SArnaldo Carvalho de Melo struct rb_root *root, int color) 893f735377SArnaldo Carvalho de Melo { 903f735377SArnaldo Carvalho de Melo struct rb_node *parent = rb_parent(old); 913f735377SArnaldo Carvalho de Melo new->__rb_parent_color = old->__rb_parent_color; 923f735377SArnaldo Carvalho de Melo rb_set_parent_color(old, new, color); 933f735377SArnaldo Carvalho de Melo __rb_change_child(old, new, parent, root); 943f735377SArnaldo Carvalho de Melo } 953f735377SArnaldo Carvalho de Melo 963f735377SArnaldo Carvalho de Melo static __always_inline void 973f735377SArnaldo Carvalho de Melo __rb_insert(struct rb_node *node, struct rb_root *root, 98*3aef2cadSDavidlohr Bueso bool newleft, struct rb_node **leftmost, 993f735377SArnaldo Carvalho de Melo void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 1003f735377SArnaldo Carvalho de Melo { 1013f735377SArnaldo Carvalho de Melo struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; 1023f735377SArnaldo Carvalho de Melo 103*3aef2cadSDavidlohr Bueso if (newleft) 104*3aef2cadSDavidlohr Bueso *leftmost = node; 105*3aef2cadSDavidlohr Bueso 1063f735377SArnaldo Carvalho de Melo while (true) { 1073f735377SArnaldo Carvalho de Melo /* 108*3aef2cadSDavidlohr Bueso * Loop invariant: node is red. 1093f735377SArnaldo Carvalho de Melo */ 110*3aef2cadSDavidlohr Bueso if (unlikely(!parent)) { 111*3aef2cadSDavidlohr Bueso /* 112*3aef2cadSDavidlohr Bueso * The inserted node is root. Either this is the 113*3aef2cadSDavidlohr Bueso * first node, or we recursed at Case 1 below and 114*3aef2cadSDavidlohr Bueso * are no longer violating 4). 115*3aef2cadSDavidlohr Bueso */ 1163f735377SArnaldo Carvalho de Melo rb_set_parent_color(node, NULL, RB_BLACK); 1173f735377SArnaldo Carvalho de Melo break; 118*3aef2cadSDavidlohr Bueso } 119*3aef2cadSDavidlohr Bueso 120*3aef2cadSDavidlohr Bueso /* 121*3aef2cadSDavidlohr Bueso * If there is a black parent, we are done. 122*3aef2cadSDavidlohr Bueso * Otherwise, take some corrective action as, 123*3aef2cadSDavidlohr Bueso * per 4), we don't want a red root or two 124*3aef2cadSDavidlohr Bueso * consecutive red nodes. 125*3aef2cadSDavidlohr Bueso */ 126*3aef2cadSDavidlohr Bueso if(rb_is_black(parent)) 1273f735377SArnaldo Carvalho de Melo break; 1283f735377SArnaldo Carvalho de Melo 1293f735377SArnaldo Carvalho de Melo gparent = rb_red_parent(parent); 1303f735377SArnaldo Carvalho de Melo 1313f735377SArnaldo Carvalho de Melo tmp = gparent->rb_right; 1323f735377SArnaldo Carvalho de Melo if (parent != tmp) { /* parent == gparent->rb_left */ 1333f735377SArnaldo Carvalho de Melo if (tmp && rb_is_red(tmp)) { 1343f735377SArnaldo Carvalho de Melo /* 135*3aef2cadSDavidlohr Bueso * Case 1 - node's uncle is red (color flips). 1363f735377SArnaldo Carvalho de Melo * 1373f735377SArnaldo Carvalho de Melo * G g 1383f735377SArnaldo Carvalho de Melo * / \ / \ 1393f735377SArnaldo Carvalho de Melo * p u --> P U 1403f735377SArnaldo Carvalho de Melo * / / 1413f735377SArnaldo Carvalho de Melo * n n 1423f735377SArnaldo Carvalho de Melo * 1433f735377SArnaldo Carvalho de Melo * However, since g's parent might be red, and 1443f735377SArnaldo Carvalho de Melo * 4) does not allow this, we need to recurse 1453f735377SArnaldo Carvalho de Melo * at g. 1463f735377SArnaldo Carvalho de Melo */ 1473f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, gparent, RB_BLACK); 1483f735377SArnaldo Carvalho de Melo rb_set_parent_color(parent, gparent, RB_BLACK); 1493f735377SArnaldo Carvalho de Melo node = gparent; 1503f735377SArnaldo Carvalho de Melo parent = rb_parent(node); 1513f735377SArnaldo Carvalho de Melo rb_set_parent_color(node, parent, RB_RED); 1523f735377SArnaldo Carvalho de Melo continue; 1533f735377SArnaldo Carvalho de Melo } 1543f735377SArnaldo Carvalho de Melo 1553f735377SArnaldo Carvalho de Melo tmp = parent->rb_right; 1563f735377SArnaldo Carvalho de Melo if (node == tmp) { 1573f735377SArnaldo Carvalho de Melo /* 158*3aef2cadSDavidlohr Bueso * Case 2 - node's uncle is black and node is 159*3aef2cadSDavidlohr Bueso * the parent's right child (left rotate at parent). 1603f735377SArnaldo Carvalho de Melo * 1613f735377SArnaldo Carvalho de Melo * G G 1623f735377SArnaldo Carvalho de Melo * / \ / \ 1633f735377SArnaldo Carvalho de Melo * p U --> n U 1643f735377SArnaldo Carvalho de Melo * \ / 1653f735377SArnaldo Carvalho de Melo * n p 1663f735377SArnaldo Carvalho de Melo * 1673f735377SArnaldo Carvalho de Melo * This still leaves us in violation of 4), the 1683f735377SArnaldo Carvalho de Melo * continuation into Case 3 will fix that. 1693f735377SArnaldo Carvalho de Melo */ 170*3aef2cadSDavidlohr Bueso tmp = node->rb_left; 171*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_right, tmp); 172*3aef2cadSDavidlohr Bueso WRITE_ONCE(node->rb_left, parent); 1733f735377SArnaldo Carvalho de Melo if (tmp) 1743f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, parent, 1753f735377SArnaldo Carvalho de Melo RB_BLACK); 1763f735377SArnaldo Carvalho de Melo rb_set_parent_color(parent, node, RB_RED); 1773f735377SArnaldo Carvalho de Melo augment_rotate(parent, node); 1783f735377SArnaldo Carvalho de Melo parent = node; 1793f735377SArnaldo Carvalho de Melo tmp = node->rb_right; 1803f735377SArnaldo Carvalho de Melo } 1813f735377SArnaldo Carvalho de Melo 1823f735377SArnaldo Carvalho de Melo /* 183*3aef2cadSDavidlohr Bueso * Case 3 - node's uncle is black and node is 184*3aef2cadSDavidlohr Bueso * the parent's left child (right rotate at gparent). 1853f735377SArnaldo Carvalho de Melo * 1863f735377SArnaldo Carvalho de Melo * G P 1873f735377SArnaldo Carvalho de Melo * / \ / \ 1883f735377SArnaldo Carvalho de Melo * p U --> n g 1893f735377SArnaldo Carvalho de Melo * / \ 1903f735377SArnaldo Carvalho de Melo * n U 1913f735377SArnaldo Carvalho de Melo */ 192*3aef2cadSDavidlohr Bueso WRITE_ONCE(gparent->rb_left, tmp); /* == parent->rb_right */ 193*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_right, gparent); 1943f735377SArnaldo Carvalho de Melo if (tmp) 1953f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, gparent, RB_BLACK); 1963f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(gparent, parent, root, RB_RED); 1973f735377SArnaldo Carvalho de Melo augment_rotate(gparent, parent); 1983f735377SArnaldo Carvalho de Melo break; 1993f735377SArnaldo Carvalho de Melo } else { 2003f735377SArnaldo Carvalho de Melo tmp = gparent->rb_left; 2013f735377SArnaldo Carvalho de Melo if (tmp && rb_is_red(tmp)) { 2023f735377SArnaldo Carvalho de Melo /* Case 1 - color flips */ 2033f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, gparent, RB_BLACK); 2043f735377SArnaldo Carvalho de Melo rb_set_parent_color(parent, gparent, RB_BLACK); 2053f735377SArnaldo Carvalho de Melo node = gparent; 2063f735377SArnaldo Carvalho de Melo parent = rb_parent(node); 2073f735377SArnaldo Carvalho de Melo rb_set_parent_color(node, parent, RB_RED); 2083f735377SArnaldo Carvalho de Melo continue; 2093f735377SArnaldo Carvalho de Melo } 2103f735377SArnaldo Carvalho de Melo 2113f735377SArnaldo Carvalho de Melo tmp = parent->rb_left; 2123f735377SArnaldo Carvalho de Melo if (node == tmp) { 2133f735377SArnaldo Carvalho de Melo /* Case 2 - right rotate at parent */ 214*3aef2cadSDavidlohr Bueso tmp = node->rb_right; 215*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_left, tmp); 216*3aef2cadSDavidlohr Bueso WRITE_ONCE(node->rb_right, parent); 2173f735377SArnaldo Carvalho de Melo if (tmp) 2183f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, parent, 2193f735377SArnaldo Carvalho de Melo RB_BLACK); 2203f735377SArnaldo Carvalho de Melo rb_set_parent_color(parent, node, RB_RED); 2213f735377SArnaldo Carvalho de Melo augment_rotate(parent, node); 2223f735377SArnaldo Carvalho de Melo parent = node; 2233f735377SArnaldo Carvalho de Melo tmp = node->rb_left; 2243f735377SArnaldo Carvalho de Melo } 2253f735377SArnaldo Carvalho de Melo 2263f735377SArnaldo Carvalho de Melo /* Case 3 - left rotate at gparent */ 227*3aef2cadSDavidlohr Bueso WRITE_ONCE(gparent->rb_right, tmp); /* == parent->rb_left */ 228*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_left, gparent); 2293f735377SArnaldo Carvalho de Melo if (tmp) 2303f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp, gparent, RB_BLACK); 2313f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(gparent, parent, root, RB_RED); 2323f735377SArnaldo Carvalho de Melo augment_rotate(gparent, parent); 2333f735377SArnaldo Carvalho de Melo break; 2343f735377SArnaldo Carvalho de Melo } 2353f735377SArnaldo Carvalho de Melo } 2363f735377SArnaldo Carvalho de Melo } 2373f735377SArnaldo Carvalho de Melo 2383f735377SArnaldo Carvalho de Melo /* 2393f735377SArnaldo Carvalho de Melo * Inline version for rb_erase() use - we want to be able to inline 2403f735377SArnaldo Carvalho de Melo * and eliminate the dummy_rotate callback there 2413f735377SArnaldo Carvalho de Melo */ 2423f735377SArnaldo Carvalho de Melo static __always_inline void 2433f735377SArnaldo Carvalho de Melo ____rb_erase_color(struct rb_node *parent, struct rb_root *root, 2443f735377SArnaldo Carvalho de Melo void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 2453f735377SArnaldo Carvalho de Melo { 2463f735377SArnaldo Carvalho de Melo struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; 2473f735377SArnaldo Carvalho de Melo 2483f735377SArnaldo Carvalho de Melo while (true) { 2493f735377SArnaldo Carvalho de Melo /* 2503f735377SArnaldo Carvalho de Melo * Loop invariants: 2513f735377SArnaldo Carvalho de Melo * - node is black (or NULL on first iteration) 2523f735377SArnaldo Carvalho de Melo * - node is not the root (parent is not NULL) 2533f735377SArnaldo Carvalho de Melo * - All leaf paths going through parent and node have a 2543f735377SArnaldo Carvalho de Melo * black node count that is 1 lower than other leaf paths. 2553f735377SArnaldo Carvalho de Melo */ 2563f735377SArnaldo Carvalho de Melo sibling = parent->rb_right; 2573f735377SArnaldo Carvalho de Melo if (node != sibling) { /* node == parent->rb_left */ 2583f735377SArnaldo Carvalho de Melo if (rb_is_red(sibling)) { 2593f735377SArnaldo Carvalho de Melo /* 2603f735377SArnaldo Carvalho de Melo * Case 1 - left rotate at parent 2613f735377SArnaldo Carvalho de Melo * 2623f735377SArnaldo Carvalho de Melo * P S 2633f735377SArnaldo Carvalho de Melo * / \ / \ 2643f735377SArnaldo Carvalho de Melo * N s --> p Sr 2653f735377SArnaldo Carvalho de Melo * / \ / \ 2663f735377SArnaldo Carvalho de Melo * Sl Sr N Sl 2673f735377SArnaldo Carvalho de Melo */ 268*3aef2cadSDavidlohr Bueso tmp1 = sibling->rb_left; 269*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_right, tmp1); 270*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_left, parent); 2713f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, parent, RB_BLACK); 2723f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(parent, sibling, root, 2733f735377SArnaldo Carvalho de Melo RB_RED); 2743f735377SArnaldo Carvalho de Melo augment_rotate(parent, sibling); 2753f735377SArnaldo Carvalho de Melo sibling = tmp1; 2763f735377SArnaldo Carvalho de Melo } 2773f735377SArnaldo Carvalho de Melo tmp1 = sibling->rb_right; 2783f735377SArnaldo Carvalho de Melo if (!tmp1 || rb_is_black(tmp1)) { 2793f735377SArnaldo Carvalho de Melo tmp2 = sibling->rb_left; 2803f735377SArnaldo Carvalho de Melo if (!tmp2 || rb_is_black(tmp2)) { 2813f735377SArnaldo Carvalho de Melo /* 2823f735377SArnaldo Carvalho de Melo * Case 2 - sibling color flip 2833f735377SArnaldo Carvalho de Melo * (p could be either color here) 2843f735377SArnaldo Carvalho de Melo * 2853f735377SArnaldo Carvalho de Melo * (p) (p) 2863f735377SArnaldo Carvalho de Melo * / \ / \ 2873f735377SArnaldo Carvalho de Melo * N S --> N s 2883f735377SArnaldo Carvalho de Melo * / \ / \ 2893f735377SArnaldo Carvalho de Melo * Sl Sr Sl Sr 2903f735377SArnaldo Carvalho de Melo * 2913f735377SArnaldo Carvalho de Melo * This leaves us violating 5) which 2923f735377SArnaldo Carvalho de Melo * can be fixed by flipping p to black 2933f735377SArnaldo Carvalho de Melo * if it was red, or by recursing at p. 2943f735377SArnaldo Carvalho de Melo * p is red when coming from Case 1. 2953f735377SArnaldo Carvalho de Melo */ 2963f735377SArnaldo Carvalho de Melo rb_set_parent_color(sibling, parent, 2973f735377SArnaldo Carvalho de Melo RB_RED); 2983f735377SArnaldo Carvalho de Melo if (rb_is_red(parent)) 2993f735377SArnaldo Carvalho de Melo rb_set_black(parent); 3003f735377SArnaldo Carvalho de Melo else { 3013f735377SArnaldo Carvalho de Melo node = parent; 3023f735377SArnaldo Carvalho de Melo parent = rb_parent(node); 3033f735377SArnaldo Carvalho de Melo if (parent) 3043f735377SArnaldo Carvalho de Melo continue; 3053f735377SArnaldo Carvalho de Melo } 3063f735377SArnaldo Carvalho de Melo break; 3073f735377SArnaldo Carvalho de Melo } 3083f735377SArnaldo Carvalho de Melo /* 3093f735377SArnaldo Carvalho de Melo * Case 3 - right rotate at sibling 3103f735377SArnaldo Carvalho de Melo * (p could be either color here) 3113f735377SArnaldo Carvalho de Melo * 3123f735377SArnaldo Carvalho de Melo * (p) (p) 3133f735377SArnaldo Carvalho de Melo * / \ / \ 314*3aef2cadSDavidlohr Bueso * N S --> N sl 3153f735377SArnaldo Carvalho de Melo * / \ \ 316*3aef2cadSDavidlohr Bueso * sl Sr S 317*3aef2cadSDavidlohr Bueso * \ 318*3aef2cadSDavidlohr Bueso * Sr 319*3aef2cadSDavidlohr Bueso * 320*3aef2cadSDavidlohr Bueso * Note: p might be red, and then both 321*3aef2cadSDavidlohr Bueso * p and sl are red after rotation(which 322*3aef2cadSDavidlohr Bueso * breaks property 4). This is fixed in 323*3aef2cadSDavidlohr Bueso * Case 4 (in __rb_rotate_set_parents() 324*3aef2cadSDavidlohr Bueso * which set sl the color of p 325*3aef2cadSDavidlohr Bueso * and set p RB_BLACK) 326*3aef2cadSDavidlohr Bueso * 327*3aef2cadSDavidlohr Bueso * (p) (sl) 328*3aef2cadSDavidlohr Bueso * / \ / \ 329*3aef2cadSDavidlohr Bueso * N sl --> P S 330*3aef2cadSDavidlohr Bueso * \ / \ 331*3aef2cadSDavidlohr Bueso * S N Sr 3323f735377SArnaldo Carvalho de Melo * \ 3333f735377SArnaldo Carvalho de Melo * Sr 3343f735377SArnaldo Carvalho de Melo */ 335*3aef2cadSDavidlohr Bueso tmp1 = tmp2->rb_right; 336*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_left, tmp1); 337*3aef2cadSDavidlohr Bueso WRITE_ONCE(tmp2->rb_right, sibling); 338*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_right, tmp2); 3393f735377SArnaldo Carvalho de Melo if (tmp1) 3403f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, sibling, 3413f735377SArnaldo Carvalho de Melo RB_BLACK); 3423f735377SArnaldo Carvalho de Melo augment_rotate(sibling, tmp2); 3433f735377SArnaldo Carvalho de Melo tmp1 = sibling; 3443f735377SArnaldo Carvalho de Melo sibling = tmp2; 3453f735377SArnaldo Carvalho de Melo } 3463f735377SArnaldo Carvalho de Melo /* 3473f735377SArnaldo Carvalho de Melo * Case 4 - left rotate at parent + color flips 3483f735377SArnaldo Carvalho de Melo * (p and sl could be either color here. 3493f735377SArnaldo Carvalho de Melo * After rotation, p becomes black, s acquires 3503f735377SArnaldo Carvalho de Melo * p's color, and sl keeps its color) 3513f735377SArnaldo Carvalho de Melo * 3523f735377SArnaldo Carvalho de Melo * (p) (s) 3533f735377SArnaldo Carvalho de Melo * / \ / \ 3543f735377SArnaldo Carvalho de Melo * N S --> P Sr 3553f735377SArnaldo Carvalho de Melo * / \ / \ 3563f735377SArnaldo Carvalho de Melo * (sl) sr N (sl) 3573f735377SArnaldo Carvalho de Melo */ 358*3aef2cadSDavidlohr Bueso tmp2 = sibling->rb_left; 359*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_right, tmp2); 360*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_left, parent); 3613f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, sibling, RB_BLACK); 3623f735377SArnaldo Carvalho de Melo if (tmp2) 3633f735377SArnaldo Carvalho de Melo rb_set_parent(tmp2, parent); 3643f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(parent, sibling, root, 3653f735377SArnaldo Carvalho de Melo RB_BLACK); 3663f735377SArnaldo Carvalho de Melo augment_rotate(parent, sibling); 3673f735377SArnaldo Carvalho de Melo break; 3683f735377SArnaldo Carvalho de Melo } else { 3693f735377SArnaldo Carvalho de Melo sibling = parent->rb_left; 3703f735377SArnaldo Carvalho de Melo if (rb_is_red(sibling)) { 3713f735377SArnaldo Carvalho de Melo /* Case 1 - right rotate at parent */ 372*3aef2cadSDavidlohr Bueso tmp1 = sibling->rb_right; 373*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_left, tmp1); 374*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_right, parent); 3753f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, parent, RB_BLACK); 3763f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(parent, sibling, root, 3773f735377SArnaldo Carvalho de Melo RB_RED); 3783f735377SArnaldo Carvalho de Melo augment_rotate(parent, sibling); 3793f735377SArnaldo Carvalho de Melo sibling = tmp1; 3803f735377SArnaldo Carvalho de Melo } 3813f735377SArnaldo Carvalho de Melo tmp1 = sibling->rb_left; 3823f735377SArnaldo Carvalho de Melo if (!tmp1 || rb_is_black(tmp1)) { 3833f735377SArnaldo Carvalho de Melo tmp2 = sibling->rb_right; 3843f735377SArnaldo Carvalho de Melo if (!tmp2 || rb_is_black(tmp2)) { 3853f735377SArnaldo Carvalho de Melo /* Case 2 - sibling color flip */ 3863f735377SArnaldo Carvalho de Melo rb_set_parent_color(sibling, parent, 3873f735377SArnaldo Carvalho de Melo RB_RED); 3883f735377SArnaldo Carvalho de Melo if (rb_is_red(parent)) 3893f735377SArnaldo Carvalho de Melo rb_set_black(parent); 3903f735377SArnaldo Carvalho de Melo else { 3913f735377SArnaldo Carvalho de Melo node = parent; 3923f735377SArnaldo Carvalho de Melo parent = rb_parent(node); 3933f735377SArnaldo Carvalho de Melo if (parent) 3943f735377SArnaldo Carvalho de Melo continue; 3953f735377SArnaldo Carvalho de Melo } 3963f735377SArnaldo Carvalho de Melo break; 3973f735377SArnaldo Carvalho de Melo } 398*3aef2cadSDavidlohr Bueso /* Case 3 - left rotate at sibling */ 399*3aef2cadSDavidlohr Bueso tmp1 = tmp2->rb_left; 400*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_right, tmp1); 401*3aef2cadSDavidlohr Bueso WRITE_ONCE(tmp2->rb_left, sibling); 402*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_left, tmp2); 4033f735377SArnaldo Carvalho de Melo if (tmp1) 4043f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, sibling, 4053f735377SArnaldo Carvalho de Melo RB_BLACK); 4063f735377SArnaldo Carvalho de Melo augment_rotate(sibling, tmp2); 4073f735377SArnaldo Carvalho de Melo tmp1 = sibling; 4083f735377SArnaldo Carvalho de Melo sibling = tmp2; 4093f735377SArnaldo Carvalho de Melo } 410*3aef2cadSDavidlohr Bueso /* Case 4 - right rotate at parent + color flips */ 411*3aef2cadSDavidlohr Bueso tmp2 = sibling->rb_right; 412*3aef2cadSDavidlohr Bueso WRITE_ONCE(parent->rb_left, tmp2); 413*3aef2cadSDavidlohr Bueso WRITE_ONCE(sibling->rb_right, parent); 4143f735377SArnaldo Carvalho de Melo rb_set_parent_color(tmp1, sibling, RB_BLACK); 4153f735377SArnaldo Carvalho de Melo if (tmp2) 4163f735377SArnaldo Carvalho de Melo rb_set_parent(tmp2, parent); 4173f735377SArnaldo Carvalho de Melo __rb_rotate_set_parents(parent, sibling, root, 4183f735377SArnaldo Carvalho de Melo RB_BLACK); 4193f735377SArnaldo Carvalho de Melo augment_rotate(parent, sibling); 4203f735377SArnaldo Carvalho de Melo break; 4213f735377SArnaldo Carvalho de Melo } 4223f735377SArnaldo Carvalho de Melo } 4233f735377SArnaldo Carvalho de Melo } 4243f735377SArnaldo Carvalho de Melo 4253f735377SArnaldo Carvalho de Melo /* Non-inline version for rb_erase_augmented() use */ 4263f735377SArnaldo Carvalho de Melo void __rb_erase_color(struct rb_node *parent, struct rb_root *root, 4273f735377SArnaldo Carvalho de Melo void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 4283f735377SArnaldo Carvalho de Melo { 4293f735377SArnaldo Carvalho de Melo ____rb_erase_color(parent, root, augment_rotate); 4303f735377SArnaldo Carvalho de Melo } 4313f735377SArnaldo Carvalho de Melo 4323f735377SArnaldo Carvalho de Melo /* 4333f735377SArnaldo Carvalho de Melo * Non-augmented rbtree manipulation functions. 4343f735377SArnaldo Carvalho de Melo * 4353f735377SArnaldo Carvalho de Melo * We use dummy augmented callbacks here, and have the compiler optimize them 4363f735377SArnaldo Carvalho de Melo * out of the rb_insert_color() and rb_erase() function definitions. 4373f735377SArnaldo Carvalho de Melo */ 4383f735377SArnaldo Carvalho de Melo 4393f735377SArnaldo Carvalho de Melo static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {} 4403f735377SArnaldo Carvalho de Melo static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {} 4413f735377SArnaldo Carvalho de Melo static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {} 4423f735377SArnaldo Carvalho de Melo 4433f735377SArnaldo Carvalho de Melo static const struct rb_augment_callbacks dummy_callbacks = { 444*3aef2cadSDavidlohr Bueso .propagate = dummy_propagate, 445*3aef2cadSDavidlohr Bueso .copy = dummy_copy, 446*3aef2cadSDavidlohr Bueso .rotate = dummy_rotate 4473f735377SArnaldo Carvalho de Melo }; 4483f735377SArnaldo Carvalho de Melo 4493f735377SArnaldo Carvalho de Melo void rb_insert_color(struct rb_node *node, struct rb_root *root) 4503f735377SArnaldo Carvalho de Melo { 451*3aef2cadSDavidlohr Bueso __rb_insert(node, root, false, NULL, dummy_rotate); 4523f735377SArnaldo Carvalho de Melo } 4533f735377SArnaldo Carvalho de Melo 4543f735377SArnaldo Carvalho de Melo void rb_erase(struct rb_node *node, struct rb_root *root) 4553f735377SArnaldo Carvalho de Melo { 4563f735377SArnaldo Carvalho de Melo struct rb_node *rebalance; 457*3aef2cadSDavidlohr Bueso rebalance = __rb_erase_augmented(node, root, 458*3aef2cadSDavidlohr Bueso NULL, &dummy_callbacks); 4593f735377SArnaldo Carvalho de Melo if (rebalance) 4603f735377SArnaldo Carvalho de Melo ____rb_erase_color(rebalance, root, dummy_rotate); 4613f735377SArnaldo Carvalho de Melo } 4623f735377SArnaldo Carvalho de Melo 463*3aef2cadSDavidlohr Bueso void rb_insert_color_cached(struct rb_node *node, 464*3aef2cadSDavidlohr Bueso struct rb_root_cached *root, bool leftmost) 465*3aef2cadSDavidlohr Bueso { 466*3aef2cadSDavidlohr Bueso __rb_insert(node, &root->rb_root, leftmost, 467*3aef2cadSDavidlohr Bueso &root->rb_leftmost, dummy_rotate); 468*3aef2cadSDavidlohr Bueso } 469*3aef2cadSDavidlohr Bueso 470*3aef2cadSDavidlohr Bueso void rb_erase_cached(struct rb_node *node, struct rb_root_cached *root) 471*3aef2cadSDavidlohr Bueso { 472*3aef2cadSDavidlohr Bueso struct rb_node *rebalance; 473*3aef2cadSDavidlohr Bueso rebalance = __rb_erase_augmented(node, &root->rb_root, 474*3aef2cadSDavidlohr Bueso &root->rb_leftmost, &dummy_callbacks); 475*3aef2cadSDavidlohr Bueso if (rebalance) 476*3aef2cadSDavidlohr Bueso ____rb_erase_color(rebalance, &root->rb_root, dummy_rotate); 477*3aef2cadSDavidlohr Bueso } 478*3aef2cadSDavidlohr Bueso 4793f735377SArnaldo Carvalho de Melo /* 4803f735377SArnaldo Carvalho de Melo * Augmented rbtree manipulation functions. 4813f735377SArnaldo Carvalho de Melo * 4823f735377SArnaldo Carvalho de Melo * This instantiates the same __always_inline functions as in the non-augmented 4833f735377SArnaldo Carvalho de Melo * case, but this time with user-defined callbacks. 4843f735377SArnaldo Carvalho de Melo */ 4853f735377SArnaldo Carvalho de Melo 4863f735377SArnaldo Carvalho de Melo void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 487*3aef2cadSDavidlohr Bueso bool newleft, struct rb_node **leftmost, 4883f735377SArnaldo Carvalho de Melo void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 4893f735377SArnaldo Carvalho de Melo { 490*3aef2cadSDavidlohr Bueso __rb_insert(node, root, newleft, leftmost, augment_rotate); 4913f735377SArnaldo Carvalho de Melo } 4923f735377SArnaldo Carvalho de Melo 4933f735377SArnaldo Carvalho de Melo /* 4943f735377SArnaldo Carvalho de Melo * This function returns the first node (in sort order) of the tree. 4953f735377SArnaldo Carvalho de Melo */ 4963f735377SArnaldo Carvalho de Melo struct rb_node *rb_first(const struct rb_root *root) 4973f735377SArnaldo Carvalho de Melo { 4983f735377SArnaldo Carvalho de Melo struct rb_node *n; 4993f735377SArnaldo Carvalho de Melo 5003f735377SArnaldo Carvalho de Melo n = root->rb_node; 5013f735377SArnaldo Carvalho de Melo if (!n) 5023f735377SArnaldo Carvalho de Melo return NULL; 5033f735377SArnaldo Carvalho de Melo while (n->rb_left) 5043f735377SArnaldo Carvalho de Melo n = n->rb_left; 5053f735377SArnaldo Carvalho de Melo return n; 5063f735377SArnaldo Carvalho de Melo } 5073f735377SArnaldo Carvalho de Melo 5083f735377SArnaldo Carvalho de Melo struct rb_node *rb_last(const struct rb_root *root) 5093f735377SArnaldo Carvalho de Melo { 5103f735377SArnaldo Carvalho de Melo struct rb_node *n; 5113f735377SArnaldo Carvalho de Melo 5123f735377SArnaldo Carvalho de Melo n = root->rb_node; 5133f735377SArnaldo Carvalho de Melo if (!n) 5143f735377SArnaldo Carvalho de Melo return NULL; 5153f735377SArnaldo Carvalho de Melo while (n->rb_right) 5163f735377SArnaldo Carvalho de Melo n = n->rb_right; 5173f735377SArnaldo Carvalho de Melo return n; 5183f735377SArnaldo Carvalho de Melo } 5193f735377SArnaldo Carvalho de Melo 5203f735377SArnaldo Carvalho de Melo struct rb_node *rb_next(const struct rb_node *node) 5213f735377SArnaldo Carvalho de Melo { 5223f735377SArnaldo Carvalho de Melo struct rb_node *parent; 5233f735377SArnaldo Carvalho de Melo 5243f735377SArnaldo Carvalho de Melo if (RB_EMPTY_NODE(node)) 5253f735377SArnaldo Carvalho de Melo return NULL; 5263f735377SArnaldo Carvalho de Melo 5273f735377SArnaldo Carvalho de Melo /* 5283f735377SArnaldo Carvalho de Melo * If we have a right-hand child, go down and then left as far 5293f735377SArnaldo Carvalho de Melo * as we can. 5303f735377SArnaldo Carvalho de Melo */ 5313f735377SArnaldo Carvalho de Melo if (node->rb_right) { 5323f735377SArnaldo Carvalho de Melo node = node->rb_right; 5333f735377SArnaldo Carvalho de Melo while (node->rb_left) 5343f735377SArnaldo Carvalho de Melo node=node->rb_left; 5353f735377SArnaldo Carvalho de Melo return (struct rb_node *)node; 5363f735377SArnaldo Carvalho de Melo } 5373f735377SArnaldo Carvalho de Melo 5383f735377SArnaldo Carvalho de Melo /* 5393f735377SArnaldo Carvalho de Melo * No right-hand children. Everything down and left is smaller than us, 5403f735377SArnaldo Carvalho de Melo * so any 'next' node must be in the general direction of our parent. 5413f735377SArnaldo Carvalho de Melo * Go up the tree; any time the ancestor is a right-hand child of its 5423f735377SArnaldo Carvalho de Melo * parent, keep going up. First time it's a left-hand child of its 5433f735377SArnaldo Carvalho de Melo * parent, said parent is our 'next' node. 5443f735377SArnaldo Carvalho de Melo */ 5453f735377SArnaldo Carvalho de Melo while ((parent = rb_parent(node)) && node == parent->rb_right) 5463f735377SArnaldo Carvalho de Melo node = parent; 5473f735377SArnaldo Carvalho de Melo 5483f735377SArnaldo Carvalho de Melo return parent; 5493f735377SArnaldo Carvalho de Melo } 5503f735377SArnaldo Carvalho de Melo 5513f735377SArnaldo Carvalho de Melo struct rb_node *rb_prev(const struct rb_node *node) 5523f735377SArnaldo Carvalho de Melo { 5533f735377SArnaldo Carvalho de Melo struct rb_node *parent; 5543f735377SArnaldo Carvalho de Melo 5553f735377SArnaldo Carvalho de Melo if (RB_EMPTY_NODE(node)) 5563f735377SArnaldo Carvalho de Melo return NULL; 5573f735377SArnaldo Carvalho de Melo 5583f735377SArnaldo Carvalho de Melo /* 5593f735377SArnaldo Carvalho de Melo * If we have a left-hand child, go down and then right as far 5603f735377SArnaldo Carvalho de Melo * as we can. 5613f735377SArnaldo Carvalho de Melo */ 5623f735377SArnaldo Carvalho de Melo if (node->rb_left) { 5633f735377SArnaldo Carvalho de Melo node = node->rb_left; 5643f735377SArnaldo Carvalho de Melo while (node->rb_right) 5653f735377SArnaldo Carvalho de Melo node=node->rb_right; 5663f735377SArnaldo Carvalho de Melo return (struct rb_node *)node; 5673f735377SArnaldo Carvalho de Melo } 5683f735377SArnaldo Carvalho de Melo 5693f735377SArnaldo Carvalho de Melo /* 5703f735377SArnaldo Carvalho de Melo * No left-hand children. Go up till we find an ancestor which 5713f735377SArnaldo Carvalho de Melo * is a right-hand child of its parent. 5723f735377SArnaldo Carvalho de Melo */ 5733f735377SArnaldo Carvalho de Melo while ((parent = rb_parent(node)) && node == parent->rb_left) 5743f735377SArnaldo Carvalho de Melo node = parent; 5753f735377SArnaldo Carvalho de Melo 5763f735377SArnaldo Carvalho de Melo return parent; 5773f735377SArnaldo Carvalho de Melo } 5783f735377SArnaldo Carvalho de Melo 5793f735377SArnaldo Carvalho de Melo void rb_replace_node(struct rb_node *victim, struct rb_node *new, 5803f735377SArnaldo Carvalho de Melo struct rb_root *root) 5813f735377SArnaldo Carvalho de Melo { 5823f735377SArnaldo Carvalho de Melo struct rb_node *parent = rb_parent(victim); 5833f735377SArnaldo Carvalho de Melo 584*3aef2cadSDavidlohr Bueso /* Copy the pointers/colour from the victim to the replacement */ 585*3aef2cadSDavidlohr Bueso *new = *victim; 586*3aef2cadSDavidlohr Bueso 5873f735377SArnaldo Carvalho de Melo /* Set the surrounding nodes to point to the replacement */ 5883f735377SArnaldo Carvalho de Melo if (victim->rb_left) 5893f735377SArnaldo Carvalho de Melo rb_set_parent(victim->rb_left, new); 5903f735377SArnaldo Carvalho de Melo if (victim->rb_right) 5913f735377SArnaldo Carvalho de Melo rb_set_parent(victim->rb_right, new); 592*3aef2cadSDavidlohr Bueso __rb_change_child(victim, new, parent, root); 593*3aef2cadSDavidlohr Bueso } 5943f735377SArnaldo Carvalho de Melo 595*3aef2cadSDavidlohr Bueso void rb_replace_node_cached(struct rb_node *victim, struct rb_node *new, 596*3aef2cadSDavidlohr Bueso struct rb_root_cached *root) 597*3aef2cadSDavidlohr Bueso { 598*3aef2cadSDavidlohr Bueso rb_replace_node(victim, new, &root->rb_root); 599*3aef2cadSDavidlohr Bueso 600*3aef2cadSDavidlohr Bueso if (root->rb_leftmost == victim) 601*3aef2cadSDavidlohr Bueso root->rb_leftmost = new; 6023f735377SArnaldo Carvalho de Melo } 6033f735377SArnaldo Carvalho de Melo 6043f735377SArnaldo Carvalho de Melo static struct rb_node *rb_left_deepest_node(const struct rb_node *node) 6053f735377SArnaldo Carvalho de Melo { 6063f735377SArnaldo Carvalho de Melo for (;;) { 6073f735377SArnaldo Carvalho de Melo if (node->rb_left) 6083f735377SArnaldo Carvalho de Melo node = node->rb_left; 6093f735377SArnaldo Carvalho de Melo else if (node->rb_right) 6103f735377SArnaldo Carvalho de Melo node = node->rb_right; 6113f735377SArnaldo Carvalho de Melo else 6123f735377SArnaldo Carvalho de Melo return (struct rb_node *)node; 6133f735377SArnaldo Carvalho de Melo } 6143f735377SArnaldo Carvalho de Melo } 6153f735377SArnaldo Carvalho de Melo 6163f735377SArnaldo Carvalho de Melo struct rb_node *rb_next_postorder(const struct rb_node *node) 6173f735377SArnaldo Carvalho de Melo { 6183f735377SArnaldo Carvalho de Melo const struct rb_node *parent; 6193f735377SArnaldo Carvalho de Melo if (!node) 6203f735377SArnaldo Carvalho de Melo return NULL; 6213f735377SArnaldo Carvalho de Melo parent = rb_parent(node); 6223f735377SArnaldo Carvalho de Melo 6233f735377SArnaldo Carvalho de Melo /* If we're sitting on node, we've already seen our children */ 6243f735377SArnaldo Carvalho de Melo if (parent && node == parent->rb_left && parent->rb_right) { 6253f735377SArnaldo Carvalho de Melo /* If we are the parent's left node, go to the parent's right 6263f735377SArnaldo Carvalho de Melo * node then all the way down to the left */ 6273f735377SArnaldo Carvalho de Melo return rb_left_deepest_node(parent->rb_right); 6283f735377SArnaldo Carvalho de Melo } else 6293f735377SArnaldo Carvalho de Melo /* Otherwise we are the parent's right node, and the parent 6303f735377SArnaldo Carvalho de Melo * should be next */ 6313f735377SArnaldo Carvalho de Melo return (struct rb_node *)parent; 6323f735377SArnaldo Carvalho de Melo } 6333f735377SArnaldo Carvalho de Melo 6343f735377SArnaldo Carvalho de Melo struct rb_node *rb_first_postorder(const struct rb_root *root) 6353f735377SArnaldo Carvalho de Melo { 6363f735377SArnaldo Carvalho de Melo if (!root->rb_node) 6373f735377SArnaldo Carvalho de Melo return NULL; 6383f735377SArnaldo Carvalho de Melo 6393f735377SArnaldo Carvalho de Melo return rb_left_deepest_node(root->rb_node); 6403f735377SArnaldo Carvalho de Melo } 641