162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci Red Black Trees 462306a36Sopenharmony_ci (C) 1999 Andrea Arcangeli <andrea@suse.de> 562306a36Sopenharmony_ci (C) 2002 David Woodhouse <dwmw2@infradead.org> 662306a36Sopenharmony_ci (C) 2012 Michel Lespinasse <walken@google.com> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci linux/lib/rbtree.c 1062306a36Sopenharmony_ci*/ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/rbtree_augmented.h> 1362306a36Sopenharmony_ci#include <linux/export.h> 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/* 1662306a36Sopenharmony_ci * red-black trees properties: https://en.wikipedia.org/wiki/Rbtree 1762306a36Sopenharmony_ci * 1862306a36Sopenharmony_ci * 1) A node is either red or black 1962306a36Sopenharmony_ci * 2) The root is black 2062306a36Sopenharmony_ci * 3) All leaves (NULL) are black 2162306a36Sopenharmony_ci * 4) Both children of every red node are black 2262306a36Sopenharmony_ci * 5) Every simple path from root to leaves contains the same number 2362306a36Sopenharmony_ci * of black nodes. 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two 2662306a36Sopenharmony_ci * consecutive red nodes in a path and every red node is therefore followed by 2762306a36Sopenharmony_ci * a black. So if B is the number of black nodes on every simple path (as per 2862306a36Sopenharmony_ci * 5), then the longest possible path due to 4 is 2B. 2962306a36Sopenharmony_ci * 3062306a36Sopenharmony_ci * We shall indicate color with case, where black nodes are uppercase and red 3162306a36Sopenharmony_ci * nodes will be lowercase. Unknown color nodes shall be drawn as red within 3262306a36Sopenharmony_ci * parentheses and have some accompanying text comment. 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* 3662306a36Sopenharmony_ci * Notes on lockless lookups: 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * All stores to the tree structure (rb_left and rb_right) must be done using 3962306a36Sopenharmony_ci * WRITE_ONCE(). And we must not inadvertently cause (temporary) loops in the 4062306a36Sopenharmony_ci * tree structure as seen in program order. 4162306a36Sopenharmony_ci * 4262306a36Sopenharmony_ci * These two requirements will allow lockless iteration of the tree -- not 4362306a36Sopenharmony_ci * correct iteration mind you, tree rotations are not atomic so a lookup might 4462306a36Sopenharmony_ci * miss entire subtrees. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * But they do guarantee that any such traversal will only see valid elements 4762306a36Sopenharmony_ci * and that it will indeed complete -- does not get stuck in a loop. 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci * It also guarantees that if the lookup returns an element it is the 'correct' 5062306a36Sopenharmony_ci * one. But not returning an element does _NOT_ mean it's not present. 5162306a36Sopenharmony_ci * 5262306a36Sopenharmony_ci * NOTE: 5362306a36Sopenharmony_ci * 5462306a36Sopenharmony_ci * Stores to __rb_parent_color are not important for simple lookups so those 5562306a36Sopenharmony_ci * are left undone as of now. Nor did I check for loops involving parent 5662306a36Sopenharmony_ci * pointers. 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic inline void rb_set_black(struct rb_node *rb) 6062306a36Sopenharmony_ci{ 6162306a36Sopenharmony_ci rb->__rb_parent_color += RB_BLACK; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic inline struct rb_node *rb_red_parent(struct rb_node *red) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci return (struct rb_node *)red->__rb_parent_color; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci/* 7062306a36Sopenharmony_ci * Helper function for rotations: 7162306a36Sopenharmony_ci * - old's parent and color get assigned to new 7262306a36Sopenharmony_ci * - old gets assigned new as a parent and 'color' as a color. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cistatic inline void 7562306a36Sopenharmony_ci__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, 7662306a36Sopenharmony_ci struct rb_root *root, int color) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci struct rb_node *parent = rb_parent(old); 7962306a36Sopenharmony_ci new->__rb_parent_color = old->__rb_parent_color; 8062306a36Sopenharmony_ci rb_set_parent_color(old, new, color); 8162306a36Sopenharmony_ci __rb_change_child(old, new, parent, root); 8262306a36Sopenharmony_ci} 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_cistatic __always_inline void 8562306a36Sopenharmony_ci__rb_insert(struct rb_node *node, struct rb_root *root, 8662306a36Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci while (true) { 9162306a36Sopenharmony_ci /* 9262306a36Sopenharmony_ci * Loop invariant: node is red. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci if (unlikely(!parent)) { 9562306a36Sopenharmony_ci /* 9662306a36Sopenharmony_ci * The inserted node is root. Either this is the 9762306a36Sopenharmony_ci * first node, or we recursed at Case 1 below and 9862306a36Sopenharmony_ci * are no longer violating 4). 9962306a36Sopenharmony_ci */ 10062306a36Sopenharmony_ci rb_set_parent_color(node, NULL, RB_BLACK); 10162306a36Sopenharmony_ci break; 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* 10562306a36Sopenharmony_ci * If there is a black parent, we are done. 10662306a36Sopenharmony_ci * Otherwise, take some corrective action as, 10762306a36Sopenharmony_ci * per 4), we don't want a red root or two 10862306a36Sopenharmony_ci * consecutive red nodes. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci if(rb_is_black(parent)) 11162306a36Sopenharmony_ci break; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci gparent = rb_red_parent(parent); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci tmp = gparent->rb_right; 11662306a36Sopenharmony_ci if (parent != tmp) { /* parent == gparent->rb_left */ 11762306a36Sopenharmony_ci if (tmp && rb_is_red(tmp)) { 11862306a36Sopenharmony_ci /* 11962306a36Sopenharmony_ci * Case 1 - node's uncle is red (color flips). 12062306a36Sopenharmony_ci * 12162306a36Sopenharmony_ci * G g 12262306a36Sopenharmony_ci * / \ / \ 12362306a36Sopenharmony_ci * p u --> P U 12462306a36Sopenharmony_ci * / / 12562306a36Sopenharmony_ci * n n 12662306a36Sopenharmony_ci * 12762306a36Sopenharmony_ci * However, since g's parent might be red, and 12862306a36Sopenharmony_ci * 4) does not allow this, we need to recurse 12962306a36Sopenharmony_ci * at g. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 13262306a36Sopenharmony_ci rb_set_parent_color(parent, gparent, RB_BLACK); 13362306a36Sopenharmony_ci node = gparent; 13462306a36Sopenharmony_ci parent = rb_parent(node); 13562306a36Sopenharmony_ci rb_set_parent_color(node, parent, RB_RED); 13662306a36Sopenharmony_ci continue; 13762306a36Sopenharmony_ci } 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci tmp = parent->rb_right; 14062306a36Sopenharmony_ci if (node == tmp) { 14162306a36Sopenharmony_ci /* 14262306a36Sopenharmony_ci * Case 2 - node's uncle is black and node is 14362306a36Sopenharmony_ci * the parent's right child (left rotate at parent). 14462306a36Sopenharmony_ci * 14562306a36Sopenharmony_ci * G G 14662306a36Sopenharmony_ci * / \ / \ 14762306a36Sopenharmony_ci * p U --> n U 14862306a36Sopenharmony_ci * \ / 14962306a36Sopenharmony_ci * n p 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * This still leaves us in violation of 4), the 15262306a36Sopenharmony_ci * continuation into Case 3 will fix that. 15362306a36Sopenharmony_ci */ 15462306a36Sopenharmony_ci tmp = node->rb_left; 15562306a36Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp); 15662306a36Sopenharmony_ci WRITE_ONCE(node->rb_left, parent); 15762306a36Sopenharmony_ci if (tmp) 15862306a36Sopenharmony_ci rb_set_parent_color(tmp, parent, 15962306a36Sopenharmony_ci RB_BLACK); 16062306a36Sopenharmony_ci rb_set_parent_color(parent, node, RB_RED); 16162306a36Sopenharmony_ci augment_rotate(parent, node); 16262306a36Sopenharmony_ci parent = node; 16362306a36Sopenharmony_ci tmp = node->rb_right; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci /* 16762306a36Sopenharmony_ci * Case 3 - node's uncle is black and node is 16862306a36Sopenharmony_ci * the parent's left child (right rotate at gparent). 16962306a36Sopenharmony_ci * 17062306a36Sopenharmony_ci * G P 17162306a36Sopenharmony_ci * / \ / \ 17262306a36Sopenharmony_ci * p U --> n g 17362306a36Sopenharmony_ci * / \ 17462306a36Sopenharmony_ci * n U 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ci WRITE_ONCE(gparent->rb_left, tmp); /* == parent->rb_right */ 17762306a36Sopenharmony_ci WRITE_ONCE(parent->rb_right, gparent); 17862306a36Sopenharmony_ci if (tmp) 17962306a36Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 18062306a36Sopenharmony_ci __rb_rotate_set_parents(gparent, parent, root, RB_RED); 18162306a36Sopenharmony_ci augment_rotate(gparent, parent); 18262306a36Sopenharmony_ci break; 18362306a36Sopenharmony_ci } else { 18462306a36Sopenharmony_ci tmp = gparent->rb_left; 18562306a36Sopenharmony_ci if (tmp && rb_is_red(tmp)) { 18662306a36Sopenharmony_ci /* Case 1 - color flips */ 18762306a36Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 18862306a36Sopenharmony_ci rb_set_parent_color(parent, gparent, RB_BLACK); 18962306a36Sopenharmony_ci node = gparent; 19062306a36Sopenharmony_ci parent = rb_parent(node); 19162306a36Sopenharmony_ci rb_set_parent_color(node, parent, RB_RED); 19262306a36Sopenharmony_ci continue; 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci tmp = parent->rb_left; 19662306a36Sopenharmony_ci if (node == tmp) { 19762306a36Sopenharmony_ci /* Case 2 - right rotate at parent */ 19862306a36Sopenharmony_ci tmp = node->rb_right; 19962306a36Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp); 20062306a36Sopenharmony_ci WRITE_ONCE(node->rb_right, parent); 20162306a36Sopenharmony_ci if (tmp) 20262306a36Sopenharmony_ci rb_set_parent_color(tmp, parent, 20362306a36Sopenharmony_ci RB_BLACK); 20462306a36Sopenharmony_ci rb_set_parent_color(parent, node, RB_RED); 20562306a36Sopenharmony_ci augment_rotate(parent, node); 20662306a36Sopenharmony_ci parent = node; 20762306a36Sopenharmony_ci tmp = node->rb_left; 20862306a36Sopenharmony_ci } 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci /* Case 3 - left rotate at gparent */ 21162306a36Sopenharmony_ci WRITE_ONCE(gparent->rb_right, tmp); /* == parent->rb_left */ 21262306a36Sopenharmony_ci WRITE_ONCE(parent->rb_left, gparent); 21362306a36Sopenharmony_ci if (tmp) 21462306a36Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 21562306a36Sopenharmony_ci __rb_rotate_set_parents(gparent, parent, root, RB_RED); 21662306a36Sopenharmony_ci augment_rotate(gparent, parent); 21762306a36Sopenharmony_ci break; 21862306a36Sopenharmony_ci } 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci/* 22362306a36Sopenharmony_ci * Inline version for rb_erase() use - we want to be able to inline 22462306a36Sopenharmony_ci * and eliminate the dummy_rotate callback there 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_cistatic __always_inline void 22762306a36Sopenharmony_ci____rb_erase_color(struct rb_node *parent, struct rb_root *root, 22862306a36Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci while (true) { 23362306a36Sopenharmony_ci /* 23462306a36Sopenharmony_ci * Loop invariants: 23562306a36Sopenharmony_ci * - node is black (or NULL on first iteration) 23662306a36Sopenharmony_ci * - node is not the root (parent is not NULL) 23762306a36Sopenharmony_ci * - All leaf paths going through parent and node have a 23862306a36Sopenharmony_ci * black node count that is 1 lower than other leaf paths. 23962306a36Sopenharmony_ci */ 24062306a36Sopenharmony_ci sibling = parent->rb_right; 24162306a36Sopenharmony_ci if (node != sibling) { /* node == parent->rb_left */ 24262306a36Sopenharmony_ci if (rb_is_red(sibling)) { 24362306a36Sopenharmony_ci /* 24462306a36Sopenharmony_ci * Case 1 - left rotate at parent 24562306a36Sopenharmony_ci * 24662306a36Sopenharmony_ci * P S 24762306a36Sopenharmony_ci * / \ / \ 24862306a36Sopenharmony_ci * N s --> p Sr 24962306a36Sopenharmony_ci * / \ / \ 25062306a36Sopenharmony_ci * Sl Sr N Sl 25162306a36Sopenharmony_ci */ 25262306a36Sopenharmony_ci tmp1 = sibling->rb_left; 25362306a36Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp1); 25462306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_left, parent); 25562306a36Sopenharmony_ci rb_set_parent_color(tmp1, parent, RB_BLACK); 25662306a36Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 25762306a36Sopenharmony_ci RB_RED); 25862306a36Sopenharmony_ci augment_rotate(parent, sibling); 25962306a36Sopenharmony_ci sibling = tmp1; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci tmp1 = sibling->rb_right; 26262306a36Sopenharmony_ci if (!tmp1 || rb_is_black(tmp1)) { 26362306a36Sopenharmony_ci tmp2 = sibling->rb_left; 26462306a36Sopenharmony_ci if (!tmp2 || rb_is_black(tmp2)) { 26562306a36Sopenharmony_ci /* 26662306a36Sopenharmony_ci * Case 2 - sibling color flip 26762306a36Sopenharmony_ci * (p could be either color here) 26862306a36Sopenharmony_ci * 26962306a36Sopenharmony_ci * (p) (p) 27062306a36Sopenharmony_ci * / \ / \ 27162306a36Sopenharmony_ci * N S --> N s 27262306a36Sopenharmony_ci * / \ / \ 27362306a36Sopenharmony_ci * Sl Sr Sl Sr 27462306a36Sopenharmony_ci * 27562306a36Sopenharmony_ci * This leaves us violating 5) which 27662306a36Sopenharmony_ci * can be fixed by flipping p to black 27762306a36Sopenharmony_ci * if it was red, or by recursing at p. 27862306a36Sopenharmony_ci * p is red when coming from Case 1. 27962306a36Sopenharmony_ci */ 28062306a36Sopenharmony_ci rb_set_parent_color(sibling, parent, 28162306a36Sopenharmony_ci RB_RED); 28262306a36Sopenharmony_ci if (rb_is_red(parent)) 28362306a36Sopenharmony_ci rb_set_black(parent); 28462306a36Sopenharmony_ci else { 28562306a36Sopenharmony_ci node = parent; 28662306a36Sopenharmony_ci parent = rb_parent(node); 28762306a36Sopenharmony_ci if (parent) 28862306a36Sopenharmony_ci continue; 28962306a36Sopenharmony_ci } 29062306a36Sopenharmony_ci break; 29162306a36Sopenharmony_ci } 29262306a36Sopenharmony_ci /* 29362306a36Sopenharmony_ci * Case 3 - right rotate at sibling 29462306a36Sopenharmony_ci * (p could be either color here) 29562306a36Sopenharmony_ci * 29662306a36Sopenharmony_ci * (p) (p) 29762306a36Sopenharmony_ci * / \ / \ 29862306a36Sopenharmony_ci * N S --> N sl 29962306a36Sopenharmony_ci * / \ \ 30062306a36Sopenharmony_ci * sl Sr S 30162306a36Sopenharmony_ci * \ 30262306a36Sopenharmony_ci * Sr 30362306a36Sopenharmony_ci * 30462306a36Sopenharmony_ci * Note: p might be red, and then both 30562306a36Sopenharmony_ci * p and sl are red after rotation(which 30662306a36Sopenharmony_ci * breaks property 4). This is fixed in 30762306a36Sopenharmony_ci * Case 4 (in __rb_rotate_set_parents() 30862306a36Sopenharmony_ci * which set sl the color of p 30962306a36Sopenharmony_ci * and set p RB_BLACK) 31062306a36Sopenharmony_ci * 31162306a36Sopenharmony_ci * (p) (sl) 31262306a36Sopenharmony_ci * / \ / \ 31362306a36Sopenharmony_ci * N sl --> P S 31462306a36Sopenharmony_ci * \ / \ 31562306a36Sopenharmony_ci * S N Sr 31662306a36Sopenharmony_ci * \ 31762306a36Sopenharmony_ci * Sr 31862306a36Sopenharmony_ci */ 31962306a36Sopenharmony_ci tmp1 = tmp2->rb_right; 32062306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_left, tmp1); 32162306a36Sopenharmony_ci WRITE_ONCE(tmp2->rb_right, sibling); 32262306a36Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp2); 32362306a36Sopenharmony_ci if (tmp1) 32462306a36Sopenharmony_ci rb_set_parent_color(tmp1, sibling, 32562306a36Sopenharmony_ci RB_BLACK); 32662306a36Sopenharmony_ci augment_rotate(sibling, tmp2); 32762306a36Sopenharmony_ci tmp1 = sibling; 32862306a36Sopenharmony_ci sibling = tmp2; 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci /* 33162306a36Sopenharmony_ci * Case 4 - left rotate at parent + color flips 33262306a36Sopenharmony_ci * (p and sl could be either color here. 33362306a36Sopenharmony_ci * After rotation, p becomes black, s acquires 33462306a36Sopenharmony_ci * p's color, and sl keeps its color) 33562306a36Sopenharmony_ci * 33662306a36Sopenharmony_ci * (p) (s) 33762306a36Sopenharmony_ci * / \ / \ 33862306a36Sopenharmony_ci * N S --> P Sr 33962306a36Sopenharmony_ci * / \ / \ 34062306a36Sopenharmony_ci * (sl) sr N (sl) 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci tmp2 = sibling->rb_left; 34362306a36Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp2); 34462306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_left, parent); 34562306a36Sopenharmony_ci rb_set_parent_color(tmp1, sibling, RB_BLACK); 34662306a36Sopenharmony_ci if (tmp2) 34762306a36Sopenharmony_ci rb_set_parent(tmp2, parent); 34862306a36Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 34962306a36Sopenharmony_ci RB_BLACK); 35062306a36Sopenharmony_ci augment_rotate(parent, sibling); 35162306a36Sopenharmony_ci break; 35262306a36Sopenharmony_ci } else { 35362306a36Sopenharmony_ci sibling = parent->rb_left; 35462306a36Sopenharmony_ci if (rb_is_red(sibling)) { 35562306a36Sopenharmony_ci /* Case 1 - right rotate at parent */ 35662306a36Sopenharmony_ci tmp1 = sibling->rb_right; 35762306a36Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp1); 35862306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_right, parent); 35962306a36Sopenharmony_ci rb_set_parent_color(tmp1, parent, RB_BLACK); 36062306a36Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 36162306a36Sopenharmony_ci RB_RED); 36262306a36Sopenharmony_ci augment_rotate(parent, sibling); 36362306a36Sopenharmony_ci sibling = tmp1; 36462306a36Sopenharmony_ci } 36562306a36Sopenharmony_ci tmp1 = sibling->rb_left; 36662306a36Sopenharmony_ci if (!tmp1 || rb_is_black(tmp1)) { 36762306a36Sopenharmony_ci tmp2 = sibling->rb_right; 36862306a36Sopenharmony_ci if (!tmp2 || rb_is_black(tmp2)) { 36962306a36Sopenharmony_ci /* Case 2 - sibling color flip */ 37062306a36Sopenharmony_ci rb_set_parent_color(sibling, parent, 37162306a36Sopenharmony_ci RB_RED); 37262306a36Sopenharmony_ci if (rb_is_red(parent)) 37362306a36Sopenharmony_ci rb_set_black(parent); 37462306a36Sopenharmony_ci else { 37562306a36Sopenharmony_ci node = parent; 37662306a36Sopenharmony_ci parent = rb_parent(node); 37762306a36Sopenharmony_ci if (parent) 37862306a36Sopenharmony_ci continue; 37962306a36Sopenharmony_ci } 38062306a36Sopenharmony_ci break; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci /* Case 3 - left rotate at sibling */ 38362306a36Sopenharmony_ci tmp1 = tmp2->rb_left; 38462306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_right, tmp1); 38562306a36Sopenharmony_ci WRITE_ONCE(tmp2->rb_left, sibling); 38662306a36Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp2); 38762306a36Sopenharmony_ci if (tmp1) 38862306a36Sopenharmony_ci rb_set_parent_color(tmp1, sibling, 38962306a36Sopenharmony_ci RB_BLACK); 39062306a36Sopenharmony_ci augment_rotate(sibling, tmp2); 39162306a36Sopenharmony_ci tmp1 = sibling; 39262306a36Sopenharmony_ci sibling = tmp2; 39362306a36Sopenharmony_ci } 39462306a36Sopenharmony_ci /* Case 4 - right rotate at parent + color flips */ 39562306a36Sopenharmony_ci tmp2 = sibling->rb_right; 39662306a36Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp2); 39762306a36Sopenharmony_ci WRITE_ONCE(sibling->rb_right, parent); 39862306a36Sopenharmony_ci rb_set_parent_color(tmp1, sibling, RB_BLACK); 39962306a36Sopenharmony_ci if (tmp2) 40062306a36Sopenharmony_ci rb_set_parent(tmp2, parent); 40162306a36Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 40262306a36Sopenharmony_ci RB_BLACK); 40362306a36Sopenharmony_ci augment_rotate(parent, sibling); 40462306a36Sopenharmony_ci break; 40562306a36Sopenharmony_ci } 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci/* Non-inline version for rb_erase_augmented() use */ 41062306a36Sopenharmony_civoid __rb_erase_color(struct rb_node *parent, struct rb_root *root, 41162306a36Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 41262306a36Sopenharmony_ci{ 41362306a36Sopenharmony_ci ____rb_erase_color(parent, root, augment_rotate); 41462306a36Sopenharmony_ci} 41562306a36Sopenharmony_ciEXPORT_SYMBOL(__rb_erase_color); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci/* 41862306a36Sopenharmony_ci * Non-augmented rbtree manipulation functions. 41962306a36Sopenharmony_ci * 42062306a36Sopenharmony_ci * We use dummy augmented callbacks here, and have the compiler optimize them 42162306a36Sopenharmony_ci * out of the rb_insert_color() and rb_erase() function definitions. 42262306a36Sopenharmony_ci */ 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {} 42562306a36Sopenharmony_cistatic inline void dummy_copy(struct rb_node *old, struct rb_node *new) {} 42662306a36Sopenharmony_cistatic inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {} 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic const struct rb_augment_callbacks dummy_callbacks = { 42962306a36Sopenharmony_ci .propagate = dummy_propagate, 43062306a36Sopenharmony_ci .copy = dummy_copy, 43162306a36Sopenharmony_ci .rotate = dummy_rotate 43262306a36Sopenharmony_ci}; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_civoid rb_insert_color(struct rb_node *node, struct rb_root *root) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci __rb_insert(node, root, dummy_rotate); 43762306a36Sopenharmony_ci} 43862306a36Sopenharmony_ciEXPORT_SYMBOL(rb_insert_color); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_civoid rb_erase(struct rb_node *node, struct rb_root *root) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci struct rb_node *rebalance; 44362306a36Sopenharmony_ci rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); 44462306a36Sopenharmony_ci if (rebalance) 44562306a36Sopenharmony_ci ____rb_erase_color(rebalance, root, dummy_rotate); 44662306a36Sopenharmony_ci} 44762306a36Sopenharmony_ciEXPORT_SYMBOL(rb_erase); 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci/* 45062306a36Sopenharmony_ci * Augmented rbtree manipulation functions. 45162306a36Sopenharmony_ci * 45262306a36Sopenharmony_ci * This instantiates the same __always_inline functions as in the non-augmented 45362306a36Sopenharmony_ci * case, but this time with user-defined callbacks. 45462306a36Sopenharmony_ci */ 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_civoid __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 45762306a36Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci __rb_insert(node, root, augment_rotate); 46062306a36Sopenharmony_ci} 46162306a36Sopenharmony_ciEXPORT_SYMBOL(__rb_insert_augmented); 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci/* 46462306a36Sopenharmony_ci * This function returns the first node (in sort order) of the tree. 46562306a36Sopenharmony_ci */ 46662306a36Sopenharmony_cistruct rb_node *rb_first(const struct rb_root *root) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci struct rb_node *n; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci n = root->rb_node; 47162306a36Sopenharmony_ci if (!n) 47262306a36Sopenharmony_ci return NULL; 47362306a36Sopenharmony_ci while (n->rb_left) 47462306a36Sopenharmony_ci n = n->rb_left; 47562306a36Sopenharmony_ci return n; 47662306a36Sopenharmony_ci} 47762306a36Sopenharmony_ciEXPORT_SYMBOL(rb_first); 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_cistruct rb_node *rb_last(const struct rb_root *root) 48062306a36Sopenharmony_ci{ 48162306a36Sopenharmony_ci struct rb_node *n; 48262306a36Sopenharmony_ci 48362306a36Sopenharmony_ci n = root->rb_node; 48462306a36Sopenharmony_ci if (!n) 48562306a36Sopenharmony_ci return NULL; 48662306a36Sopenharmony_ci while (n->rb_right) 48762306a36Sopenharmony_ci n = n->rb_right; 48862306a36Sopenharmony_ci return n; 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ciEXPORT_SYMBOL(rb_last); 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_cistruct rb_node *rb_next(const struct rb_node *node) 49362306a36Sopenharmony_ci{ 49462306a36Sopenharmony_ci struct rb_node *parent; 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci if (RB_EMPTY_NODE(node)) 49762306a36Sopenharmony_ci return NULL; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci /* 50062306a36Sopenharmony_ci * If we have a right-hand child, go down and then left as far 50162306a36Sopenharmony_ci * as we can. 50262306a36Sopenharmony_ci */ 50362306a36Sopenharmony_ci if (node->rb_right) { 50462306a36Sopenharmony_ci node = node->rb_right; 50562306a36Sopenharmony_ci while (node->rb_left) 50662306a36Sopenharmony_ci node = node->rb_left; 50762306a36Sopenharmony_ci return (struct rb_node *)node; 50862306a36Sopenharmony_ci } 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci /* 51162306a36Sopenharmony_ci * No right-hand children. Everything down and left is smaller than us, 51262306a36Sopenharmony_ci * so any 'next' node must be in the general direction of our parent. 51362306a36Sopenharmony_ci * Go up the tree; any time the ancestor is a right-hand child of its 51462306a36Sopenharmony_ci * parent, keep going up. First time it's a left-hand child of its 51562306a36Sopenharmony_ci * parent, said parent is our 'next' node. 51662306a36Sopenharmony_ci */ 51762306a36Sopenharmony_ci while ((parent = rb_parent(node)) && node == parent->rb_right) 51862306a36Sopenharmony_ci node = parent; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci return parent; 52162306a36Sopenharmony_ci} 52262306a36Sopenharmony_ciEXPORT_SYMBOL(rb_next); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_cistruct rb_node *rb_prev(const struct rb_node *node) 52562306a36Sopenharmony_ci{ 52662306a36Sopenharmony_ci struct rb_node *parent; 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci if (RB_EMPTY_NODE(node)) 52962306a36Sopenharmony_ci return NULL; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci /* 53262306a36Sopenharmony_ci * If we have a left-hand child, go down and then right as far 53362306a36Sopenharmony_ci * as we can. 53462306a36Sopenharmony_ci */ 53562306a36Sopenharmony_ci if (node->rb_left) { 53662306a36Sopenharmony_ci node = node->rb_left; 53762306a36Sopenharmony_ci while (node->rb_right) 53862306a36Sopenharmony_ci node = node->rb_right; 53962306a36Sopenharmony_ci return (struct rb_node *)node; 54062306a36Sopenharmony_ci } 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci /* 54362306a36Sopenharmony_ci * No left-hand children. Go up till we find an ancestor which 54462306a36Sopenharmony_ci * is a right-hand child of its parent. 54562306a36Sopenharmony_ci */ 54662306a36Sopenharmony_ci while ((parent = rb_parent(node)) && node == parent->rb_left) 54762306a36Sopenharmony_ci node = parent; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci return parent; 55062306a36Sopenharmony_ci} 55162306a36Sopenharmony_ciEXPORT_SYMBOL(rb_prev); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_civoid rb_replace_node(struct rb_node *victim, struct rb_node *new, 55462306a36Sopenharmony_ci struct rb_root *root) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci struct rb_node *parent = rb_parent(victim); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci /* Copy the pointers/colour from the victim to the replacement */ 55962306a36Sopenharmony_ci *new = *victim; 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci /* Set the surrounding nodes to point to the replacement */ 56262306a36Sopenharmony_ci if (victim->rb_left) 56362306a36Sopenharmony_ci rb_set_parent(victim->rb_left, new); 56462306a36Sopenharmony_ci if (victim->rb_right) 56562306a36Sopenharmony_ci rb_set_parent(victim->rb_right, new); 56662306a36Sopenharmony_ci __rb_change_child(victim, new, parent, root); 56762306a36Sopenharmony_ci} 56862306a36Sopenharmony_ciEXPORT_SYMBOL(rb_replace_node); 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_civoid rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, 57162306a36Sopenharmony_ci struct rb_root *root) 57262306a36Sopenharmony_ci{ 57362306a36Sopenharmony_ci struct rb_node *parent = rb_parent(victim); 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_ci /* Copy the pointers/colour from the victim to the replacement */ 57662306a36Sopenharmony_ci *new = *victim; 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci /* Set the surrounding nodes to point to the replacement */ 57962306a36Sopenharmony_ci if (victim->rb_left) 58062306a36Sopenharmony_ci rb_set_parent(victim->rb_left, new); 58162306a36Sopenharmony_ci if (victim->rb_right) 58262306a36Sopenharmony_ci rb_set_parent(victim->rb_right, new); 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci /* Set the parent's pointer to the new node last after an RCU barrier 58562306a36Sopenharmony_ci * so that the pointers onwards are seen to be set correctly when doing 58662306a36Sopenharmony_ci * an RCU walk over the tree. 58762306a36Sopenharmony_ci */ 58862306a36Sopenharmony_ci __rb_change_child_rcu(victim, new, parent, root); 58962306a36Sopenharmony_ci} 59062306a36Sopenharmony_ciEXPORT_SYMBOL(rb_replace_node_rcu); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_cistatic struct rb_node *rb_left_deepest_node(const struct rb_node *node) 59362306a36Sopenharmony_ci{ 59462306a36Sopenharmony_ci for (;;) { 59562306a36Sopenharmony_ci if (node->rb_left) 59662306a36Sopenharmony_ci node = node->rb_left; 59762306a36Sopenharmony_ci else if (node->rb_right) 59862306a36Sopenharmony_ci node = node->rb_right; 59962306a36Sopenharmony_ci else 60062306a36Sopenharmony_ci return (struct rb_node *)node; 60162306a36Sopenharmony_ci } 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_cistruct rb_node *rb_next_postorder(const struct rb_node *node) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci const struct rb_node *parent; 60762306a36Sopenharmony_ci if (!node) 60862306a36Sopenharmony_ci return NULL; 60962306a36Sopenharmony_ci parent = rb_parent(node); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci /* If we're sitting on node, we've already seen our children */ 61262306a36Sopenharmony_ci if (parent && node == parent->rb_left && parent->rb_right) { 61362306a36Sopenharmony_ci /* If we are the parent's left node, go to the parent's right 61462306a36Sopenharmony_ci * node then all the way down to the left */ 61562306a36Sopenharmony_ci return rb_left_deepest_node(parent->rb_right); 61662306a36Sopenharmony_ci } else 61762306a36Sopenharmony_ci /* Otherwise we are the parent's right node, and the parent 61862306a36Sopenharmony_ci * should be next */ 61962306a36Sopenharmony_ci return (struct rb_node *)parent; 62062306a36Sopenharmony_ci} 62162306a36Sopenharmony_ciEXPORT_SYMBOL(rb_next_postorder); 62262306a36Sopenharmony_ci 62362306a36Sopenharmony_cistruct rb_node *rb_first_postorder(const struct rb_root *root) 62462306a36Sopenharmony_ci{ 62562306a36Sopenharmony_ci if (!root->rb_node) 62662306a36Sopenharmony_ci return NULL; 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci return rb_left_deepest_node(root->rb_node); 62962306a36Sopenharmony_ci} 63062306a36Sopenharmony_ciEXPORT_SYMBOL(rb_first_postorder); 631