178acc472SPeter Tyser /* 278acc472SPeter Tyser Red Black Trees 378acc472SPeter Tyser (C) 1999 Andrea Arcangeli <andrea@suse.de> 478acc472SPeter Tyser (C) 2002 David Woodhouse <dwmw2@infradead.org> 5*9dd228b5SHeiko Schocher (C) 2012 Michel Lespinasse <walken@google.com> 678acc472SPeter Tyser 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 878acc472SPeter Tyser 978acc472SPeter Tyser linux/lib/rbtree.c 1078acc472SPeter Tyser */ 1178acc472SPeter Tyser 12*9dd228b5SHeiko Schocher #define __UBOOT__ 13*9dd228b5SHeiko Schocher #include <linux/rbtree_augmented.h> 14*9dd228b5SHeiko Schocher #ifndef __UBOOT__ 15*9dd228b5SHeiko Schocher #include <linux/export.h> 16*9dd228b5SHeiko Schocher #else 1778acc472SPeter Tyser #include <ubi_uboot.h> 18*9dd228b5SHeiko Schocher #endif 19*9dd228b5SHeiko Schocher /* 20*9dd228b5SHeiko Schocher * red-black trees properties: http://en.wikipedia.org/wiki/Rbtree 21*9dd228b5SHeiko Schocher * 22*9dd228b5SHeiko Schocher * 1) A node is either red or black 23*9dd228b5SHeiko Schocher * 2) The root is black 24*9dd228b5SHeiko Schocher * 3) All leaves (NULL) are black 25*9dd228b5SHeiko Schocher * 4) Both children of every red node are black 26*9dd228b5SHeiko Schocher * 5) Every simple path from root to leaves contains the same number 27*9dd228b5SHeiko Schocher * of black nodes. 28*9dd228b5SHeiko Schocher * 29*9dd228b5SHeiko Schocher * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two 30*9dd228b5SHeiko Schocher * consecutive red nodes in a path and every red node is therefore followed by 31*9dd228b5SHeiko Schocher * a black. So if B is the number of black nodes on every simple path (as per 32*9dd228b5SHeiko Schocher * 5), then the longest possible path due to 4 is 2B. 33*9dd228b5SHeiko Schocher * 34*9dd228b5SHeiko Schocher * We shall indicate color with case, where black nodes are uppercase and red 35*9dd228b5SHeiko Schocher * nodes will be lowercase. Unknown color nodes shall be drawn as red within 36*9dd228b5SHeiko Schocher * parentheses and have some accompanying text comment. 37*9dd228b5SHeiko Schocher */ 3878acc472SPeter Tyser 39*9dd228b5SHeiko Schocher static inline void rb_set_black(struct rb_node *rb) 4078acc472SPeter Tyser { 41*9dd228b5SHeiko Schocher rb->__rb_parent_color |= RB_BLACK; 42*9dd228b5SHeiko Schocher } 4378acc472SPeter Tyser 44*9dd228b5SHeiko Schocher static inline struct rb_node *rb_red_parent(struct rb_node *red) 45*9dd228b5SHeiko Schocher { 46*9dd228b5SHeiko Schocher return (struct rb_node *)red->__rb_parent_color; 47*9dd228b5SHeiko Schocher } 4878acc472SPeter Tyser 49*9dd228b5SHeiko Schocher /* 50*9dd228b5SHeiko Schocher * Helper function for rotations: 51*9dd228b5SHeiko Schocher * - old's parent and color get assigned to new 52*9dd228b5SHeiko Schocher * - old gets assigned new as a parent and 'color' as a color. 53*9dd228b5SHeiko Schocher */ 54*9dd228b5SHeiko Schocher static inline void 55*9dd228b5SHeiko Schocher __rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, 56*9dd228b5SHeiko Schocher struct rb_root *root, int color) 57*9dd228b5SHeiko Schocher { 58*9dd228b5SHeiko Schocher struct rb_node *parent = rb_parent(old); 59*9dd228b5SHeiko Schocher new->__rb_parent_color = old->__rb_parent_color; 60*9dd228b5SHeiko Schocher rb_set_parent_color(old, new, color); 61*9dd228b5SHeiko Schocher __rb_change_child(old, new, parent, root); 62*9dd228b5SHeiko Schocher } 6378acc472SPeter Tyser 64*9dd228b5SHeiko Schocher static __always_inline void 65*9dd228b5SHeiko Schocher __rb_insert(struct rb_node *node, struct rb_root *root, 66*9dd228b5SHeiko Schocher void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 67*9dd228b5SHeiko Schocher { 68*9dd228b5SHeiko Schocher struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; 69*9dd228b5SHeiko Schocher 70*9dd228b5SHeiko Schocher while (true) { 71*9dd228b5SHeiko Schocher /* 72*9dd228b5SHeiko Schocher * Loop invariant: node is red 73*9dd228b5SHeiko Schocher * 74*9dd228b5SHeiko Schocher * If there is a black parent, we are done. 75*9dd228b5SHeiko Schocher * Otherwise, take some corrective action as we don't 76*9dd228b5SHeiko Schocher * want a red root or two consecutive red nodes. 77*9dd228b5SHeiko Schocher */ 78*9dd228b5SHeiko Schocher if (!parent) { 79*9dd228b5SHeiko Schocher rb_set_parent_color(node, NULL, RB_BLACK); 80*9dd228b5SHeiko Schocher break; 81*9dd228b5SHeiko Schocher } else if (rb_is_black(parent)) 82*9dd228b5SHeiko Schocher break; 83*9dd228b5SHeiko Schocher 84*9dd228b5SHeiko Schocher gparent = rb_red_parent(parent); 85*9dd228b5SHeiko Schocher 86*9dd228b5SHeiko Schocher tmp = gparent->rb_right; 87*9dd228b5SHeiko Schocher if (parent != tmp) { /* parent == gparent->rb_left */ 88*9dd228b5SHeiko Schocher if (tmp && rb_is_red(tmp)) { 89*9dd228b5SHeiko Schocher /* 90*9dd228b5SHeiko Schocher * Case 1 - color flips 91*9dd228b5SHeiko Schocher * 92*9dd228b5SHeiko Schocher * G g 93*9dd228b5SHeiko Schocher * / \ / \ 94*9dd228b5SHeiko Schocher * p u --> P U 95*9dd228b5SHeiko Schocher * / / 96*9dd228b5SHeiko Schocher * n N 97*9dd228b5SHeiko Schocher * 98*9dd228b5SHeiko Schocher * However, since g's parent might be red, and 99*9dd228b5SHeiko Schocher * 4) does not allow this, we need to recurse 100*9dd228b5SHeiko Schocher * at g. 101*9dd228b5SHeiko Schocher */ 102*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, gparent, RB_BLACK); 103*9dd228b5SHeiko Schocher rb_set_parent_color(parent, gparent, RB_BLACK); 104*9dd228b5SHeiko Schocher node = gparent; 105*9dd228b5SHeiko Schocher parent = rb_parent(node); 106*9dd228b5SHeiko Schocher rb_set_parent_color(node, parent, RB_RED); 107*9dd228b5SHeiko Schocher continue; 108*9dd228b5SHeiko Schocher } 109*9dd228b5SHeiko Schocher 110*9dd228b5SHeiko Schocher tmp = parent->rb_right; 111*9dd228b5SHeiko Schocher if (node == tmp) { 112*9dd228b5SHeiko Schocher /* 113*9dd228b5SHeiko Schocher * Case 2 - left rotate at parent 114*9dd228b5SHeiko Schocher * 115*9dd228b5SHeiko Schocher * G G 116*9dd228b5SHeiko Schocher * / \ / \ 117*9dd228b5SHeiko Schocher * p U --> n U 118*9dd228b5SHeiko Schocher * \ / 119*9dd228b5SHeiko Schocher * n p 120*9dd228b5SHeiko Schocher * 121*9dd228b5SHeiko Schocher * This still leaves us in violation of 4), the 122*9dd228b5SHeiko Schocher * continuation into Case 3 will fix that. 123*9dd228b5SHeiko Schocher */ 124*9dd228b5SHeiko Schocher parent->rb_right = tmp = node->rb_left; 125*9dd228b5SHeiko Schocher node->rb_left = parent; 126*9dd228b5SHeiko Schocher if (tmp) 127*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, parent, 128*9dd228b5SHeiko Schocher RB_BLACK); 129*9dd228b5SHeiko Schocher rb_set_parent_color(parent, node, RB_RED); 130*9dd228b5SHeiko Schocher augment_rotate(parent, node); 131*9dd228b5SHeiko Schocher parent = node; 132*9dd228b5SHeiko Schocher tmp = node->rb_right; 133*9dd228b5SHeiko Schocher } 134*9dd228b5SHeiko Schocher 135*9dd228b5SHeiko Schocher /* 136*9dd228b5SHeiko Schocher * Case 3 - right rotate at gparent 137*9dd228b5SHeiko Schocher * 138*9dd228b5SHeiko Schocher * G P 139*9dd228b5SHeiko Schocher * / \ / \ 140*9dd228b5SHeiko Schocher * p U --> n g 141*9dd228b5SHeiko Schocher * / \ 142*9dd228b5SHeiko Schocher * n U 143*9dd228b5SHeiko Schocher */ 144*9dd228b5SHeiko Schocher gparent->rb_left = tmp; /* == parent->rb_right */ 145*9dd228b5SHeiko Schocher parent->rb_right = gparent; 146*9dd228b5SHeiko Schocher if (tmp) 147*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, gparent, RB_BLACK); 148*9dd228b5SHeiko Schocher __rb_rotate_set_parents(gparent, parent, root, RB_RED); 149*9dd228b5SHeiko Schocher augment_rotate(gparent, parent); 150*9dd228b5SHeiko Schocher break; 151*9dd228b5SHeiko Schocher } else { 152*9dd228b5SHeiko Schocher tmp = gparent->rb_left; 153*9dd228b5SHeiko Schocher if (tmp && rb_is_red(tmp)) { 154*9dd228b5SHeiko Schocher /* Case 1 - color flips */ 155*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, gparent, RB_BLACK); 156*9dd228b5SHeiko Schocher rb_set_parent_color(parent, gparent, RB_BLACK); 157*9dd228b5SHeiko Schocher node = gparent; 158*9dd228b5SHeiko Schocher parent = rb_parent(node); 159*9dd228b5SHeiko Schocher rb_set_parent_color(node, parent, RB_RED); 160*9dd228b5SHeiko Schocher continue; 161*9dd228b5SHeiko Schocher } 162*9dd228b5SHeiko Schocher 163*9dd228b5SHeiko Schocher tmp = parent->rb_left; 164*9dd228b5SHeiko Schocher if (node == tmp) { 165*9dd228b5SHeiko Schocher /* Case 2 - right rotate at parent */ 166*9dd228b5SHeiko Schocher parent->rb_left = tmp = node->rb_right; 167*9dd228b5SHeiko Schocher node->rb_right = parent; 168*9dd228b5SHeiko Schocher if (tmp) 169*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, parent, 170*9dd228b5SHeiko Schocher RB_BLACK); 171*9dd228b5SHeiko Schocher rb_set_parent_color(parent, node, RB_RED); 172*9dd228b5SHeiko Schocher augment_rotate(parent, node); 173*9dd228b5SHeiko Schocher parent = node; 174*9dd228b5SHeiko Schocher tmp = node->rb_left; 175*9dd228b5SHeiko Schocher } 176*9dd228b5SHeiko Schocher 177*9dd228b5SHeiko Schocher /* Case 3 - left rotate at gparent */ 178*9dd228b5SHeiko Schocher gparent->rb_right = tmp; /* == parent->rb_left */ 179*9dd228b5SHeiko Schocher parent->rb_left = gparent; 180*9dd228b5SHeiko Schocher if (tmp) 181*9dd228b5SHeiko Schocher rb_set_parent_color(tmp, gparent, RB_BLACK); 182*9dd228b5SHeiko Schocher __rb_rotate_set_parents(gparent, parent, root, RB_RED); 183*9dd228b5SHeiko Schocher augment_rotate(gparent, parent); 184*9dd228b5SHeiko Schocher break; 185*9dd228b5SHeiko Schocher } 186*9dd228b5SHeiko Schocher } 187*9dd228b5SHeiko Schocher } 188*9dd228b5SHeiko Schocher 189*9dd228b5SHeiko Schocher /* 190*9dd228b5SHeiko Schocher * Inline version for rb_erase() use - we want to be able to inline 191*9dd228b5SHeiko Schocher * and eliminate the dummy_rotate callback there 192*9dd228b5SHeiko Schocher */ 193*9dd228b5SHeiko Schocher static __always_inline void 194*9dd228b5SHeiko Schocher ____rb_erase_color(struct rb_node *parent, struct rb_root *root, 195*9dd228b5SHeiko Schocher void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 196*9dd228b5SHeiko Schocher { 197*9dd228b5SHeiko Schocher struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; 198*9dd228b5SHeiko Schocher 199*9dd228b5SHeiko Schocher while (true) { 200*9dd228b5SHeiko Schocher /* 201*9dd228b5SHeiko Schocher * Loop invariants: 202*9dd228b5SHeiko Schocher * - node is black (or NULL on first iteration) 203*9dd228b5SHeiko Schocher * - node is not the root (parent is not NULL) 204*9dd228b5SHeiko Schocher * - All leaf paths going through parent and node have a 205*9dd228b5SHeiko Schocher * black node count that is 1 lower than other leaf paths. 206*9dd228b5SHeiko Schocher */ 207*9dd228b5SHeiko Schocher sibling = parent->rb_right; 208*9dd228b5SHeiko Schocher if (node != sibling) { /* node == parent->rb_left */ 209*9dd228b5SHeiko Schocher if (rb_is_red(sibling)) { 210*9dd228b5SHeiko Schocher /* 211*9dd228b5SHeiko Schocher * Case 1 - left rotate at parent 212*9dd228b5SHeiko Schocher * 213*9dd228b5SHeiko Schocher * P S 214*9dd228b5SHeiko Schocher * / \ / \ 215*9dd228b5SHeiko Schocher * N s --> p Sr 216*9dd228b5SHeiko Schocher * / \ / \ 217*9dd228b5SHeiko Schocher * Sl Sr N Sl 218*9dd228b5SHeiko Schocher */ 219*9dd228b5SHeiko Schocher parent->rb_right = tmp1 = sibling->rb_left; 220*9dd228b5SHeiko Schocher sibling->rb_left = parent; 221*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, parent, RB_BLACK); 222*9dd228b5SHeiko Schocher __rb_rotate_set_parents(parent, sibling, root, 223*9dd228b5SHeiko Schocher RB_RED); 224*9dd228b5SHeiko Schocher augment_rotate(parent, sibling); 225*9dd228b5SHeiko Schocher sibling = tmp1; 226*9dd228b5SHeiko Schocher } 227*9dd228b5SHeiko Schocher tmp1 = sibling->rb_right; 228*9dd228b5SHeiko Schocher if (!tmp1 || rb_is_black(tmp1)) { 229*9dd228b5SHeiko Schocher tmp2 = sibling->rb_left; 230*9dd228b5SHeiko Schocher if (!tmp2 || rb_is_black(tmp2)) { 231*9dd228b5SHeiko Schocher /* 232*9dd228b5SHeiko Schocher * Case 2 - sibling color flip 233*9dd228b5SHeiko Schocher * (p could be either color here) 234*9dd228b5SHeiko Schocher * 235*9dd228b5SHeiko Schocher * (p) (p) 236*9dd228b5SHeiko Schocher * / \ / \ 237*9dd228b5SHeiko Schocher * N S --> N s 238*9dd228b5SHeiko Schocher * / \ / \ 239*9dd228b5SHeiko Schocher * Sl Sr Sl Sr 240*9dd228b5SHeiko Schocher * 241*9dd228b5SHeiko Schocher * This leaves us violating 5) which 242*9dd228b5SHeiko Schocher * can be fixed by flipping p to black 243*9dd228b5SHeiko Schocher * if it was red, or by recursing at p. 244*9dd228b5SHeiko Schocher * p is red when coming from Case 1. 245*9dd228b5SHeiko Schocher */ 246*9dd228b5SHeiko Schocher rb_set_parent_color(sibling, parent, 247*9dd228b5SHeiko Schocher RB_RED); 248*9dd228b5SHeiko Schocher if (rb_is_red(parent)) 249*9dd228b5SHeiko Schocher rb_set_black(parent); 250*9dd228b5SHeiko Schocher else { 251*9dd228b5SHeiko Schocher node = parent; 252*9dd228b5SHeiko Schocher parent = rb_parent(node); 25378acc472SPeter Tyser if (parent) 254*9dd228b5SHeiko Schocher continue; 25578acc472SPeter Tyser } 256*9dd228b5SHeiko Schocher break; 25778acc472SPeter Tyser } 258*9dd228b5SHeiko Schocher /* 259*9dd228b5SHeiko Schocher * Case 3 - right rotate at sibling 260*9dd228b5SHeiko Schocher * (p could be either color here) 261*9dd228b5SHeiko Schocher * 262*9dd228b5SHeiko Schocher * (p) (p) 263*9dd228b5SHeiko Schocher * / \ / \ 264*9dd228b5SHeiko Schocher * N S --> N Sl 265*9dd228b5SHeiko Schocher * / \ \ 266*9dd228b5SHeiko Schocher * sl Sr s 267*9dd228b5SHeiko Schocher * \ 268*9dd228b5SHeiko Schocher * Sr 269*9dd228b5SHeiko Schocher */ 270*9dd228b5SHeiko Schocher sibling->rb_left = tmp1 = tmp2->rb_right; 271*9dd228b5SHeiko Schocher tmp2->rb_right = sibling; 272*9dd228b5SHeiko Schocher parent->rb_right = tmp2; 273*9dd228b5SHeiko Schocher if (tmp1) 274*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, sibling, 275*9dd228b5SHeiko Schocher RB_BLACK); 276*9dd228b5SHeiko Schocher augment_rotate(sibling, tmp2); 277*9dd228b5SHeiko Schocher tmp1 = sibling; 278*9dd228b5SHeiko Schocher sibling = tmp2; 279*9dd228b5SHeiko Schocher } 280*9dd228b5SHeiko Schocher /* 281*9dd228b5SHeiko Schocher * Case 4 - left rotate at parent + color flips 282*9dd228b5SHeiko Schocher * (p and sl could be either color here. 283*9dd228b5SHeiko Schocher * After rotation, p becomes black, s acquires 284*9dd228b5SHeiko Schocher * p's color, and sl keeps its color) 285*9dd228b5SHeiko Schocher * 286*9dd228b5SHeiko Schocher * (p) (s) 287*9dd228b5SHeiko Schocher * / \ / \ 288*9dd228b5SHeiko Schocher * N S --> P Sr 289*9dd228b5SHeiko Schocher * / \ / \ 290*9dd228b5SHeiko Schocher * (sl) sr N (sl) 291*9dd228b5SHeiko Schocher */ 292*9dd228b5SHeiko Schocher parent->rb_right = tmp2 = sibling->rb_left; 293*9dd228b5SHeiko Schocher sibling->rb_left = parent; 294*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, sibling, RB_BLACK); 295*9dd228b5SHeiko Schocher if (tmp2) 296*9dd228b5SHeiko Schocher rb_set_parent(tmp2, parent); 297*9dd228b5SHeiko Schocher __rb_rotate_set_parents(parent, sibling, root, 298*9dd228b5SHeiko Schocher RB_BLACK); 299*9dd228b5SHeiko Schocher augment_rotate(parent, sibling); 300*9dd228b5SHeiko Schocher break; 301*9dd228b5SHeiko Schocher } else { 302*9dd228b5SHeiko Schocher sibling = parent->rb_left; 303*9dd228b5SHeiko Schocher if (rb_is_red(sibling)) { 304*9dd228b5SHeiko Schocher /* Case 1 - right rotate at parent */ 305*9dd228b5SHeiko Schocher parent->rb_left = tmp1 = sibling->rb_right; 306*9dd228b5SHeiko Schocher sibling->rb_right = parent; 307*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, parent, RB_BLACK); 308*9dd228b5SHeiko Schocher __rb_rotate_set_parents(parent, sibling, root, 309*9dd228b5SHeiko Schocher RB_RED); 310*9dd228b5SHeiko Schocher augment_rotate(parent, sibling); 311*9dd228b5SHeiko Schocher sibling = tmp1; 312*9dd228b5SHeiko Schocher } 313*9dd228b5SHeiko Schocher tmp1 = sibling->rb_left; 314*9dd228b5SHeiko Schocher if (!tmp1 || rb_is_black(tmp1)) { 315*9dd228b5SHeiko Schocher tmp2 = sibling->rb_right; 316*9dd228b5SHeiko Schocher if (!tmp2 || rb_is_black(tmp2)) { 317*9dd228b5SHeiko Schocher /* Case 2 - sibling color flip */ 318*9dd228b5SHeiko Schocher rb_set_parent_color(sibling, parent, 319*9dd228b5SHeiko Schocher RB_RED); 320*9dd228b5SHeiko Schocher if (rb_is_red(parent)) 321*9dd228b5SHeiko Schocher rb_set_black(parent); 322*9dd228b5SHeiko Schocher else { 323*9dd228b5SHeiko Schocher node = parent; 324*9dd228b5SHeiko Schocher parent = rb_parent(node); 32578acc472SPeter Tyser if (parent) 326*9dd228b5SHeiko Schocher continue; 327*9dd228b5SHeiko Schocher } 328*9dd228b5SHeiko Schocher break; 329*9dd228b5SHeiko Schocher } 330*9dd228b5SHeiko Schocher /* Case 3 - right rotate at sibling */ 331*9dd228b5SHeiko Schocher sibling->rb_right = tmp1 = tmp2->rb_left; 332*9dd228b5SHeiko Schocher tmp2->rb_left = sibling; 333*9dd228b5SHeiko Schocher parent->rb_left = tmp2; 334*9dd228b5SHeiko Schocher if (tmp1) 335*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, sibling, 336*9dd228b5SHeiko Schocher RB_BLACK); 337*9dd228b5SHeiko Schocher augment_rotate(sibling, tmp2); 338*9dd228b5SHeiko Schocher tmp1 = sibling; 339*9dd228b5SHeiko Schocher sibling = tmp2; 340*9dd228b5SHeiko Schocher } 341*9dd228b5SHeiko Schocher /* Case 4 - left rotate at parent + color flips */ 342*9dd228b5SHeiko Schocher parent->rb_left = tmp2 = sibling->rb_right; 343*9dd228b5SHeiko Schocher sibling->rb_right = parent; 344*9dd228b5SHeiko Schocher rb_set_parent_color(tmp1, sibling, RB_BLACK); 345*9dd228b5SHeiko Schocher if (tmp2) 346*9dd228b5SHeiko Schocher rb_set_parent(tmp2, parent); 347*9dd228b5SHeiko Schocher __rb_rotate_set_parents(parent, sibling, root, 348*9dd228b5SHeiko Schocher RB_BLACK); 349*9dd228b5SHeiko Schocher augment_rotate(parent, sibling); 350*9dd228b5SHeiko Schocher break; 351*9dd228b5SHeiko Schocher } 352*9dd228b5SHeiko Schocher } 353*9dd228b5SHeiko Schocher } 354*9dd228b5SHeiko Schocher 355*9dd228b5SHeiko Schocher /* Non-inline version for rb_erase_augmented() use */ 356*9dd228b5SHeiko Schocher void __rb_erase_color(struct rb_node *parent, struct rb_root *root, 357*9dd228b5SHeiko Schocher void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 35878acc472SPeter Tyser { 359*9dd228b5SHeiko Schocher ____rb_erase_color(parent, root, augment_rotate); 36078acc472SPeter Tyser } 361*9dd228b5SHeiko Schocher EXPORT_SYMBOL(__rb_erase_color); 362*9dd228b5SHeiko Schocher 363*9dd228b5SHeiko Schocher /* 364*9dd228b5SHeiko Schocher * Non-augmented rbtree manipulation functions. 365*9dd228b5SHeiko Schocher * 366*9dd228b5SHeiko Schocher * We use dummy augmented callbacks here, and have the compiler optimize them 367*9dd228b5SHeiko Schocher * out of the rb_insert_color() and rb_erase() function definitions. 368*9dd228b5SHeiko Schocher */ 369*9dd228b5SHeiko Schocher 370*9dd228b5SHeiko Schocher static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {} 371*9dd228b5SHeiko Schocher static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {} 372*9dd228b5SHeiko Schocher static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {} 373*9dd228b5SHeiko Schocher 374*9dd228b5SHeiko Schocher static const struct rb_augment_callbacks dummy_callbacks = { 375*9dd228b5SHeiko Schocher dummy_propagate, dummy_copy, dummy_rotate 376*9dd228b5SHeiko Schocher }; 37778acc472SPeter Tyser 37878acc472SPeter Tyser void rb_insert_color(struct rb_node *node, struct rb_root *root) 37978acc472SPeter Tyser { 380*9dd228b5SHeiko Schocher __rb_insert(node, root, dummy_rotate); 38178acc472SPeter Tyser } 382*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_insert_color); 38378acc472SPeter Tyser 38478acc472SPeter Tyser void rb_erase(struct rb_node *node, struct rb_root *root) 38578acc472SPeter Tyser { 386*9dd228b5SHeiko Schocher struct rb_node *rebalance; 387*9dd228b5SHeiko Schocher rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); 388*9dd228b5SHeiko Schocher if (rebalance) 389*9dd228b5SHeiko Schocher ____rb_erase_color(rebalance, root, dummy_rotate); 39078acc472SPeter Tyser } 391*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_erase); 39278acc472SPeter Tyser 393*9dd228b5SHeiko Schocher /* 394*9dd228b5SHeiko Schocher * Augmented rbtree manipulation functions. 395*9dd228b5SHeiko Schocher * 396*9dd228b5SHeiko Schocher * This instantiates the same __always_inline functions as in the non-augmented 397*9dd228b5SHeiko Schocher * case, but this time with user-defined callbacks. 398*9dd228b5SHeiko Schocher */ 39978acc472SPeter Tyser 400*9dd228b5SHeiko Schocher void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 401*9dd228b5SHeiko Schocher void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 40278acc472SPeter Tyser { 403*9dd228b5SHeiko Schocher __rb_insert(node, root, augment_rotate); 40478acc472SPeter Tyser } 405*9dd228b5SHeiko Schocher EXPORT_SYMBOL(__rb_insert_augmented); 40678acc472SPeter Tyser 40778acc472SPeter Tyser /* 40878acc472SPeter Tyser * This function returns the first node (in sort order) of the tree. 40978acc472SPeter Tyser */ 410*9dd228b5SHeiko Schocher struct rb_node *rb_first(const struct rb_root *root) 41178acc472SPeter Tyser { 41278acc472SPeter Tyser struct rb_node *n; 41378acc472SPeter Tyser 41478acc472SPeter Tyser n = root->rb_node; 41578acc472SPeter Tyser if (!n) 41678acc472SPeter Tyser return NULL; 41778acc472SPeter Tyser while (n->rb_left) 41878acc472SPeter Tyser n = n->rb_left; 41978acc472SPeter Tyser return n; 42078acc472SPeter Tyser } 421*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_first); 42278acc472SPeter Tyser 423*9dd228b5SHeiko Schocher struct rb_node *rb_last(const struct rb_root *root) 42478acc472SPeter Tyser { 42578acc472SPeter Tyser struct rb_node *n; 42678acc472SPeter Tyser 42778acc472SPeter Tyser n = root->rb_node; 42878acc472SPeter Tyser if (!n) 42978acc472SPeter Tyser return NULL; 43078acc472SPeter Tyser while (n->rb_right) 43178acc472SPeter Tyser n = n->rb_right; 43278acc472SPeter Tyser return n; 43378acc472SPeter Tyser } 434*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_last); 43578acc472SPeter Tyser 436*9dd228b5SHeiko Schocher struct rb_node *rb_next(const struct rb_node *node) 43778acc472SPeter Tyser { 43878acc472SPeter Tyser struct rb_node *parent; 43978acc472SPeter Tyser 440*9dd228b5SHeiko Schocher if (RB_EMPTY_NODE(node)) 44178acc472SPeter Tyser return NULL; 44278acc472SPeter Tyser 443*9dd228b5SHeiko Schocher /* 444*9dd228b5SHeiko Schocher * If we have a right-hand child, go down and then left as far 445*9dd228b5SHeiko Schocher * as we can. 446*9dd228b5SHeiko Schocher */ 44778acc472SPeter Tyser if (node->rb_right) { 44878acc472SPeter Tyser node = node->rb_right; 44978acc472SPeter Tyser while (node->rb_left) 45078acc472SPeter Tyser node=node->rb_left; 451*9dd228b5SHeiko Schocher return (struct rb_node *)node; 45278acc472SPeter Tyser } 45378acc472SPeter Tyser 454*9dd228b5SHeiko Schocher /* 455*9dd228b5SHeiko Schocher * No right-hand children. Everything down and left is smaller than us, 456*9dd228b5SHeiko Schocher * so any 'next' node must be in the general direction of our parent. 457*9dd228b5SHeiko Schocher * Go up the tree; any time the ancestor is a right-hand child of its 458*9dd228b5SHeiko Schocher * parent, keep going up. First time it's a left-hand child of its 459*9dd228b5SHeiko Schocher * parent, said parent is our 'next' node. 460*9dd228b5SHeiko Schocher */ 46178acc472SPeter Tyser while ((parent = rb_parent(node)) && node == parent->rb_right) 46278acc472SPeter Tyser node = parent; 46378acc472SPeter Tyser 46478acc472SPeter Tyser return parent; 46578acc472SPeter Tyser } 466*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_next); 46778acc472SPeter Tyser 468*9dd228b5SHeiko Schocher struct rb_node *rb_prev(const struct rb_node *node) 46978acc472SPeter Tyser { 47078acc472SPeter Tyser struct rb_node *parent; 47178acc472SPeter Tyser 472*9dd228b5SHeiko Schocher if (RB_EMPTY_NODE(node)) 47378acc472SPeter Tyser return NULL; 47478acc472SPeter Tyser 475*9dd228b5SHeiko Schocher /* 476*9dd228b5SHeiko Schocher * If we have a left-hand child, go down and then right as far 477*9dd228b5SHeiko Schocher * as we can. 478*9dd228b5SHeiko Schocher */ 47978acc472SPeter Tyser if (node->rb_left) { 48078acc472SPeter Tyser node = node->rb_left; 48178acc472SPeter Tyser while (node->rb_right) 48278acc472SPeter Tyser node=node->rb_right; 483*9dd228b5SHeiko Schocher return (struct rb_node *)node; 48478acc472SPeter Tyser } 48578acc472SPeter Tyser 486*9dd228b5SHeiko Schocher /* 487*9dd228b5SHeiko Schocher * No left-hand children. Go up till we find an ancestor which 488*9dd228b5SHeiko Schocher * is a right-hand child of its parent. 489*9dd228b5SHeiko Schocher */ 49078acc472SPeter Tyser while ((parent = rb_parent(node)) && node == parent->rb_left) 49178acc472SPeter Tyser node = parent; 49278acc472SPeter Tyser 49378acc472SPeter Tyser return parent; 49478acc472SPeter Tyser } 495*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_prev); 49678acc472SPeter Tyser 49778acc472SPeter Tyser void rb_replace_node(struct rb_node *victim, struct rb_node *new, 49878acc472SPeter Tyser struct rb_root *root) 49978acc472SPeter Tyser { 50078acc472SPeter Tyser struct rb_node *parent = rb_parent(victim); 50178acc472SPeter Tyser 50278acc472SPeter Tyser /* Set the surrounding nodes to point to the replacement */ 503*9dd228b5SHeiko Schocher __rb_change_child(victim, new, parent, root); 50478acc472SPeter Tyser if (victim->rb_left) 50578acc472SPeter Tyser rb_set_parent(victim->rb_left, new); 50678acc472SPeter Tyser if (victim->rb_right) 50778acc472SPeter Tyser rb_set_parent(victim->rb_right, new); 50878acc472SPeter Tyser 50978acc472SPeter Tyser /* Copy the pointers/colour from the victim to the replacement */ 51078acc472SPeter Tyser *new = *victim; 51178acc472SPeter Tyser } 512*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_replace_node); 513*9dd228b5SHeiko Schocher 514*9dd228b5SHeiko Schocher static struct rb_node *rb_left_deepest_node(const struct rb_node *node) 515*9dd228b5SHeiko Schocher { 516*9dd228b5SHeiko Schocher for (;;) { 517*9dd228b5SHeiko Schocher if (node->rb_left) 518*9dd228b5SHeiko Schocher node = node->rb_left; 519*9dd228b5SHeiko Schocher else if (node->rb_right) 520*9dd228b5SHeiko Schocher node = node->rb_right; 521*9dd228b5SHeiko Schocher else 522*9dd228b5SHeiko Schocher return (struct rb_node *)node; 523*9dd228b5SHeiko Schocher } 524*9dd228b5SHeiko Schocher } 525*9dd228b5SHeiko Schocher 526*9dd228b5SHeiko Schocher struct rb_node *rb_next_postorder(const struct rb_node *node) 527*9dd228b5SHeiko Schocher { 528*9dd228b5SHeiko Schocher const struct rb_node *parent; 529*9dd228b5SHeiko Schocher if (!node) 530*9dd228b5SHeiko Schocher return NULL; 531*9dd228b5SHeiko Schocher parent = rb_parent(node); 532*9dd228b5SHeiko Schocher 533*9dd228b5SHeiko Schocher /* If we're sitting on node, we've already seen our children */ 534*9dd228b5SHeiko Schocher if (parent && node == parent->rb_left && parent->rb_right) { 535*9dd228b5SHeiko Schocher /* If we are the parent's left node, go to the parent's right 536*9dd228b5SHeiko Schocher * node then all the way down to the left */ 537*9dd228b5SHeiko Schocher return rb_left_deepest_node(parent->rb_right); 538*9dd228b5SHeiko Schocher } else 539*9dd228b5SHeiko Schocher /* Otherwise we are the parent's right node, and the parent 540*9dd228b5SHeiko Schocher * should be next */ 541*9dd228b5SHeiko Schocher return (struct rb_node *)parent; 542*9dd228b5SHeiko Schocher } 543*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_next_postorder); 544*9dd228b5SHeiko Schocher 545*9dd228b5SHeiko Schocher struct rb_node *rb_first_postorder(const struct rb_root *root) 546*9dd228b5SHeiko Schocher { 547*9dd228b5SHeiko Schocher if (!root->rb_node) 548*9dd228b5SHeiko Schocher return NULL; 549*9dd228b5SHeiko Schocher 550*9dd228b5SHeiko Schocher return rb_left_deepest_node(root->rb_node); 551*9dd228b5SHeiko Schocher } 552*9dd228b5SHeiko Schocher EXPORT_SYMBOL(rb_first_postorder); 553