1 /* SPDX-License-Identifier: GPL-2.0-or-later * 1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 2 /* 3 Red Black Trees 3 Red Black Trees 4 (C) 1999 Andrea Arcangeli <andrea@suse.de> 4 (C) 1999 Andrea Arcangeli <andrea@suse.de> 5 (C) 2002 David Woodhouse <dwmw2@infradead.o 5 (C) 2002 David Woodhouse <dwmw2@infradead.org> 6 (C) 2012 Michel Lespinasse <walken@google.c 6 (C) 2012 Michel Lespinasse <walken@google.com> 7 7 8 8 9 linux/include/linux/rbtree_augmented.h 9 linux/include/linux/rbtree_augmented.h 10 */ 10 */ 11 11 12 #ifndef _LINUX_RBTREE_AUGMENTED_H 12 #ifndef _LINUX_RBTREE_AUGMENTED_H 13 #define _LINUX_RBTREE_AUGMENTED_H 13 #define _LINUX_RBTREE_AUGMENTED_H 14 14 15 #include <linux/compiler.h> 15 #include <linux/compiler.h> 16 #include <linux/rbtree.h> 16 #include <linux/rbtree.h> 17 #include <linux/rcupdate.h> 17 #include <linux/rcupdate.h> 18 18 19 /* 19 /* 20 * Please note - only struct rb_augment_callba 20 * Please note - only struct rb_augment_callbacks and the prototypes for 21 * rb_insert_augmented() and rb_erase_augmente 21 * rb_insert_augmented() and rb_erase_augmented() are intended to be public. 22 * The rest are implementation details you are 22 * The rest are implementation details you are not expected to depend on. 23 * 23 * 24 * See Documentation/core-api/rbtree.rst for d 24 * See Documentation/core-api/rbtree.rst for documentation and samples. 25 */ 25 */ 26 26 27 struct rb_augment_callbacks { 27 struct rb_augment_callbacks { 28 void (*propagate)(struct rb_node *node 28 void (*propagate)(struct rb_node *node, struct rb_node *stop); 29 void (*copy)(struct rb_node *old, stru 29 void (*copy)(struct rb_node *old, struct rb_node *new); 30 void (*rotate)(struct rb_node *old, st 30 void (*rotate)(struct rb_node *old, struct rb_node *new); 31 }; 31 }; 32 32 33 extern void __rb_insert_augmented(struct rb_no 33 extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root, 34 void (*augment_rotate)(struct rb_node 34 void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); 35 35 36 /* 36 /* 37 * Fixup the rbtree and update the augmented i 37 * Fixup the rbtree and update the augmented information when rebalancing. 38 * 38 * 39 * On insertion, the user must update the augm 39 * On insertion, the user must update the augmented information on the path 40 * leading to the inserted node, then call rb_ 40 * leading to the inserted node, then call rb_link_node() as usual and 41 * rb_insert_augmented() instead of the usual 41 * rb_insert_augmented() instead of the usual rb_insert_color() call. 42 * If rb_insert_augmented() rebalances the rbt 42 * If rb_insert_augmented() rebalances the rbtree, it will callback into 43 * a user provided function to update the augm 43 * a user provided function to update the augmented information on the 44 * affected subtrees. 44 * affected subtrees. 45 */ 45 */ 46 static inline void 46 static inline void 47 rb_insert_augmented(struct rb_node *node, stru 47 rb_insert_augmented(struct rb_node *node, struct rb_root *root, 48 const struct rb_augment_ca 48 const struct rb_augment_callbacks *augment) 49 { 49 { 50 __rb_insert_augmented(node, root, augm 50 __rb_insert_augmented(node, root, augment->rotate); 51 } 51 } 52 52 53 static inline void 53 static inline void 54 rb_insert_augmented_cached(struct rb_node *nod 54 rb_insert_augmented_cached(struct rb_node *node, 55 struct rb_root_cach 55 struct rb_root_cached *root, bool newleft, 56 const struct rb_aug 56 const struct rb_augment_callbacks *augment) 57 { 57 { 58 if (newleft) 58 if (newleft) 59 root->rb_leftmost = node; 59 root->rb_leftmost = node; 60 rb_insert_augmented(node, &root->rb_ro 60 rb_insert_augmented(node, &root->rb_root, augment); 61 } 61 } 62 62 63 static __always_inline struct rb_node * << 64 rb_add_augmented_cached(struct rb_node *node, << 65 bool (*less)(struct rb << 66 const struct rb_augmen << 67 { << 68 struct rb_node **link = &tree->rb_root << 69 struct rb_node *parent = NULL; << 70 bool leftmost = true; << 71 << 72 while (*link) { << 73 parent = *link; << 74 if (less(node, parent)) { << 75 link = &parent->rb_lef << 76 } else { << 77 link = &parent->rb_rig << 78 leftmost = false; << 79 } << 80 } << 81 << 82 rb_link_node(node, parent, link); << 83 augment->propagate(parent, NULL); /* s << 84 rb_insert_augmented_cached(node, tree, << 85 << 86 return leftmost ? node : NULL; << 87 } << 88 << 89 /* 63 /* 90 * Template for declaring augmented rbtree cal 64 * Template for declaring augmented rbtree callbacks (generic case) 91 * 65 * 92 * RBSTATIC: 'static' or empty 66 * RBSTATIC: 'static' or empty 93 * RBNAME: name of the rb_augment_callbac 67 * RBNAME: name of the rb_augment_callbacks structure 94 * RBSTRUCT: struct type of the tree nodes 68 * RBSTRUCT: struct type of the tree nodes 95 * RBFIELD: name of struct rb_node field w 69 * RBFIELD: name of struct rb_node field within RBSTRUCT 96 * RBAUGMENTED: name of field within RBSTRUCT 70 * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree 97 * RBCOMPUTE: name of function that recomput 71 * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data 98 */ 72 */ 99 73 100 #define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, 74 #define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ 101 RBSTRUCT, RBFIELD 75 RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \ 102 static inline void 76 static inline void \ 103 RBNAME ## _propagate(struct rb_node *rb, struc 77 RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \ 104 { 78 { \ 105 while (rb != stop) { 79 while (rb != stop) { \ 106 RBSTRUCT *node = rb_entry(rb, 80 RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \ 107 if (RBCOMPUTE(node, true)) 81 if (RBCOMPUTE(node, true)) \ 108 break; 82 break; \ 109 rb = rb_parent(&node->RBFIELD) 83 rb = rb_parent(&node->RBFIELD); \ 110 } 84 } \ 111 } 85 } \ 112 static inline void 86 static inline void \ 113 RBNAME ## _copy(struct rb_node *rb_old, struct 87 RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \ 114 { 88 { \ 115 RBSTRUCT *old = rb_entry(rb_old, RBSTR 89 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ 116 RBSTRUCT *new = rb_entry(rb_new, RBSTR 90 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ 117 new->RBAUGMENTED = old->RBAUGMENTED; 91 new->RBAUGMENTED = old->RBAUGMENTED; \ 118 } 92 } \ 119 static void 93 static void \ 120 RBNAME ## _rotate(struct rb_node *rb_old, stru 94 RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \ 121 { 95 { \ 122 RBSTRUCT *old = rb_entry(rb_old, RBSTR 96 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \ 123 RBSTRUCT *new = rb_entry(rb_new, RBSTR 97 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \ 124 new->RBAUGMENTED = old->RBAUGMENTED; 98 new->RBAUGMENTED = old->RBAUGMENTED; \ 125 RBCOMPUTE(old, false); 99 RBCOMPUTE(old, false); \ 126 } 100 } \ 127 RBSTATIC const struct rb_augment_callbacks RBN 101 RBSTATIC const struct rb_augment_callbacks RBNAME = { \ 128 .propagate = RBNAME ## _propagate, 102 .propagate = RBNAME ## _propagate, \ 129 .copy = RBNAME ## _copy, 103 .copy = RBNAME ## _copy, \ 130 .rotate = RBNAME ## _rotate 104 .rotate = RBNAME ## _rotate \ 131 }; 105 }; 132 106 133 /* 107 /* 134 * Template for declaring augmented rbtree cal 108 * Template for declaring augmented rbtree callbacks, 135 * computing RBAUGMENTED scalar as max(RBCOMPU 109 * computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes. 136 * 110 * 137 * RBSTATIC: 'static' or empty 111 * RBSTATIC: 'static' or empty 138 * RBNAME: name of the rb_augment_callbac 112 * RBNAME: name of the rb_augment_callbacks structure 139 * RBSTRUCT: struct type of the tree nodes 113 * RBSTRUCT: struct type of the tree nodes 140 * RBFIELD: name of struct rb_node field w 114 * RBFIELD: name of struct rb_node field within RBSTRUCT 141 * RBTYPE: type of the RBAUGMENTED field 115 * RBTYPE: type of the RBAUGMENTED field 142 * RBAUGMENTED: name of RBTYPE field within RB 116 * RBAUGMENTED: name of RBTYPE field within RBSTRUCT holding data for subtree 143 * RBCOMPUTE: name of function that returns 117 * RBCOMPUTE: name of function that returns the per-node RBTYPE scalar 144 */ 118 */ 145 119 146 #define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBN 120 #define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \ 147 RBTYPE, RBAUG 121 RBTYPE, RBAUGMENTED, RBCOMPUTE) \ 148 static inline bool RBNAME ## _compute_max(RBST 122 static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \ 149 { 123 { \ 150 RBSTRUCT *child; 124 RBSTRUCT *child; \ 151 RBTYPE max = RBCOMPUTE(node); 125 RBTYPE max = RBCOMPUTE(node); \ 152 if (node->RBFIELD.rb_left) { 126 if (node->RBFIELD.rb_left) { \ 153 child = rb_entry(node->RBFIELD 127 child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \ 154 if (child->RBAUGMENTED > max) 128 if (child->RBAUGMENTED > max) \ 155 max = child->RBAUGMENT 129 max = child->RBAUGMENTED; \ 156 } 130 } \ 157 if (node->RBFIELD.rb_right) { 131 if (node->RBFIELD.rb_right) { \ 158 child = rb_entry(node->RBFIELD 132 child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \ 159 if (child->RBAUGMENTED > max) 133 if (child->RBAUGMENTED > max) \ 160 max = child->RBAUGMENT 134 max = child->RBAUGMENTED; \ 161 } 135 } \ 162 if (exit && node->RBAUGMENTED == max) 136 if (exit && node->RBAUGMENTED == max) \ 163 return true; 137 return true; \ 164 node->RBAUGMENTED = max; 138 node->RBAUGMENTED = max; \ 165 return false; 139 return false; \ 166 } 140 } \ 167 RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, 141 RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \ 168 RBSTRUCT, RBFIELD, RBAUGM 142 RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max) 169 143 170 144 171 #define RB_RED 0 145 #define RB_RED 0 172 #define RB_BLACK 1 146 #define RB_BLACK 1 173 147 174 #define __rb_parent(pc) ((struct rb_node *) 148 #define __rb_parent(pc) ((struct rb_node *)(pc & ~3)) 175 149 176 #define __rb_color(pc) ((pc) & 1) 150 #define __rb_color(pc) ((pc) & 1) 177 #define __rb_is_black(pc) __rb_color(pc) 151 #define __rb_is_black(pc) __rb_color(pc) 178 #define __rb_is_red(pc) (!__rb_color(pc)) 152 #define __rb_is_red(pc) (!__rb_color(pc)) 179 #define rb_color(rb) __rb_color((rb)->__ 153 #define rb_color(rb) __rb_color((rb)->__rb_parent_color) 180 #define rb_is_red(rb) __rb_is_red((rb)->_ 154 #define rb_is_red(rb) __rb_is_red((rb)->__rb_parent_color) 181 #define rb_is_black(rb) __rb_is_black((rb)- 155 #define rb_is_black(rb) __rb_is_black((rb)->__rb_parent_color) 182 156 183 static inline void rb_set_parent(struct rb_nod 157 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) 184 { 158 { 185 rb->__rb_parent_color = rb_color(rb) + !! 159 rb->__rb_parent_color = rb_color(rb) | (unsigned long)p; 186 } 160 } 187 161 188 static inline void rb_set_parent_color(struct 162 static inline void rb_set_parent_color(struct rb_node *rb, 189 struct 163 struct rb_node *p, int color) 190 { 164 { 191 rb->__rb_parent_color = (unsigned long !! 165 rb->__rb_parent_color = (unsigned long)p | color; 192 } 166 } 193 167 194 static inline void 168 static inline void 195 __rb_change_child(struct rb_node *old, struct 169 __rb_change_child(struct rb_node *old, struct rb_node *new, 196 struct rb_node *parent, stru 170 struct rb_node *parent, struct rb_root *root) 197 { 171 { 198 if (parent) { 172 if (parent) { 199 if (parent->rb_left == old) 173 if (parent->rb_left == old) 200 WRITE_ONCE(parent->rb_ 174 WRITE_ONCE(parent->rb_left, new); 201 else 175 else 202 WRITE_ONCE(parent->rb_ 176 WRITE_ONCE(parent->rb_right, new); 203 } else 177 } else 204 WRITE_ONCE(root->rb_node, new) 178 WRITE_ONCE(root->rb_node, new); 205 } 179 } 206 180 207 static inline void 181 static inline void 208 __rb_change_child_rcu(struct rb_node *old, str 182 __rb_change_child_rcu(struct rb_node *old, struct rb_node *new, 209 struct rb_node *parent, 183 struct rb_node *parent, struct rb_root *root) 210 { 184 { 211 if (parent) { 185 if (parent) { 212 if (parent->rb_left == old) 186 if (parent->rb_left == old) 213 rcu_assign_pointer(par 187 rcu_assign_pointer(parent->rb_left, new); 214 else 188 else 215 rcu_assign_pointer(par 189 rcu_assign_pointer(parent->rb_right, new); 216 } else 190 } else 217 rcu_assign_pointer(root->rb_no 191 rcu_assign_pointer(root->rb_node, new); 218 } 192 } 219 193 220 extern void __rb_erase_color(struct rb_node *p 194 extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root, 221 void (*augment_rotate)(struct rb_node 195 void (*augment_rotate)(struct rb_node *old, struct rb_node *new)); 222 196 223 static __always_inline struct rb_node * 197 static __always_inline struct rb_node * 224 __rb_erase_augmented(struct rb_node *node, str 198 __rb_erase_augmented(struct rb_node *node, struct rb_root *root, 225 const struct rb_augment_c 199 const struct rb_augment_callbacks *augment) 226 { 200 { 227 struct rb_node *child = node->rb_right 201 struct rb_node *child = node->rb_right; 228 struct rb_node *tmp = node->rb_left; 202 struct rb_node *tmp = node->rb_left; 229 struct rb_node *parent, *rebalance; 203 struct rb_node *parent, *rebalance; 230 unsigned long pc; 204 unsigned long pc; 231 205 232 if (!tmp) { 206 if (!tmp) { 233 /* 207 /* 234 * Case 1: node to erase has n 208 * Case 1: node to erase has no more than 1 child (easy!) 235 * 209 * 236 * Note that if there is one c 210 * Note that if there is one child it must be red due to 5) 237 * and node must be black due 211 * and node must be black due to 4). We adjust colors locally 238 * so as to bypass __rb_erase_ 212 * so as to bypass __rb_erase_color() later on. 239 */ 213 */ 240 pc = node->__rb_parent_color; 214 pc = node->__rb_parent_color; 241 parent = __rb_parent(pc); 215 parent = __rb_parent(pc); 242 __rb_change_child(node, child, 216 __rb_change_child(node, child, parent, root); 243 if (child) { 217 if (child) { 244 child->__rb_parent_col 218 child->__rb_parent_color = pc; 245 rebalance = NULL; 219 rebalance = NULL; 246 } else 220 } else 247 rebalance = __rb_is_bl 221 rebalance = __rb_is_black(pc) ? parent : NULL; 248 tmp = parent; 222 tmp = parent; 249 } else if (!child) { 223 } else if (!child) { 250 /* Still case 1, but this time 224 /* Still case 1, but this time the child is node->rb_left */ 251 tmp->__rb_parent_color = pc = 225 tmp->__rb_parent_color = pc = node->__rb_parent_color; 252 parent = __rb_parent(pc); 226 parent = __rb_parent(pc); 253 __rb_change_child(node, tmp, p 227 __rb_change_child(node, tmp, parent, root); 254 rebalance = NULL; 228 rebalance = NULL; 255 tmp = parent; 229 tmp = parent; 256 } else { 230 } else { 257 struct rb_node *successor = ch 231 struct rb_node *successor = child, *child2; 258 232 259 tmp = child->rb_left; 233 tmp = child->rb_left; 260 if (!tmp) { 234 if (!tmp) { 261 /* 235 /* 262 * Case 2: node's succ 236 * Case 2: node's successor is its right child 263 * 237 * 264 * (n) (s) 238 * (n) (s) 265 * / \ / \ 239 * / \ / \ 266 * (x) (s) -> (x) ( 240 * (x) (s) -> (x) (c) 267 * \ 241 * \ 268 * (c) 242 * (c) 269 */ 243 */ 270 parent = successor; 244 parent = successor; 271 child2 = successor->rb 245 child2 = successor->rb_right; 272 246 273 augment->copy(node, su 247 augment->copy(node, successor); 274 } else { 248 } else { 275 /* 249 /* 276 * Case 3: node's succ 250 * Case 3: node's successor is leftmost under 277 * node's right child 251 * node's right child subtree 278 * 252 * 279 * (n) (s) 253 * (n) (s) 280 * / \ / \ 254 * / \ / \ 281 * (x) (y) -> (x) ( 255 * (x) (y) -> (x) (y) 282 * / / 256 * / / 283 * (p) (p) 257 * (p) (p) 284 * / / 258 * / / 285 * (s) (c) 259 * (s) (c) 286 * \ 260 * \ 287 * (c) 261 * (c) 288 */ 262 */ 289 do { 263 do { 290 parent = succe 264 parent = successor; 291 successor = tm 265 successor = tmp; 292 tmp = tmp->rb_ 266 tmp = tmp->rb_left; 293 } while (tmp); 267 } while (tmp); 294 child2 = successor->rb 268 child2 = successor->rb_right; 295 WRITE_ONCE(parent->rb_ 269 WRITE_ONCE(parent->rb_left, child2); 296 WRITE_ONCE(successor-> 270 WRITE_ONCE(successor->rb_right, child); 297 rb_set_parent(child, s 271 rb_set_parent(child, successor); 298 272 299 augment->copy(node, su 273 augment->copy(node, successor); 300 augment->propagate(par 274 augment->propagate(parent, successor); 301 } 275 } 302 276 303 tmp = node->rb_left; 277 tmp = node->rb_left; 304 WRITE_ONCE(successor->rb_left, 278 WRITE_ONCE(successor->rb_left, tmp); 305 rb_set_parent(tmp, successor); 279 rb_set_parent(tmp, successor); 306 280 307 pc = node->__rb_parent_color; 281 pc = node->__rb_parent_color; 308 tmp = __rb_parent(pc); 282 tmp = __rb_parent(pc); 309 __rb_change_child(node, succes 283 __rb_change_child(node, successor, tmp, root); 310 284 311 if (child2) { 285 if (child2) { 312 rb_set_parent_color(ch 286 rb_set_parent_color(child2, parent, RB_BLACK); 313 rebalance = NULL; 287 rebalance = NULL; 314 } else { 288 } else { 315 rebalance = rb_is_blac 289 rebalance = rb_is_black(successor) ? parent : NULL; 316 } 290 } 317 successor->__rb_parent_color = 291 successor->__rb_parent_color = pc; 318 tmp = successor; 292 tmp = successor; 319 } 293 } 320 294 321 augment->propagate(tmp, NULL); 295 augment->propagate(tmp, NULL); 322 return rebalance; 296 return rebalance; 323 } 297 } 324 298 325 static __always_inline void 299 static __always_inline void 326 rb_erase_augmented(struct rb_node *node, struc 300 rb_erase_augmented(struct rb_node *node, struct rb_root *root, 327 const struct rb_augment_cal 301 const struct rb_augment_callbacks *augment) 328 { 302 { 329 struct rb_node *rebalance = __rb_erase 303 struct rb_node *rebalance = __rb_erase_augmented(node, root, augment); 330 if (rebalance) 304 if (rebalance) 331 __rb_erase_color(rebalance, ro 305 __rb_erase_color(rebalance, root, augment->rotate); 332 } 306 } 333 307 334 static __always_inline void 308 static __always_inline void 335 rb_erase_augmented_cached(struct rb_node *node 309 rb_erase_augmented_cached(struct rb_node *node, struct rb_root_cached *root, 336 const struct rb_augm 310 const struct rb_augment_callbacks *augment) 337 { 311 { 338 if (root->rb_leftmost == node) 312 if (root->rb_leftmost == node) 339 root->rb_leftmost = rb_next(no 313 root->rb_leftmost = rb_next(node); 340 rb_erase_augmented(node, &root->rb_roo 314 rb_erase_augmented(node, &root->rb_root, augment); 341 } 315 } 342 316 343 #endif /* _LINUX_RBTREE_AUGMENTED_H */ 317 #endif /* _LINUX_RBTREE_AUGMENTED_H */ 344 318
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.