11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds Red Black Trees 31da177e4SLinus Torvalds (C) 1999 Andrea Arcangeli <andrea@suse.de> 41da177e4SLinus Torvalds (C) 2002 David Woodhouse <dwmw2@infradead.org> 51da177e4SLinus Torvalds 61da177e4SLinus Torvalds This program is free software; you can redistribute it and/or modify 71da177e4SLinus Torvalds it under the terms of the GNU General Public License as published by 81da177e4SLinus Torvalds the Free Software Foundation; either version 2 of the License, or 91da177e4SLinus Torvalds (at your option) any later version. 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds This program is distributed in the hope that it will be useful, 121da177e4SLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 131da177e4SLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141da177e4SLinus Torvalds GNU General Public License for more details. 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds You should have received a copy of the GNU General Public License 171da177e4SLinus Torvalds along with this program; if not, write to the Free Software 181da177e4SLinus Torvalds Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds linux/lib/rbtree.c 211da177e4SLinus Torvalds */ 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds #include <linux/rbtree.h> 241da177e4SLinus Torvalds #include <linux/module.h> 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) 271da177e4SLinus Torvalds { 281da177e4SLinus Torvalds struct rb_node *right = node->rb_right; 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds if ((node->rb_right = right->rb_left)) 311da177e4SLinus Torvalds right->rb_left->rb_parent = node; 321da177e4SLinus Torvalds right->rb_left = node; 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds if ((right->rb_parent = node->rb_parent)) 351da177e4SLinus Torvalds { 361da177e4SLinus Torvalds if (node == node->rb_parent->rb_left) 371da177e4SLinus Torvalds node->rb_parent->rb_left = right; 381da177e4SLinus Torvalds else 391da177e4SLinus Torvalds node->rb_parent->rb_right = right; 401da177e4SLinus Torvalds } 411da177e4SLinus Torvalds else 421da177e4SLinus Torvalds root->rb_node = right; 431da177e4SLinus Torvalds node->rb_parent = right; 441da177e4SLinus Torvalds } 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) 471da177e4SLinus Torvalds { 481da177e4SLinus Torvalds struct rb_node *left = node->rb_left; 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds if ((node->rb_left = left->rb_right)) 511da177e4SLinus Torvalds left->rb_right->rb_parent = node; 521da177e4SLinus Torvalds left->rb_right = node; 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds if ((left->rb_parent = node->rb_parent)) 551da177e4SLinus Torvalds { 561da177e4SLinus Torvalds if (node == node->rb_parent->rb_right) 571da177e4SLinus Torvalds node->rb_parent->rb_right = left; 581da177e4SLinus Torvalds else 591da177e4SLinus Torvalds node->rb_parent->rb_left = left; 601da177e4SLinus Torvalds } 611da177e4SLinus Torvalds else 621da177e4SLinus Torvalds root->rb_node = left; 631da177e4SLinus Torvalds node->rb_parent = left; 641da177e4SLinus Torvalds } 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds void rb_insert_color(struct rb_node *node, struct rb_root *root) 671da177e4SLinus Torvalds { 681da177e4SLinus Torvalds struct rb_node *parent, *gparent; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds while ((parent = node->rb_parent) && parent->rb_color == RB_RED) 711da177e4SLinus Torvalds { 721da177e4SLinus Torvalds gparent = parent->rb_parent; 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds if (parent == gparent->rb_left) 751da177e4SLinus Torvalds { 761da177e4SLinus Torvalds { 771da177e4SLinus Torvalds register struct rb_node *uncle = gparent->rb_right; 781da177e4SLinus Torvalds if (uncle && uncle->rb_color == RB_RED) 791da177e4SLinus Torvalds { 801da177e4SLinus Torvalds uncle->rb_color = RB_BLACK; 811da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 821da177e4SLinus Torvalds gparent->rb_color = RB_RED; 831da177e4SLinus Torvalds node = gparent; 841da177e4SLinus Torvalds continue; 851da177e4SLinus Torvalds } 861da177e4SLinus Torvalds } 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds if (parent->rb_right == node) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds register struct rb_node *tmp; 911da177e4SLinus Torvalds __rb_rotate_left(parent, root); 921da177e4SLinus Torvalds tmp = parent; 931da177e4SLinus Torvalds parent = node; 941da177e4SLinus Torvalds node = tmp; 951da177e4SLinus Torvalds } 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 981da177e4SLinus Torvalds gparent->rb_color = RB_RED; 991da177e4SLinus Torvalds __rb_rotate_right(gparent, root); 1001da177e4SLinus Torvalds } else { 1011da177e4SLinus Torvalds { 1021da177e4SLinus Torvalds register struct rb_node *uncle = gparent->rb_left; 1031da177e4SLinus Torvalds if (uncle && uncle->rb_color == RB_RED) 1041da177e4SLinus Torvalds { 1051da177e4SLinus Torvalds uncle->rb_color = RB_BLACK; 1061da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 1071da177e4SLinus Torvalds gparent->rb_color = RB_RED; 1081da177e4SLinus Torvalds node = gparent; 1091da177e4SLinus Torvalds continue; 1101da177e4SLinus Torvalds } 1111da177e4SLinus Torvalds } 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds if (parent->rb_left == node) 1141da177e4SLinus Torvalds { 1151da177e4SLinus Torvalds register struct rb_node *tmp; 1161da177e4SLinus Torvalds __rb_rotate_right(parent, root); 1171da177e4SLinus Torvalds tmp = parent; 1181da177e4SLinus Torvalds parent = node; 1191da177e4SLinus Torvalds node = tmp; 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 1231da177e4SLinus Torvalds gparent->rb_color = RB_RED; 1241da177e4SLinus Torvalds __rb_rotate_left(gparent, root); 1251da177e4SLinus Torvalds } 1261da177e4SLinus Torvalds } 1271da177e4SLinus Torvalds 1281da177e4SLinus Torvalds root->rb_node->rb_color = RB_BLACK; 1291da177e4SLinus Torvalds } 1301da177e4SLinus Torvalds EXPORT_SYMBOL(rb_insert_color); 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, 1331da177e4SLinus Torvalds struct rb_root *root) 1341da177e4SLinus Torvalds { 1351da177e4SLinus Torvalds struct rb_node *other; 1361da177e4SLinus Torvalds 1371da177e4SLinus Torvalds while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node) 1381da177e4SLinus Torvalds { 1391da177e4SLinus Torvalds if (parent->rb_left == node) 1401da177e4SLinus Torvalds { 1411da177e4SLinus Torvalds other = parent->rb_right; 1421da177e4SLinus Torvalds if (other->rb_color == RB_RED) 1431da177e4SLinus Torvalds { 1441da177e4SLinus Torvalds other->rb_color = RB_BLACK; 1451da177e4SLinus Torvalds parent->rb_color = RB_RED; 1461da177e4SLinus Torvalds __rb_rotate_left(parent, root); 1471da177e4SLinus Torvalds other = parent->rb_right; 1481da177e4SLinus Torvalds } 1491da177e4SLinus Torvalds if ((!other->rb_left || 1501da177e4SLinus Torvalds other->rb_left->rb_color == RB_BLACK) 1511da177e4SLinus Torvalds && (!other->rb_right || 1521da177e4SLinus Torvalds other->rb_right->rb_color == RB_BLACK)) 1531da177e4SLinus Torvalds { 1541da177e4SLinus Torvalds other->rb_color = RB_RED; 1551da177e4SLinus Torvalds node = parent; 1561da177e4SLinus Torvalds parent = node->rb_parent; 1571da177e4SLinus Torvalds } 1581da177e4SLinus Torvalds else 1591da177e4SLinus Torvalds { 1601da177e4SLinus Torvalds if (!other->rb_right || 1611da177e4SLinus Torvalds other->rb_right->rb_color == RB_BLACK) 1621da177e4SLinus Torvalds { 1631da177e4SLinus Torvalds register struct rb_node *o_left; 1641da177e4SLinus Torvalds if ((o_left = other->rb_left)) 1651da177e4SLinus Torvalds o_left->rb_color = RB_BLACK; 1661da177e4SLinus Torvalds other->rb_color = RB_RED; 1671da177e4SLinus Torvalds __rb_rotate_right(other, root); 1681da177e4SLinus Torvalds other = parent->rb_right; 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds other->rb_color = parent->rb_color; 1711da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 1721da177e4SLinus Torvalds if (other->rb_right) 1731da177e4SLinus Torvalds other->rb_right->rb_color = RB_BLACK; 1741da177e4SLinus Torvalds __rb_rotate_left(parent, root); 1751da177e4SLinus Torvalds node = root->rb_node; 1761da177e4SLinus Torvalds break; 1771da177e4SLinus Torvalds } 1781da177e4SLinus Torvalds } 1791da177e4SLinus Torvalds else 1801da177e4SLinus Torvalds { 1811da177e4SLinus Torvalds other = parent->rb_left; 1821da177e4SLinus Torvalds if (other->rb_color == RB_RED) 1831da177e4SLinus Torvalds { 1841da177e4SLinus Torvalds other->rb_color = RB_BLACK; 1851da177e4SLinus Torvalds parent->rb_color = RB_RED; 1861da177e4SLinus Torvalds __rb_rotate_right(parent, root); 1871da177e4SLinus Torvalds other = parent->rb_left; 1881da177e4SLinus Torvalds } 1891da177e4SLinus Torvalds if ((!other->rb_left || 1901da177e4SLinus Torvalds other->rb_left->rb_color == RB_BLACK) 1911da177e4SLinus Torvalds && (!other->rb_right || 1921da177e4SLinus Torvalds other->rb_right->rb_color == RB_BLACK)) 1931da177e4SLinus Torvalds { 1941da177e4SLinus Torvalds other->rb_color = RB_RED; 1951da177e4SLinus Torvalds node = parent; 1961da177e4SLinus Torvalds parent = node->rb_parent; 1971da177e4SLinus Torvalds } 1981da177e4SLinus Torvalds else 1991da177e4SLinus Torvalds { 2001da177e4SLinus Torvalds if (!other->rb_left || 2011da177e4SLinus Torvalds other->rb_left->rb_color == RB_BLACK) 2021da177e4SLinus Torvalds { 2031da177e4SLinus Torvalds register struct rb_node *o_right; 2041da177e4SLinus Torvalds if ((o_right = other->rb_right)) 2051da177e4SLinus Torvalds o_right->rb_color = RB_BLACK; 2061da177e4SLinus Torvalds other->rb_color = RB_RED; 2071da177e4SLinus Torvalds __rb_rotate_left(other, root); 2081da177e4SLinus Torvalds other = parent->rb_left; 2091da177e4SLinus Torvalds } 2101da177e4SLinus Torvalds other->rb_color = parent->rb_color; 2111da177e4SLinus Torvalds parent->rb_color = RB_BLACK; 2121da177e4SLinus Torvalds if (other->rb_left) 2131da177e4SLinus Torvalds other->rb_left->rb_color = RB_BLACK; 2141da177e4SLinus Torvalds __rb_rotate_right(parent, root); 2151da177e4SLinus Torvalds node = root->rb_node; 2161da177e4SLinus Torvalds break; 2171da177e4SLinus Torvalds } 2181da177e4SLinus Torvalds } 2191da177e4SLinus Torvalds } 2201da177e4SLinus Torvalds if (node) 2211da177e4SLinus Torvalds node->rb_color = RB_BLACK; 2221da177e4SLinus Torvalds } 2231da177e4SLinus Torvalds 2241da177e4SLinus Torvalds void rb_erase(struct rb_node *node, struct rb_root *root) 2251da177e4SLinus Torvalds { 2261da177e4SLinus Torvalds struct rb_node *child, *parent; 2271da177e4SLinus Torvalds int color; 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds if (!node->rb_left) 2301da177e4SLinus Torvalds child = node->rb_right; 2311da177e4SLinus Torvalds else if (!node->rb_right) 2321da177e4SLinus Torvalds child = node->rb_left; 2331da177e4SLinus Torvalds else 2341da177e4SLinus Torvalds { 2351da177e4SLinus Torvalds struct rb_node *old = node, *left; 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds node = node->rb_right; 2381da177e4SLinus Torvalds while ((left = node->rb_left) != NULL) 2391da177e4SLinus Torvalds node = left; 2401da177e4SLinus Torvalds child = node->rb_right; 2411da177e4SLinus Torvalds parent = node->rb_parent; 2421da177e4SLinus Torvalds color = node->rb_color; 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds if (child) 2451da177e4SLinus Torvalds child->rb_parent = parent; 2461da177e4SLinus Torvalds 247*1975e593SDavid Woodhouse if (node->rb_parent == old) { 248*1975e593SDavid Woodhouse parent->rb_right = child; 2491da177e4SLinus Torvalds parent = node; 250*1975e593SDavid Woodhouse } else 251*1975e593SDavid Woodhouse parent->rb_left = child; 252*1975e593SDavid Woodhouse 2531da177e4SLinus Torvalds node->rb_parent = old->rb_parent; 2541da177e4SLinus Torvalds node->rb_color = old->rb_color; 2551da177e4SLinus Torvalds node->rb_right = old->rb_right; 2561da177e4SLinus Torvalds node->rb_left = old->rb_left; 2571da177e4SLinus Torvalds 2581da177e4SLinus Torvalds if (old->rb_parent) 2591da177e4SLinus Torvalds { 2601da177e4SLinus Torvalds if (old->rb_parent->rb_left == old) 2611da177e4SLinus Torvalds old->rb_parent->rb_left = node; 2621da177e4SLinus Torvalds else 2631da177e4SLinus Torvalds old->rb_parent->rb_right = node; 2641da177e4SLinus Torvalds } else 2651da177e4SLinus Torvalds root->rb_node = node; 2661da177e4SLinus Torvalds 2671da177e4SLinus Torvalds old->rb_left->rb_parent = node; 2681da177e4SLinus Torvalds if (old->rb_right) 2691da177e4SLinus Torvalds old->rb_right->rb_parent = node; 2701da177e4SLinus Torvalds goto color; 2711da177e4SLinus Torvalds } 2721da177e4SLinus Torvalds 2731da177e4SLinus Torvalds parent = node->rb_parent; 2741da177e4SLinus Torvalds color = node->rb_color; 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds if (child) 2771da177e4SLinus Torvalds child->rb_parent = parent; 2781da177e4SLinus Torvalds if (parent) 2791da177e4SLinus Torvalds { 2801da177e4SLinus Torvalds if (parent->rb_left == node) 2811da177e4SLinus Torvalds parent->rb_left = child; 2821da177e4SLinus Torvalds else 2831da177e4SLinus Torvalds parent->rb_right = child; 2841da177e4SLinus Torvalds } 2851da177e4SLinus Torvalds else 2861da177e4SLinus Torvalds root->rb_node = child; 2871da177e4SLinus Torvalds 2881da177e4SLinus Torvalds color: 2891da177e4SLinus Torvalds if (color == RB_BLACK) 2901da177e4SLinus Torvalds __rb_erase_color(child, parent, root); 2911da177e4SLinus Torvalds } 2921da177e4SLinus Torvalds EXPORT_SYMBOL(rb_erase); 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds /* 2951da177e4SLinus Torvalds * This function returns the first node (in sort order) of the tree. 2961da177e4SLinus Torvalds */ 2971da177e4SLinus Torvalds struct rb_node *rb_first(struct rb_root *root) 2981da177e4SLinus Torvalds { 2991da177e4SLinus Torvalds struct rb_node *n; 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvalds n = root->rb_node; 3021da177e4SLinus Torvalds if (!n) 3031da177e4SLinus Torvalds return NULL; 3041da177e4SLinus Torvalds while (n->rb_left) 3051da177e4SLinus Torvalds n = n->rb_left; 3061da177e4SLinus Torvalds return n; 3071da177e4SLinus Torvalds } 3081da177e4SLinus Torvalds EXPORT_SYMBOL(rb_first); 3091da177e4SLinus Torvalds 3101da177e4SLinus Torvalds struct rb_node *rb_last(struct rb_root *root) 3111da177e4SLinus Torvalds { 3121da177e4SLinus Torvalds struct rb_node *n; 3131da177e4SLinus Torvalds 3141da177e4SLinus Torvalds n = root->rb_node; 3151da177e4SLinus Torvalds if (!n) 3161da177e4SLinus Torvalds return NULL; 3171da177e4SLinus Torvalds while (n->rb_right) 3181da177e4SLinus Torvalds n = n->rb_right; 3191da177e4SLinus Torvalds return n; 3201da177e4SLinus Torvalds } 3211da177e4SLinus Torvalds EXPORT_SYMBOL(rb_last); 3221da177e4SLinus Torvalds 3231da177e4SLinus Torvalds struct rb_node *rb_next(struct rb_node *node) 3241da177e4SLinus Torvalds { 3251da177e4SLinus Torvalds /* If we have a right-hand child, go down and then left as far 3261da177e4SLinus Torvalds as we can. */ 3271da177e4SLinus Torvalds if (node->rb_right) { 3281da177e4SLinus Torvalds node = node->rb_right; 3291da177e4SLinus Torvalds while (node->rb_left) 3301da177e4SLinus Torvalds node=node->rb_left; 3311da177e4SLinus Torvalds return node; 3321da177e4SLinus Torvalds } 3331da177e4SLinus Torvalds 3341da177e4SLinus Torvalds /* No right-hand children. Everything down and left is 3351da177e4SLinus Torvalds smaller than us, so any 'next' node must be in the general 3361da177e4SLinus Torvalds direction of our parent. Go up the tree; any time the 3371da177e4SLinus Torvalds ancestor is a right-hand child of its parent, keep going 3381da177e4SLinus Torvalds up. First time it's a left-hand child of its parent, said 3391da177e4SLinus Torvalds parent is our 'next' node. */ 3401da177e4SLinus Torvalds while (node->rb_parent && node == node->rb_parent->rb_right) 3411da177e4SLinus Torvalds node = node->rb_parent; 3421da177e4SLinus Torvalds 3431da177e4SLinus Torvalds return node->rb_parent; 3441da177e4SLinus Torvalds } 3451da177e4SLinus Torvalds EXPORT_SYMBOL(rb_next); 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds struct rb_node *rb_prev(struct rb_node *node) 3481da177e4SLinus Torvalds { 3491da177e4SLinus Torvalds /* If we have a left-hand child, go down and then right as far 3501da177e4SLinus Torvalds as we can. */ 3511da177e4SLinus Torvalds if (node->rb_left) { 3521da177e4SLinus Torvalds node = node->rb_left; 3531da177e4SLinus Torvalds while (node->rb_right) 3541da177e4SLinus Torvalds node=node->rb_right; 3551da177e4SLinus Torvalds return node; 3561da177e4SLinus Torvalds } 3571da177e4SLinus Torvalds 3581da177e4SLinus Torvalds /* No left-hand children. Go up till we find an ancestor which 3591da177e4SLinus Torvalds is a right-hand child of its parent */ 3601da177e4SLinus Torvalds while (node->rb_parent && node == node->rb_parent->rb_left) 3611da177e4SLinus Torvalds node = node->rb_parent; 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds return node->rb_parent; 3641da177e4SLinus Torvalds } 3651da177e4SLinus Torvalds EXPORT_SYMBOL(rb_prev); 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds void rb_replace_node(struct rb_node *victim, struct rb_node *new, 3681da177e4SLinus Torvalds struct rb_root *root) 3691da177e4SLinus Torvalds { 3701da177e4SLinus Torvalds struct rb_node *parent = victim->rb_parent; 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds /* Set the surrounding nodes to point to the replacement */ 3731da177e4SLinus Torvalds if (parent) { 3741da177e4SLinus Torvalds if (victim == parent->rb_left) 3751da177e4SLinus Torvalds parent->rb_left = new; 3761da177e4SLinus Torvalds else 3771da177e4SLinus Torvalds parent->rb_right = new; 3781da177e4SLinus Torvalds } else { 3791da177e4SLinus Torvalds root->rb_node = new; 3801da177e4SLinus Torvalds } 3811da177e4SLinus Torvalds if (victim->rb_left) 3821da177e4SLinus Torvalds victim->rb_left->rb_parent = new; 3831da177e4SLinus Torvalds if (victim->rb_right) 3841da177e4SLinus Torvalds victim->rb_right->rb_parent = new; 3851da177e4SLinus Torvalds 3861da177e4SLinus Torvalds /* Copy the pointers/colour from the victim to the replacement */ 3871da177e4SLinus Torvalds *new = *victim; 3881da177e4SLinus Torvalds } 3891da177e4SLinus Torvalds EXPORT_SYMBOL(rb_replace_node); 390