0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef _LINUX_RBTREE_AUGMENTED_H
0013 #define _LINUX_RBTREE_AUGMENTED_H
0014
0015 #include <linux/compiler.h>
0016 #include <linux/rbtree.h>
0017 #include <linux/rcupdate.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 struct rb_augment_callbacks {
0028 void (*propagate)(struct rb_node *node, struct rb_node *stop);
0029 void (*copy)(struct rb_node *old, struct rb_node *new);
0030 void (*rotate)(struct rb_node *old, struct rb_node *new);
0031 };
0032
0033 extern void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
0034 void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 static inline void
0047 rb_insert_augmented(struct rb_node *node, struct rb_root *root,
0048 const struct rb_augment_callbacks *augment)
0049 {
0050 __rb_insert_augmented(node, root, augment->rotate);
0051 }
0052
0053 static inline void
0054 rb_insert_augmented_cached(struct rb_node *node,
0055 struct rb_root_cached *root, bool newleft,
0056 const struct rb_augment_callbacks *augment)
0057 {
0058 if (newleft)
0059 root->rb_leftmost = node;
0060 rb_insert_augmented(node, &root->rb_root, augment);
0061 }
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 #define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
0075 RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
0076 static inline void \
0077 RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
0078 { \
0079 while (rb != stop) { \
0080 RBSTRUCT *node = rb_entry(rb, RBSTRUCT, RBFIELD); \
0081 if (RBCOMPUTE(node, true)) \
0082 break; \
0083 rb = rb_parent(&node->RBFIELD); \
0084 } \
0085 } \
0086 static inline void \
0087 RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
0088 { \
0089 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
0090 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
0091 new->RBAUGMENTED = old->RBAUGMENTED; \
0092 } \
0093 static void \
0094 RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
0095 { \
0096 RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
0097 RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
0098 new->RBAUGMENTED = old->RBAUGMENTED; \
0099 RBCOMPUTE(old, false); \
0100 } \
0101 RBSTATIC const struct rb_augment_callbacks RBNAME = { \
0102 .propagate = RBNAME ## _propagate, \
0103 .copy = RBNAME ## _copy, \
0104 .rotate = RBNAME ## _rotate \
0105 };
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 #define RB_DECLARE_CALLBACKS_MAX(RBSTATIC, RBNAME, RBSTRUCT, RBFIELD, \
0121 RBTYPE, RBAUGMENTED, RBCOMPUTE) \
0122 static inline bool RBNAME ## _compute_max(RBSTRUCT *node, bool exit) \
0123 { \
0124 RBSTRUCT *child; \
0125 RBTYPE max = RBCOMPUTE(node); \
0126 if (node->RBFIELD.rb_left) { \
0127 child = rb_entry(node->RBFIELD.rb_left, RBSTRUCT, RBFIELD); \
0128 if (child->RBAUGMENTED > max) \
0129 max = child->RBAUGMENTED; \
0130 } \
0131 if (node->RBFIELD.rb_right) { \
0132 child = rb_entry(node->RBFIELD.rb_right, RBSTRUCT, RBFIELD); \
0133 if (child->RBAUGMENTED > max) \
0134 max = child->RBAUGMENTED; \
0135 } \
0136 if (exit && node->RBAUGMENTED == max) \
0137 return true; \
0138 node->RBAUGMENTED = max; \
0139 return false; \
0140 } \
0141 RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
0142 RBSTRUCT, RBFIELD, RBAUGMENTED, RBNAME ## _compute_max)
0143
0144
0145 #define RB_RED 0
0146 #define RB_BLACK 1
0147
0148 #define __rb_parent(pc) ((struct rb_node *)(pc & ~3))
0149
0150 #define __rb_color(pc) ((pc) & 1)
0151 #define __rb_is_black(pc) __rb_color(pc)
0152 #define __rb_is_red(pc) (!__rb_color(pc))
0153 #define rb_color(rb) __rb_color((rb)->__rb_parent_color)
0154 #define rb_is_red(rb) __rb_is_red((rb)->__rb_parent_color)
0155 #define rb_is_black(rb) __rb_is_black((rb)->__rb_parent_color)
0156
0157 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
0158 {
0159 rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
0160 }
0161
0162 static inline void rb_set_parent_color(struct rb_node *rb,
0163 struct rb_node *p, int color)
0164 {
0165 rb->__rb_parent_color = (unsigned long)p | color;
0166 }
0167
0168 static inline void
0169 __rb_change_child(struct rb_node *old, struct rb_node *new,
0170 struct rb_node *parent, struct rb_root *root)
0171 {
0172 if (parent) {
0173 if (parent->rb_left == old)
0174 WRITE_ONCE(parent->rb_left, new);
0175 else
0176 WRITE_ONCE(parent->rb_right, new);
0177 } else
0178 WRITE_ONCE(root->rb_node, new);
0179 }
0180
0181 static inline void
0182 __rb_change_child_rcu(struct rb_node *old, struct rb_node *new,
0183 struct rb_node *parent, struct rb_root *root)
0184 {
0185 if (parent) {
0186 if (parent->rb_left == old)
0187 rcu_assign_pointer(parent->rb_left, new);
0188 else
0189 rcu_assign_pointer(parent->rb_right, new);
0190 } else
0191 rcu_assign_pointer(root->rb_node, new);
0192 }
0193
0194 extern void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
0195 void (*augment_rotate)(struct rb_node *old, struct rb_node *new));
0196
0197 static __always_inline struct rb_node *
0198 __rb_erase_augmented(struct rb_node *node, struct rb_root *root,
0199 const struct rb_augment_callbacks *augment)
0200 {
0201 struct rb_node *child = node->rb_right;
0202 struct rb_node *tmp = node->rb_left;
0203 struct rb_node *parent, *rebalance;
0204 unsigned long pc;
0205
0206 if (!tmp) {
0207
0208
0209
0210
0211
0212
0213
0214 pc = node->__rb_parent_color;
0215 parent = __rb_parent(pc);
0216 __rb_change_child(node, child, parent, root);
0217 if (child) {
0218 child->__rb_parent_color = pc;
0219 rebalance = NULL;
0220 } else
0221 rebalance = __rb_is_black(pc) ? parent : NULL;
0222 tmp = parent;
0223 } else if (!child) {
0224
0225 tmp->__rb_parent_color = pc = node->__rb_parent_color;
0226 parent = __rb_parent(pc);
0227 __rb_change_child(node, tmp, parent, root);
0228 rebalance = NULL;
0229 tmp = parent;
0230 } else {
0231 struct rb_node *successor = child, *child2;
0232
0233 tmp = child->rb_left;
0234 if (!tmp) {
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 parent = successor;
0245 child2 = successor->rb_right;
0246
0247 augment->copy(node, successor);
0248 } else {
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263 do {
0264 parent = successor;
0265 successor = tmp;
0266 tmp = tmp->rb_left;
0267 } while (tmp);
0268 child2 = successor->rb_right;
0269 WRITE_ONCE(parent->rb_left, child2);
0270 WRITE_ONCE(successor->rb_right, child);
0271 rb_set_parent(child, successor);
0272
0273 augment->copy(node, successor);
0274 augment->propagate(parent, successor);
0275 }
0276
0277 tmp = node->rb_left;
0278 WRITE_ONCE(successor->rb_left, tmp);
0279 rb_set_parent(tmp, successor);
0280
0281 pc = node->__rb_parent_color;
0282 tmp = __rb_parent(pc);
0283 __rb_change_child(node, successor, tmp, root);
0284
0285 if (child2) {
0286 rb_set_parent_color(child2, parent, RB_BLACK);
0287 rebalance = NULL;
0288 } else {
0289 rebalance = rb_is_black(successor) ? parent : NULL;
0290 }
0291 successor->__rb_parent_color = pc;
0292 tmp = successor;
0293 }
0294
0295 augment->propagate(tmp, NULL);
0296 return rebalance;
0297 }
0298
0299 static __always_inline void
0300 rb_erase_augmented(struct rb_node *node, struct rb_root *root,
0301 const struct rb_augment_callbacks *augment)
0302 {
0303 struct rb_node *rebalance = __rb_erase_augmented(node, root, augment);
0304 if (rebalance)
0305 __rb_erase_color(rebalance, root, augment->rotate);
0306 }
0307
0308 static __always_inline void
0309 rb_erase_augmented_cached(struct rb_node *node, struct rb_root_cached *root,
0310 const struct rb_augment_callbacks *augment)
0311 {
0312 if (root->rb_leftmost == node)
0313 root->rb_leftmost = rb_next(node);
0314 rb_erase_augmented(node, &root->rb_root, augment);
0315 }
0316
0317 #endif