1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/rbtree_augmented.h>
25#include <linux/export.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47static inline void rb_set_black(struct rb_node *rb)
48{
49 rb->__rb_parent_color |= RB_BLACK;
50}
51
52static inline struct rb_node *rb_red_parent(struct rb_node *red)
53{
54 return (struct rb_node *)red->__rb_parent_color;
55}
56
57
58
59
60
61
62static inline void
63__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new,
64 struct rb_root *root, int color)
65{
66 struct rb_node *parent = rb_parent(old);
67 new->__rb_parent_color = old->__rb_parent_color;
68 rb_set_parent_color(old, new, color);
69 __rb_change_child(old, new, parent, root);
70}
71
72static __always_inline void
73__rb_insert(struct rb_node *node, struct rb_root *root,
74 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
75{
76 struct rb_node *parent = rb_red_parent(node), *gparent, *tmp;
77
78 while (true) {
79
80
81
82
83
84
85
86 if (!parent) {
87 rb_set_parent_color(node, NULL, RB_BLACK);
88 break;
89 } else if (rb_is_black(parent))
90 break;
91
92 gparent = rb_red_parent(parent);
93
94 tmp = gparent->rb_right;
95 if (parent != tmp) {
96 if (tmp && rb_is_red(tmp)) {
97
98
99
100
101
102
103
104
105
106
107
108
109
110 rb_set_parent_color(tmp, gparent, RB_BLACK);
111 rb_set_parent_color(parent, gparent, RB_BLACK);
112 node = gparent;
113 parent = rb_parent(node);
114 rb_set_parent_color(node, parent, RB_RED);
115 continue;
116 }
117
118 tmp = parent->rb_right;
119 if (node == tmp) {
120
121
122
123
124
125
126
127
128
129
130
131
132 parent->rb_right = tmp = node->rb_left;
133 node->rb_left = parent;
134 if (tmp)
135 rb_set_parent_color(tmp, parent,
136 RB_BLACK);
137 rb_set_parent_color(parent, node, RB_RED);
138 augment_rotate(parent, node);
139 parent = node;
140 tmp = node->rb_right;
141 }
142
143
144
145
146
147
148
149
150
151
152 gparent->rb_left = tmp;
153 parent->rb_right = gparent;
154 if (tmp)
155 rb_set_parent_color(tmp, gparent, RB_BLACK);
156 __rb_rotate_set_parents(gparent, parent, root, RB_RED);
157 augment_rotate(gparent, parent);
158 break;
159 } else {
160 tmp = gparent->rb_left;
161 if (tmp && rb_is_red(tmp)) {
162
163 rb_set_parent_color(tmp, gparent, RB_BLACK);
164 rb_set_parent_color(parent, gparent, RB_BLACK);
165 node = gparent;
166 parent = rb_parent(node);
167 rb_set_parent_color(node, parent, RB_RED);
168 continue;
169 }
170
171 tmp = parent->rb_left;
172 if (node == tmp) {
173
174 parent->rb_left = tmp = node->rb_right;
175 node->rb_right = parent;
176 if (tmp)
177 rb_set_parent_color(tmp, parent,
178 RB_BLACK);
179 rb_set_parent_color(parent, node, RB_RED);
180 augment_rotate(parent, node);
181 parent = node;
182 tmp = node->rb_left;
183 }
184
185
186 gparent->rb_right = tmp;
187 parent->rb_left = gparent;
188 if (tmp)
189 rb_set_parent_color(tmp, gparent, RB_BLACK);
190 __rb_rotate_set_parents(gparent, parent, root, RB_RED);
191 augment_rotate(gparent, parent);
192 break;
193 }
194 }
195}
196
197
198
199
200
201static __always_inline void
202____rb_erase_color(struct rb_node *parent, struct rb_root *root,
203 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
204{
205 struct rb_node *node = NULL, *sibling, *tmp1, *tmp2;
206
207 while (true) {
208
209
210
211
212
213
214
215 sibling = parent->rb_right;
216 if (node != sibling) {
217 if (rb_is_red(sibling)) {
218
219
220
221
222
223
224
225
226
227 parent->rb_right = tmp1 = sibling->rb_left;
228 sibling->rb_left = parent;
229 rb_set_parent_color(tmp1, parent, RB_BLACK);
230 __rb_rotate_set_parents(parent, sibling, root,
231 RB_RED);
232 augment_rotate(parent, sibling);
233 sibling = tmp1;
234 }
235 tmp1 = sibling->rb_right;
236 if (!tmp1 || rb_is_black(tmp1)) {
237 tmp2 = sibling->rb_left;
238 if (!tmp2 || rb_is_black(tmp2)) {
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 rb_set_parent_color(sibling, parent,
255 RB_RED);
256 if (rb_is_red(parent))
257 rb_set_black(parent);
258 else {
259 node = parent;
260 parent = rb_parent(node);
261 if (parent)
262 continue;
263 }
264 break;
265 }
266
267
268
269
270
271
272
273
274
275
276
277
278 sibling->rb_left = tmp1 = tmp2->rb_right;
279 tmp2->rb_right = sibling;
280 parent->rb_right = tmp2;
281 if (tmp1)
282 rb_set_parent_color(tmp1, sibling,
283 RB_BLACK);
284 augment_rotate(sibling, tmp2);
285 tmp1 = sibling;
286 sibling = tmp2;
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300 parent->rb_right = tmp2 = sibling->rb_left;
301 sibling->rb_left = parent;
302 rb_set_parent_color(tmp1, sibling, RB_BLACK);
303 if (tmp2)
304 rb_set_parent(tmp2, parent);
305 __rb_rotate_set_parents(parent, sibling, root,
306 RB_BLACK);
307 augment_rotate(parent, sibling);
308 break;
309 } else {
310 sibling = parent->rb_left;
311 if (rb_is_red(sibling)) {
312
313 parent->rb_left = tmp1 = sibling->rb_right;
314 sibling->rb_right = parent;
315 rb_set_parent_color(tmp1, parent, RB_BLACK);
316 __rb_rotate_set_parents(parent, sibling, root,
317 RB_RED);
318 augment_rotate(parent, sibling);
319 sibling = tmp1;
320 }
321 tmp1 = sibling->rb_left;
322 if (!tmp1 || rb_is_black(tmp1)) {
323 tmp2 = sibling->rb_right;
324 if (!tmp2 || rb_is_black(tmp2)) {
325
326 rb_set_parent_color(sibling, parent,
327 RB_RED);
328 if (rb_is_red(parent))
329 rb_set_black(parent);
330 else {
331 node = parent;
332 parent = rb_parent(node);
333 if (parent)
334 continue;
335 }
336 break;
337 }
338
339 sibling->rb_right = tmp1 = tmp2->rb_left;
340 tmp2->rb_left = sibling;
341 parent->rb_left = tmp2;
342 if (tmp1)
343 rb_set_parent_color(tmp1, sibling,
344 RB_BLACK);
345 augment_rotate(sibling, tmp2);
346 tmp1 = sibling;
347 sibling = tmp2;
348 }
349
350 parent->rb_left = tmp2 = sibling->rb_right;
351 sibling->rb_right = parent;
352 rb_set_parent_color(tmp1, sibling, RB_BLACK);
353 if (tmp2)
354 rb_set_parent(tmp2, parent);
355 __rb_rotate_set_parents(parent, sibling, root,
356 RB_BLACK);
357 augment_rotate(parent, sibling);
358 break;
359 }
360 }
361}
362
363
364void __rb_erase_color(struct rb_node *parent, struct rb_root *root,
365 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
366{
367 ____rb_erase_color(parent, root, augment_rotate);
368}
369EXPORT_SYMBOL(__rb_erase_color);
370
371
372
373
374
375
376
377
378static inline void dummy_propagate(struct rb_node *node, struct rb_node *stop) {}
379static inline void dummy_copy(struct rb_node *old, struct rb_node *new) {}
380static inline void dummy_rotate(struct rb_node *old, struct rb_node *new) {}
381
382static const struct rb_augment_callbacks dummy_callbacks = {
383 dummy_propagate, dummy_copy, dummy_rotate
384};
385
386void rb_insert_color(struct rb_node *node, struct rb_root *root)
387{
388 __rb_insert(node, root, dummy_rotate);
389}
390EXPORT_SYMBOL(rb_insert_color);
391
392void rb_erase(struct rb_node *node, struct rb_root *root)
393{
394 struct rb_node *rebalance;
395 rebalance = __rb_erase_augmented(node, root, &dummy_callbacks);
396 if (rebalance)
397 ____rb_erase_color(rebalance, root, dummy_rotate);
398}
399EXPORT_SYMBOL(rb_erase);
400
401
402
403
404
405
406
407
408void __rb_insert_augmented(struct rb_node *node, struct rb_root *root,
409 void (*augment_rotate)(struct rb_node *old, struct rb_node *new))
410{
411 __rb_insert(node, root, augment_rotate);
412}
413EXPORT_SYMBOL(__rb_insert_augmented);
414
415
416
417
418struct rb_node *rb_first(const struct rb_root *root)
419{
420 struct rb_node *n;
421
422 n = root->rb_node;
423 if (!n)
424 return NULL;
425 while (n->rb_left)
426 n = n->rb_left;
427 return n;
428}
429EXPORT_SYMBOL(rb_first);
430
431struct rb_node *rb_last(const struct rb_root *root)
432{
433 struct rb_node *n;
434
435 n = root->rb_node;
436 if (!n)
437 return NULL;
438 while (n->rb_right)
439 n = n->rb_right;
440 return n;
441}
442EXPORT_SYMBOL(rb_last);
443
444struct rb_node *rb_next(const struct rb_node *node)
445{
446 struct rb_node *parent;
447
448 if (RB_EMPTY_NODE(node))
449 return NULL;
450
451
452
453
454
455 if (node->rb_right) {
456 node = node->rb_right;
457 while (node->rb_left)
458 node=node->rb_left;
459 return (struct rb_node *)node;
460 }
461
462
463
464
465
466
467
468
469 while ((parent = rb_parent(node)) && node == parent->rb_right)
470 node = parent;
471
472 return parent;
473}
474EXPORT_SYMBOL(rb_next);
475
476struct rb_node *rb_prev(const struct rb_node *node)
477{
478 struct rb_node *parent;
479
480 if (RB_EMPTY_NODE(node))
481 return NULL;
482
483
484
485
486
487 if (node->rb_left) {
488 node = node->rb_left;
489 while (node->rb_right)
490 node=node->rb_right;
491 return (struct rb_node *)node;
492 }
493
494
495
496
497
498 while ((parent = rb_parent(node)) && node == parent->rb_left)
499 node = parent;
500
501 return parent;
502}
503EXPORT_SYMBOL(rb_prev);
504
505void rb_replace_node(struct rb_node *victim, struct rb_node *new,
506 struct rb_root *root)
507{
508 struct rb_node *parent = rb_parent(victim);
509
510
511 __rb_change_child(victim, new, parent, root);
512 if (victim->rb_left)
513 rb_set_parent(victim->rb_left, new);
514 if (victim->rb_right)
515 rb_set_parent(victim->rb_right, new);
516
517
518 *new = *victim;
519}
520EXPORT_SYMBOL(rb_replace_node);
521
522static struct rb_node *rb_left_deepest_node(const struct rb_node *node)
523{
524 for (;;) {
525 if (node->rb_left)
526 node = node->rb_left;
527 else if (node->rb_right)
528 node = node->rb_right;
529 else
530 return (struct rb_node *)node;
531 }
532}
533
534struct rb_node *rb_next_postorder(const struct rb_node *node)
535{
536 const struct rb_node *parent;
537 if (!node)
538 return NULL;
539 parent = rb_parent(node);
540
541
542 if (parent && node == parent->rb_left && parent->rb_right) {
543
544
545 return rb_left_deepest_node(parent->rb_right);
546 } else
547
548
549 return (struct rb_node *)parent;
550}
551EXPORT_SYMBOL(rb_next_postorder);
552
553struct rb_node *rb_first_postorder(const struct rb_root *root)
554{
555 if (!root->rb_node)
556 return NULL;
557
558 return rb_left_deepest_node(root->rb_node);
559}
560EXPORT_SYMBOL(rb_first_postorder);
561