18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci Red Black Trees 48c2ecf20Sopenharmony_ci (C) 1999 Andrea Arcangeli <andrea@suse.de> 58c2ecf20Sopenharmony_ci (C) 2002 David Woodhouse <dwmw2@infradead.org> 68c2ecf20Sopenharmony_ci (C) 2012 Michel Lespinasse <walken@google.com> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci linux/lib/rbtree.c 108c2ecf20Sopenharmony_ci*/ 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/rbtree_augmented.h> 138c2ecf20Sopenharmony_ci#include <linux/export.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * red-black trees properties: https://en.wikipedia.org/wiki/Rbtree 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * 1) A node is either red or black 198c2ecf20Sopenharmony_ci * 2) The root is black 208c2ecf20Sopenharmony_ci * 3) All leaves (NULL) are black 218c2ecf20Sopenharmony_ci * 4) Both children of every red node are black 228c2ecf20Sopenharmony_ci * 5) Every simple path from root to leaves contains the same number 238c2ecf20Sopenharmony_ci * of black nodes. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * 4 and 5 give the O(log n) guarantee, since 4 implies you cannot have two 268c2ecf20Sopenharmony_ci * consecutive red nodes in a path and every red node is therefore followed by 278c2ecf20Sopenharmony_ci * a black. So if B is the number of black nodes on every simple path (as per 288c2ecf20Sopenharmony_ci * 5), then the longest possible path due to 4 is 2B. 298c2ecf20Sopenharmony_ci * 308c2ecf20Sopenharmony_ci * We shall indicate color with case, where black nodes are uppercase and red 318c2ecf20Sopenharmony_ci * nodes will be lowercase. Unknown color nodes shall be drawn as red within 328c2ecf20Sopenharmony_ci * parentheses and have some accompanying text comment. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* 368c2ecf20Sopenharmony_ci * Notes on lockless lookups: 378c2ecf20Sopenharmony_ci * 388c2ecf20Sopenharmony_ci * All stores to the tree structure (rb_left and rb_right) must be done using 398c2ecf20Sopenharmony_ci * WRITE_ONCE(). And we must not inadvertently cause (temporary) loops in the 408c2ecf20Sopenharmony_ci * tree structure as seen in program order. 418c2ecf20Sopenharmony_ci * 428c2ecf20Sopenharmony_ci * These two requirements will allow lockless iteration of the tree -- not 438c2ecf20Sopenharmony_ci * correct iteration mind you, tree rotations are not atomic so a lookup might 448c2ecf20Sopenharmony_ci * miss entire subtrees. 458c2ecf20Sopenharmony_ci * 468c2ecf20Sopenharmony_ci * But they do guarantee that any such traversal will only see valid elements 478c2ecf20Sopenharmony_ci * and that it will indeed complete -- does not get stuck in a loop. 488c2ecf20Sopenharmony_ci * 498c2ecf20Sopenharmony_ci * It also guarantees that if the lookup returns an element it is the 'correct' 508c2ecf20Sopenharmony_ci * one. But not returning an element does _NOT_ mean it's not present. 518c2ecf20Sopenharmony_ci * 528c2ecf20Sopenharmony_ci * NOTE: 538c2ecf20Sopenharmony_ci * 548c2ecf20Sopenharmony_ci * Stores to __rb_parent_color are not important for simple lookups so those 558c2ecf20Sopenharmony_ci * are left undone as of now. Nor did I check for loops involving parent 568c2ecf20Sopenharmony_ci * pointers. 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic inline void rb_set_black(struct rb_node *rb) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci rb->__rb_parent_color |= RB_BLACK; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_cistatic inline struct rb_node *rb_red_parent(struct rb_node *red) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci return (struct rb_node *)red->__rb_parent_color; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/* 708c2ecf20Sopenharmony_ci * Helper function for rotations: 718c2ecf20Sopenharmony_ci * - old's parent and color get assigned to new 728c2ecf20Sopenharmony_ci * - old gets assigned new as a parent and 'color' as a color. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_cistatic inline void 758c2ecf20Sopenharmony_ci__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, 768c2ecf20Sopenharmony_ci struct rb_root *root, int color) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci struct rb_node *parent = rb_parent(old); 798c2ecf20Sopenharmony_ci new->__rb_parent_color = old->__rb_parent_color; 808c2ecf20Sopenharmony_ci rb_set_parent_color(old, new, color); 818c2ecf20Sopenharmony_ci __rb_change_child(old, new, parent, root); 828c2ecf20Sopenharmony_ci} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cistatic __always_inline void 858c2ecf20Sopenharmony_ci__rb_insert(struct rb_node *node, struct rb_root *root, 868c2ecf20Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci struct rb_node *parent = rb_red_parent(node), *gparent, *tmp; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci while (true) { 918c2ecf20Sopenharmony_ci /* 928c2ecf20Sopenharmony_ci * Loop invariant: node is red. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_ci if (unlikely(!parent)) { 958c2ecf20Sopenharmony_ci /* 968c2ecf20Sopenharmony_ci * The inserted node is root. Either this is the 978c2ecf20Sopenharmony_ci * first node, or we recursed at Case 1 below and 988c2ecf20Sopenharmony_ci * are no longer violating 4). 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_ci rb_set_parent_color(node, NULL, RB_BLACK); 1018c2ecf20Sopenharmony_ci break; 1028c2ecf20Sopenharmony_ci } 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* 1058c2ecf20Sopenharmony_ci * If there is a black parent, we are done. 1068c2ecf20Sopenharmony_ci * Otherwise, take some corrective action as, 1078c2ecf20Sopenharmony_ci * per 4), we don't want a red root or two 1088c2ecf20Sopenharmony_ci * consecutive red nodes. 1098c2ecf20Sopenharmony_ci */ 1108c2ecf20Sopenharmony_ci if(rb_is_black(parent)) 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci gparent = rb_red_parent(parent); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci tmp = gparent->rb_right; 1168c2ecf20Sopenharmony_ci if (parent != tmp) { /* parent == gparent->rb_left */ 1178c2ecf20Sopenharmony_ci if (tmp && rb_is_red(tmp)) { 1188c2ecf20Sopenharmony_ci /* 1198c2ecf20Sopenharmony_ci * Case 1 - node's uncle is red (color flips). 1208c2ecf20Sopenharmony_ci * 1218c2ecf20Sopenharmony_ci * G g 1228c2ecf20Sopenharmony_ci * / \ / \ 1238c2ecf20Sopenharmony_ci * p u --> P U 1248c2ecf20Sopenharmony_ci * / / 1258c2ecf20Sopenharmony_ci * n n 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci * However, since g's parent might be red, and 1288c2ecf20Sopenharmony_ci * 4) does not allow this, we need to recurse 1298c2ecf20Sopenharmony_ci * at g. 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 1328c2ecf20Sopenharmony_ci rb_set_parent_color(parent, gparent, RB_BLACK); 1338c2ecf20Sopenharmony_ci node = gparent; 1348c2ecf20Sopenharmony_ci parent = rb_parent(node); 1358c2ecf20Sopenharmony_ci rb_set_parent_color(node, parent, RB_RED); 1368c2ecf20Sopenharmony_ci continue; 1378c2ecf20Sopenharmony_ci } 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci tmp = parent->rb_right; 1408c2ecf20Sopenharmony_ci if (node == tmp) { 1418c2ecf20Sopenharmony_ci /* 1428c2ecf20Sopenharmony_ci * Case 2 - node's uncle is black and node is 1438c2ecf20Sopenharmony_ci * the parent's right child (left rotate at parent). 1448c2ecf20Sopenharmony_ci * 1458c2ecf20Sopenharmony_ci * G G 1468c2ecf20Sopenharmony_ci * / \ / \ 1478c2ecf20Sopenharmony_ci * p U --> n U 1488c2ecf20Sopenharmony_ci * \ / 1498c2ecf20Sopenharmony_ci * n p 1508c2ecf20Sopenharmony_ci * 1518c2ecf20Sopenharmony_ci * This still leaves us in violation of 4), the 1528c2ecf20Sopenharmony_ci * continuation into Case 3 will fix that. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci tmp = node->rb_left; 1558c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp); 1568c2ecf20Sopenharmony_ci WRITE_ONCE(node->rb_left, parent); 1578c2ecf20Sopenharmony_ci if (tmp) 1588c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, parent, 1598c2ecf20Sopenharmony_ci RB_BLACK); 1608c2ecf20Sopenharmony_ci rb_set_parent_color(parent, node, RB_RED); 1618c2ecf20Sopenharmony_ci augment_rotate(parent, node); 1628c2ecf20Sopenharmony_ci parent = node; 1638c2ecf20Sopenharmony_ci tmp = node->rb_right; 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci /* 1678c2ecf20Sopenharmony_ci * Case 3 - node's uncle is black and node is 1688c2ecf20Sopenharmony_ci * the parent's left child (right rotate at gparent). 1698c2ecf20Sopenharmony_ci * 1708c2ecf20Sopenharmony_ci * G P 1718c2ecf20Sopenharmony_ci * / \ / \ 1728c2ecf20Sopenharmony_ci * p U --> n g 1738c2ecf20Sopenharmony_ci * / \ 1748c2ecf20Sopenharmony_ci * n U 1758c2ecf20Sopenharmony_ci */ 1768c2ecf20Sopenharmony_ci WRITE_ONCE(gparent->rb_left, tmp); /* == parent->rb_right */ 1778c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_right, gparent); 1788c2ecf20Sopenharmony_ci if (tmp) 1798c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 1808c2ecf20Sopenharmony_ci __rb_rotate_set_parents(gparent, parent, root, RB_RED); 1818c2ecf20Sopenharmony_ci augment_rotate(gparent, parent); 1828c2ecf20Sopenharmony_ci break; 1838c2ecf20Sopenharmony_ci } else { 1848c2ecf20Sopenharmony_ci tmp = gparent->rb_left; 1858c2ecf20Sopenharmony_ci if (tmp && rb_is_red(tmp)) { 1868c2ecf20Sopenharmony_ci /* Case 1 - color flips */ 1878c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 1888c2ecf20Sopenharmony_ci rb_set_parent_color(parent, gparent, RB_BLACK); 1898c2ecf20Sopenharmony_ci node = gparent; 1908c2ecf20Sopenharmony_ci parent = rb_parent(node); 1918c2ecf20Sopenharmony_ci rb_set_parent_color(node, parent, RB_RED); 1928c2ecf20Sopenharmony_ci continue; 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci tmp = parent->rb_left; 1968c2ecf20Sopenharmony_ci if (node == tmp) { 1978c2ecf20Sopenharmony_ci /* Case 2 - right rotate at parent */ 1988c2ecf20Sopenharmony_ci tmp = node->rb_right; 1998c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp); 2008c2ecf20Sopenharmony_ci WRITE_ONCE(node->rb_right, parent); 2018c2ecf20Sopenharmony_ci if (tmp) 2028c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, parent, 2038c2ecf20Sopenharmony_ci RB_BLACK); 2048c2ecf20Sopenharmony_ci rb_set_parent_color(parent, node, RB_RED); 2058c2ecf20Sopenharmony_ci augment_rotate(parent, node); 2068c2ecf20Sopenharmony_ci parent = node; 2078c2ecf20Sopenharmony_ci tmp = node->rb_left; 2088c2ecf20Sopenharmony_ci } 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci /* Case 3 - left rotate at gparent */ 2118c2ecf20Sopenharmony_ci WRITE_ONCE(gparent->rb_right, tmp); /* == parent->rb_left */ 2128c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_left, gparent); 2138c2ecf20Sopenharmony_ci if (tmp) 2148c2ecf20Sopenharmony_ci rb_set_parent_color(tmp, gparent, RB_BLACK); 2158c2ecf20Sopenharmony_ci __rb_rotate_set_parents(gparent, parent, root, RB_RED); 2168c2ecf20Sopenharmony_ci augment_rotate(gparent, parent); 2178c2ecf20Sopenharmony_ci break; 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci} 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci/* 2238c2ecf20Sopenharmony_ci * Inline version for rb_erase() use - we want to be able to inline 2248c2ecf20Sopenharmony_ci * and eliminate the dummy_rotate callback there 2258c2ecf20Sopenharmony_ci */ 2268c2ecf20Sopenharmony_cistatic __always_inline void 2278c2ecf20Sopenharmony_ci____rb_erase_color(struct rb_node *parent, struct rb_root *root, 2288c2ecf20Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci struct rb_node *node = NULL, *sibling, *tmp1, *tmp2; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci while (true) { 2338c2ecf20Sopenharmony_ci /* 2348c2ecf20Sopenharmony_ci * Loop invariants: 2358c2ecf20Sopenharmony_ci * - node is black (or NULL on first iteration) 2368c2ecf20Sopenharmony_ci * - node is not the root (parent is not NULL) 2378c2ecf20Sopenharmony_ci * - All leaf paths going through parent and node have a 2388c2ecf20Sopenharmony_ci * black node count that is 1 lower than other leaf paths. 2398c2ecf20Sopenharmony_ci */ 2408c2ecf20Sopenharmony_ci sibling = parent->rb_right; 2418c2ecf20Sopenharmony_ci if (node != sibling) { /* node == parent->rb_left */ 2428c2ecf20Sopenharmony_ci if (rb_is_red(sibling)) { 2438c2ecf20Sopenharmony_ci /* 2448c2ecf20Sopenharmony_ci * Case 1 - left rotate at parent 2458c2ecf20Sopenharmony_ci * 2468c2ecf20Sopenharmony_ci * P S 2478c2ecf20Sopenharmony_ci * / \ / \ 2488c2ecf20Sopenharmony_ci * N s --> p Sr 2498c2ecf20Sopenharmony_ci * / \ / \ 2508c2ecf20Sopenharmony_ci * Sl Sr N Sl 2518c2ecf20Sopenharmony_ci */ 2528c2ecf20Sopenharmony_ci tmp1 = sibling->rb_left; 2538c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp1); 2548c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_left, parent); 2558c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, parent, RB_BLACK); 2568c2ecf20Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 2578c2ecf20Sopenharmony_ci RB_RED); 2588c2ecf20Sopenharmony_ci augment_rotate(parent, sibling); 2598c2ecf20Sopenharmony_ci sibling = tmp1; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci tmp1 = sibling->rb_right; 2628c2ecf20Sopenharmony_ci if (!tmp1 || rb_is_black(tmp1)) { 2638c2ecf20Sopenharmony_ci tmp2 = sibling->rb_left; 2648c2ecf20Sopenharmony_ci if (!tmp2 || rb_is_black(tmp2)) { 2658c2ecf20Sopenharmony_ci /* 2668c2ecf20Sopenharmony_ci * Case 2 - sibling color flip 2678c2ecf20Sopenharmony_ci * (p could be either color here) 2688c2ecf20Sopenharmony_ci * 2698c2ecf20Sopenharmony_ci * (p) (p) 2708c2ecf20Sopenharmony_ci * / \ / \ 2718c2ecf20Sopenharmony_ci * N S --> N s 2728c2ecf20Sopenharmony_ci * / \ / \ 2738c2ecf20Sopenharmony_ci * Sl Sr Sl Sr 2748c2ecf20Sopenharmony_ci * 2758c2ecf20Sopenharmony_ci * This leaves us violating 5) which 2768c2ecf20Sopenharmony_ci * can be fixed by flipping p to black 2778c2ecf20Sopenharmony_ci * if it was red, or by recursing at p. 2788c2ecf20Sopenharmony_ci * p is red when coming from Case 1. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_ci rb_set_parent_color(sibling, parent, 2818c2ecf20Sopenharmony_ci RB_RED); 2828c2ecf20Sopenharmony_ci if (rb_is_red(parent)) 2838c2ecf20Sopenharmony_ci rb_set_black(parent); 2848c2ecf20Sopenharmony_ci else { 2858c2ecf20Sopenharmony_ci node = parent; 2868c2ecf20Sopenharmony_ci parent = rb_parent(node); 2878c2ecf20Sopenharmony_ci if (parent) 2888c2ecf20Sopenharmony_ci continue; 2898c2ecf20Sopenharmony_ci } 2908c2ecf20Sopenharmony_ci break; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci /* 2938c2ecf20Sopenharmony_ci * Case 3 - right rotate at sibling 2948c2ecf20Sopenharmony_ci * (p could be either color here) 2958c2ecf20Sopenharmony_ci * 2968c2ecf20Sopenharmony_ci * (p) (p) 2978c2ecf20Sopenharmony_ci * / \ / \ 2988c2ecf20Sopenharmony_ci * N S --> N sl 2998c2ecf20Sopenharmony_ci * / \ \ 3008c2ecf20Sopenharmony_ci * sl Sr S 3018c2ecf20Sopenharmony_ci * \ 3028c2ecf20Sopenharmony_ci * Sr 3038c2ecf20Sopenharmony_ci * 3048c2ecf20Sopenharmony_ci * Note: p might be red, and then both 3058c2ecf20Sopenharmony_ci * p and sl are red after rotation(which 3068c2ecf20Sopenharmony_ci * breaks property 4). This is fixed in 3078c2ecf20Sopenharmony_ci * Case 4 (in __rb_rotate_set_parents() 3088c2ecf20Sopenharmony_ci * which set sl the color of p 3098c2ecf20Sopenharmony_ci * and set p RB_BLACK) 3108c2ecf20Sopenharmony_ci * 3118c2ecf20Sopenharmony_ci * (p) (sl) 3128c2ecf20Sopenharmony_ci * / \ / \ 3138c2ecf20Sopenharmony_ci * N sl --> P S 3148c2ecf20Sopenharmony_ci * \ / \ 3158c2ecf20Sopenharmony_ci * S N Sr 3168c2ecf20Sopenharmony_ci * \ 3178c2ecf20Sopenharmony_ci * Sr 3188c2ecf20Sopenharmony_ci */ 3198c2ecf20Sopenharmony_ci tmp1 = tmp2->rb_right; 3208c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_left, tmp1); 3218c2ecf20Sopenharmony_ci WRITE_ONCE(tmp2->rb_right, sibling); 3228c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp2); 3238c2ecf20Sopenharmony_ci if (tmp1) 3248c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, sibling, 3258c2ecf20Sopenharmony_ci RB_BLACK); 3268c2ecf20Sopenharmony_ci augment_rotate(sibling, tmp2); 3278c2ecf20Sopenharmony_ci tmp1 = sibling; 3288c2ecf20Sopenharmony_ci sibling = tmp2; 3298c2ecf20Sopenharmony_ci } 3308c2ecf20Sopenharmony_ci /* 3318c2ecf20Sopenharmony_ci * Case 4 - left rotate at parent + color flips 3328c2ecf20Sopenharmony_ci * (p and sl could be either color here. 3338c2ecf20Sopenharmony_ci * After rotation, p becomes black, s acquires 3348c2ecf20Sopenharmony_ci * p's color, and sl keeps its color) 3358c2ecf20Sopenharmony_ci * 3368c2ecf20Sopenharmony_ci * (p) (s) 3378c2ecf20Sopenharmony_ci * / \ / \ 3388c2ecf20Sopenharmony_ci * N S --> P Sr 3398c2ecf20Sopenharmony_ci * / \ / \ 3408c2ecf20Sopenharmony_ci * (sl) sr N (sl) 3418c2ecf20Sopenharmony_ci */ 3428c2ecf20Sopenharmony_ci tmp2 = sibling->rb_left; 3438c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_right, tmp2); 3448c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_left, parent); 3458c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, sibling, RB_BLACK); 3468c2ecf20Sopenharmony_ci if (tmp2) 3478c2ecf20Sopenharmony_ci rb_set_parent(tmp2, parent); 3488c2ecf20Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 3498c2ecf20Sopenharmony_ci RB_BLACK); 3508c2ecf20Sopenharmony_ci augment_rotate(parent, sibling); 3518c2ecf20Sopenharmony_ci break; 3528c2ecf20Sopenharmony_ci } else { 3538c2ecf20Sopenharmony_ci sibling = parent->rb_left; 3548c2ecf20Sopenharmony_ci if (rb_is_red(sibling)) { 3558c2ecf20Sopenharmony_ci /* Case 1 - right rotate at parent */ 3568c2ecf20Sopenharmony_ci tmp1 = sibling->rb_right; 3578c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp1); 3588c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_right, parent); 3598c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, parent, RB_BLACK); 3608c2ecf20Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 3618c2ecf20Sopenharmony_ci RB_RED); 3628c2ecf20Sopenharmony_ci augment_rotate(parent, sibling); 3638c2ecf20Sopenharmony_ci sibling = tmp1; 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci tmp1 = sibling->rb_left; 3668c2ecf20Sopenharmony_ci if (!tmp1 || rb_is_black(tmp1)) { 3678c2ecf20Sopenharmony_ci tmp2 = sibling->rb_right; 3688c2ecf20Sopenharmony_ci if (!tmp2 || rb_is_black(tmp2)) { 3698c2ecf20Sopenharmony_ci /* Case 2 - sibling color flip */ 3708c2ecf20Sopenharmony_ci rb_set_parent_color(sibling, parent, 3718c2ecf20Sopenharmony_ci RB_RED); 3728c2ecf20Sopenharmony_ci if (rb_is_red(parent)) 3738c2ecf20Sopenharmony_ci rb_set_black(parent); 3748c2ecf20Sopenharmony_ci else { 3758c2ecf20Sopenharmony_ci node = parent; 3768c2ecf20Sopenharmony_ci parent = rb_parent(node); 3778c2ecf20Sopenharmony_ci if (parent) 3788c2ecf20Sopenharmony_ci continue; 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci break; 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci /* Case 3 - left rotate at sibling */ 3838c2ecf20Sopenharmony_ci tmp1 = tmp2->rb_left; 3848c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_right, tmp1); 3858c2ecf20Sopenharmony_ci WRITE_ONCE(tmp2->rb_left, sibling); 3868c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp2); 3878c2ecf20Sopenharmony_ci if (tmp1) 3888c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, sibling, 3898c2ecf20Sopenharmony_ci RB_BLACK); 3908c2ecf20Sopenharmony_ci augment_rotate(sibling, tmp2); 3918c2ecf20Sopenharmony_ci tmp1 = sibling; 3928c2ecf20Sopenharmony_ci sibling = tmp2; 3938c2ecf20Sopenharmony_ci } 3948c2ecf20Sopenharmony_ci /* Case 4 - right rotate at parent + color flips */ 3958c2ecf20Sopenharmony_ci tmp2 = sibling->rb_right; 3968c2ecf20Sopenharmony_ci WRITE_ONCE(parent->rb_left, tmp2); 3978c2ecf20Sopenharmony_ci WRITE_ONCE(sibling->rb_right, parent); 3988c2ecf20Sopenharmony_ci rb_set_parent_color(tmp1, sibling, RB_BLACK); 3998c2ecf20Sopenharmony_ci if (tmp2) 4008c2ecf20Sopenharmony_ci rb_set_parent(tmp2, parent); 4018c2ecf20Sopenharmony_ci __rb_rotate_set_parents(parent, sibling, root, 4028c2ecf20Sopenharmony_ci RB_BLACK); 4038c2ecf20Sopenharmony_ci augment_rotate(parent, sibling); 4048c2ecf20Sopenharmony_ci break; 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci } 4078c2ecf20Sopenharmony_ci} 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci/* Non-inline version for rb_erase_augmented() use */ 4108c2ecf20Sopenharmony_civoid __rb_erase_color(struct rb_node *parent, struct rb_root *root, 4118c2ecf20Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 4128c2ecf20Sopenharmony_ci{ 4138c2ecf20Sopenharmony_ci ____rb_erase_color(parent, root, augment_rotate); 4148c2ecf20Sopenharmony_ci} 4158c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__rb_erase_color); 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci/* 4188c2ecf20Sopenharmony_ci * Non-augmented rbtree manipulation functions. 4198c2ecf20Sopenharmony_ci * 4208c2ecf20Sopenharmony_ci * We use dummy augmented callbacks here, and have the compiler optimize them 4218c2ecf20Sopenharmony_ci * out of the rb_insert_color() and rb_erase() function definitions. 4228c2ecf20Sopenharmony_ci */ 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_cistatic inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {} 4258c2ecf20Sopenharmony_cistatic inline void dummy_copy(struct rb_node *old, struct rb_node *new) {} 4268c2ecf20Sopenharmony_cistatic inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {} 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_cistatic const struct rb_augment_callbacks dummy_callbacks = { 4298c2ecf20Sopenharmony_ci .propagate = dummy_propagate, 4308c2ecf20Sopenharmony_ci .copy = dummy_copy, 4318c2ecf20Sopenharmony_ci .rotate = dummy_rotate 4328c2ecf20Sopenharmony_ci}; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_civoid rb_insert_color(struct rb_node *node, struct rb_root *root) 4358c2ecf20Sopenharmony_ci{ 4368c2ecf20Sopenharmony_ci __rb_insert(node, root, dummy_rotate); 4378c2ecf20Sopenharmony_ci} 4388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_insert_color); 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_civoid rb_erase(struct rb_node *node, struct rb_root *root) 4418c2ecf20Sopenharmony_ci{ 4428c2ecf20Sopenharmony_ci struct rb_node *rebalance; 4438c2ecf20Sopenharmony_ci rebalance = __rb_erase_augmented(node, root, &dummy_callbacks); 4448c2ecf20Sopenharmony_ci if (rebalance) 4458c2ecf20Sopenharmony_ci ____rb_erase_color(rebalance, root, dummy_rotate); 4468c2ecf20Sopenharmony_ci} 4478c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_erase); 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_ci/* 4508c2ecf20Sopenharmony_ci * Augmented rbtree manipulation functions. 4518c2ecf20Sopenharmony_ci * 4528c2ecf20Sopenharmony_ci * This instantiates the same __always_inline functions as in the non-augmented 4538c2ecf20Sopenharmony_ci * case, but this time with user-defined callbacks. 4548c2ecf20Sopenharmony_ci */ 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_civoid __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 4578c2ecf20Sopenharmony_ci void (*augment_rotate)(struct rb_node *old, struct rb_node *new)) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci __rb_insert(node, root, augment_rotate); 4608c2ecf20Sopenharmony_ci} 4618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__rb_insert_augmented); 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci/* 4648c2ecf20Sopenharmony_ci * This function returns the first node (in sort order) of the tree. 4658c2ecf20Sopenharmony_ci */ 4668c2ecf20Sopenharmony_cistruct rb_node *rb_first(const struct rb_root *root) 4678c2ecf20Sopenharmony_ci{ 4688c2ecf20Sopenharmony_ci struct rb_node *n; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci n = root->rb_node; 4718c2ecf20Sopenharmony_ci if (!n) 4728c2ecf20Sopenharmony_ci return NULL; 4738c2ecf20Sopenharmony_ci while (n->rb_left) 4748c2ecf20Sopenharmony_ci n = n->rb_left; 4758c2ecf20Sopenharmony_ci return n; 4768c2ecf20Sopenharmony_ci} 4778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_first); 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistruct rb_node *rb_last(const struct rb_root *root) 4808c2ecf20Sopenharmony_ci{ 4818c2ecf20Sopenharmony_ci struct rb_node *n; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci n = root->rb_node; 4848c2ecf20Sopenharmony_ci if (!n) 4858c2ecf20Sopenharmony_ci return NULL; 4868c2ecf20Sopenharmony_ci while (n->rb_right) 4878c2ecf20Sopenharmony_ci n = n->rb_right; 4888c2ecf20Sopenharmony_ci return n; 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_last); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistruct rb_node *rb_next(const struct rb_node *node) 4938c2ecf20Sopenharmony_ci{ 4948c2ecf20Sopenharmony_ci struct rb_node *parent; 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_ci if (RB_EMPTY_NODE(node)) 4978c2ecf20Sopenharmony_ci return NULL; 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci /* 5008c2ecf20Sopenharmony_ci * If we have a right-hand child, go down and then left as far 5018c2ecf20Sopenharmony_ci * as we can. 5028c2ecf20Sopenharmony_ci */ 5038c2ecf20Sopenharmony_ci if (node->rb_right) { 5048c2ecf20Sopenharmony_ci node = node->rb_right; 5058c2ecf20Sopenharmony_ci while (node->rb_left) 5068c2ecf20Sopenharmony_ci node = node->rb_left; 5078c2ecf20Sopenharmony_ci return (struct rb_node *)node; 5088c2ecf20Sopenharmony_ci } 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_ci /* 5118c2ecf20Sopenharmony_ci * No right-hand children. Everything down and left is smaller than us, 5128c2ecf20Sopenharmony_ci * so any 'next' node must be in the general direction of our parent. 5138c2ecf20Sopenharmony_ci * Go up the tree; any time the ancestor is a right-hand child of its 5148c2ecf20Sopenharmony_ci * parent, keep going up. First time it's a left-hand child of its 5158c2ecf20Sopenharmony_ci * parent, said parent is our 'next' node. 5168c2ecf20Sopenharmony_ci */ 5178c2ecf20Sopenharmony_ci while ((parent = rb_parent(node)) && node == parent->rb_right) 5188c2ecf20Sopenharmony_ci node = parent; 5198c2ecf20Sopenharmony_ci 5208c2ecf20Sopenharmony_ci return parent; 5218c2ecf20Sopenharmony_ci} 5228c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_next); 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_cistruct rb_node *rb_prev(const struct rb_node *node) 5258c2ecf20Sopenharmony_ci{ 5268c2ecf20Sopenharmony_ci struct rb_node *parent; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci if (RB_EMPTY_NODE(node)) 5298c2ecf20Sopenharmony_ci return NULL; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci /* 5328c2ecf20Sopenharmony_ci * If we have a left-hand child, go down and then right as far 5338c2ecf20Sopenharmony_ci * as we can. 5348c2ecf20Sopenharmony_ci */ 5358c2ecf20Sopenharmony_ci if (node->rb_left) { 5368c2ecf20Sopenharmony_ci node = node->rb_left; 5378c2ecf20Sopenharmony_ci while (node->rb_right) 5388c2ecf20Sopenharmony_ci node = node->rb_right; 5398c2ecf20Sopenharmony_ci return (struct rb_node *)node; 5408c2ecf20Sopenharmony_ci } 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci /* 5438c2ecf20Sopenharmony_ci * No left-hand children. Go up till we find an ancestor which 5448c2ecf20Sopenharmony_ci * is a right-hand child of its parent. 5458c2ecf20Sopenharmony_ci */ 5468c2ecf20Sopenharmony_ci while ((parent = rb_parent(node)) && node == parent->rb_left) 5478c2ecf20Sopenharmony_ci node = parent; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci return parent; 5508c2ecf20Sopenharmony_ci} 5518c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_prev); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_civoid rb_replace_node(struct rb_node *victim, struct rb_node *new, 5548c2ecf20Sopenharmony_ci struct rb_root *root) 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci struct rb_node *parent = rb_parent(victim); 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci /* Copy the pointers/colour from the victim to the replacement */ 5598c2ecf20Sopenharmony_ci *new = *victim; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci /* Set the surrounding nodes to point to the replacement */ 5628c2ecf20Sopenharmony_ci if (victim->rb_left) 5638c2ecf20Sopenharmony_ci rb_set_parent(victim->rb_left, new); 5648c2ecf20Sopenharmony_ci if (victim->rb_right) 5658c2ecf20Sopenharmony_ci rb_set_parent(victim->rb_right, new); 5668c2ecf20Sopenharmony_ci __rb_change_child(victim, new, parent, root); 5678c2ecf20Sopenharmony_ci} 5688c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_replace_node); 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_civoid rb_replace_node_rcu(struct rb_node *victim, struct rb_node *new, 5718c2ecf20Sopenharmony_ci struct rb_root *root) 5728c2ecf20Sopenharmony_ci{ 5738c2ecf20Sopenharmony_ci struct rb_node *parent = rb_parent(victim); 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci /* Copy the pointers/colour from the victim to the replacement */ 5768c2ecf20Sopenharmony_ci *new = *victim; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci /* Set the surrounding nodes to point to the replacement */ 5798c2ecf20Sopenharmony_ci if (victim->rb_left) 5808c2ecf20Sopenharmony_ci rb_set_parent(victim->rb_left, new); 5818c2ecf20Sopenharmony_ci if (victim->rb_right) 5828c2ecf20Sopenharmony_ci rb_set_parent(victim->rb_right, new); 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci /* Set the parent's pointer to the new node last after an RCU barrier 5858c2ecf20Sopenharmony_ci * so that the pointers onwards are seen to be set correctly when doing 5868c2ecf20Sopenharmony_ci * an RCU walk over the tree. 5878c2ecf20Sopenharmony_ci */ 5888c2ecf20Sopenharmony_ci __rb_change_child_rcu(victim, new, parent, root); 5898c2ecf20Sopenharmony_ci} 5908c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_replace_node_rcu); 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_cistatic struct rb_node *rb_left_deepest_node(const struct rb_node *node) 5938c2ecf20Sopenharmony_ci{ 5948c2ecf20Sopenharmony_ci for (;;) { 5958c2ecf20Sopenharmony_ci if (node->rb_left) 5968c2ecf20Sopenharmony_ci node = node->rb_left; 5978c2ecf20Sopenharmony_ci else if (node->rb_right) 5988c2ecf20Sopenharmony_ci node = node->rb_right; 5998c2ecf20Sopenharmony_ci else 6008c2ecf20Sopenharmony_ci return (struct rb_node *)node; 6018c2ecf20Sopenharmony_ci } 6028c2ecf20Sopenharmony_ci} 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_cistruct rb_node *rb_next_postorder(const struct rb_node *node) 6058c2ecf20Sopenharmony_ci{ 6068c2ecf20Sopenharmony_ci const struct rb_node *parent; 6078c2ecf20Sopenharmony_ci if (!node) 6088c2ecf20Sopenharmony_ci return NULL; 6098c2ecf20Sopenharmony_ci parent = rb_parent(node); 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci /* If we're sitting on node, we've already seen our children */ 6128c2ecf20Sopenharmony_ci if (parent && node == parent->rb_left && parent->rb_right) { 6138c2ecf20Sopenharmony_ci /* If we are the parent's left node, go to the parent's right 6148c2ecf20Sopenharmony_ci * node then all the way down to the left */ 6158c2ecf20Sopenharmony_ci return rb_left_deepest_node(parent->rb_right); 6168c2ecf20Sopenharmony_ci } else 6178c2ecf20Sopenharmony_ci /* Otherwise we are the parent's right node, and the parent 6188c2ecf20Sopenharmony_ci * should be next */ 6198c2ecf20Sopenharmony_ci return (struct rb_node *)parent; 6208c2ecf20Sopenharmony_ci} 6218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_next_postorder); 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistruct rb_node *rb_first_postorder(const struct rb_root *root) 6248c2ecf20Sopenharmony_ci{ 6258c2ecf20Sopenharmony_ci if (!root->rb_node) 6268c2ecf20Sopenharmony_ci return NULL; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci return rb_left_deepest_node(root->rb_node); 6298c2ecf20Sopenharmony_ci} 6308c2ecf20Sopenharmony_ciEXPORT_SYMBOL(rb_first_postorder); 631