]> git.karo-electronics.de Git - karo-tx-linux.git/blob - lib/rbtree.c
d0be5fcaafe8e919cd46c4624146656948fbdba9
[karo-tx-linux.git] / lib / rbtree.c
1 /*
2   Red Black Trees
3   (C) 1999  Andrea Arcangeli <andrea@suse.de>
4   (C) 2002  David Woodhouse <dwmw2@infradead.org>
5   
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20   linux/lib/rbtree.c
21 */
22
23 #include <linux/rbtree.h>
24 #include <linux/export.h>
25
26 #define RB_RED          0
27 #define RB_BLACK        1
28
29 #define rb_color(r)   ((r)->__rb_parent_color & 1)
30 #define rb_is_red(r)   (!rb_color(r))
31 #define rb_is_black(r) rb_color(r)
32 #define rb_set_red(r)  do { (r)->__rb_parent_color &= ~1; } while (0)
33 #define rb_set_black(r)  do { (r)->__rb_parent_color |= 1; } while (0)
34
35 static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
36 {
37         rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
38 }
39 static inline void rb_set_color(struct rb_node *rb, int color)
40 {
41         rb->__rb_parent_color = (rb->__rb_parent_color & ~1) | color;
42 }
43
44 static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
45 {
46         struct rb_node *right = node->rb_right;
47         struct rb_node *parent = rb_parent(node);
48
49         if ((node->rb_right = right->rb_left))
50                 rb_set_parent(right->rb_left, node);
51         right->rb_left = node;
52
53         rb_set_parent(right, parent);
54
55         if (parent)
56         {
57                 if (node == parent->rb_left)
58                         parent->rb_left = right;
59                 else
60                         parent->rb_right = right;
61         }
62         else
63                 root->rb_node = right;
64         rb_set_parent(node, right);
65 }
66
67 static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
68 {
69         struct rb_node *left = node->rb_left;
70         struct rb_node *parent = rb_parent(node);
71
72         if ((node->rb_left = left->rb_right))
73                 rb_set_parent(left->rb_right, node);
74         left->rb_right = node;
75
76         rb_set_parent(left, parent);
77
78         if (parent)
79         {
80                 if (node == parent->rb_right)
81                         parent->rb_right = left;
82                 else
83                         parent->rb_left = left;
84         }
85         else
86                 root->rb_node = left;
87         rb_set_parent(node, left);
88 }
89
90 void rb_insert_color(struct rb_node *node, struct rb_root *root)
91 {
92         struct rb_node *parent, *gparent;
93
94         while (true) {
95                 /*
96                  * Loop invariant: node is red
97                  *
98                  * If there is a black parent, we are done.
99                  * Otherwise, take some corrective action as we don't
100                  * want a red root or two consecutive red nodes.
101                  */
102                 parent = rb_parent(node);
103                 if (!parent) {
104                         rb_set_black(node);
105                         break;
106                 } else if (rb_is_black(parent))
107                         break;
108
109                 gparent = rb_parent(parent);
110
111                 if (parent == gparent->rb_left)
112                 {
113                         {
114                                 register struct rb_node *uncle = gparent->rb_right;
115                                 if (uncle && rb_is_red(uncle))
116                                 {
117                                         rb_set_black(uncle);
118                                         rb_set_black(parent);
119                                         rb_set_red(gparent);
120                                         node = gparent;
121                                         continue;
122                                 }
123                         }
124
125                         if (parent->rb_right == node) {
126                                 __rb_rotate_left(parent, root);
127                                 parent = node;
128                         }
129
130                         rb_set_black(parent);
131                         rb_set_red(gparent);
132                         __rb_rotate_right(gparent, root);
133                         break;
134                 } else {
135                         {
136                                 register struct rb_node *uncle = gparent->rb_left;
137                                 if (uncle && rb_is_red(uncle))
138                                 {
139                                         rb_set_black(uncle);
140                                         rb_set_black(parent);
141                                         rb_set_red(gparent);
142                                         node = gparent;
143                                         continue;
144                                 }
145                         }
146
147                         if (parent->rb_left == node) {
148                                 __rb_rotate_right(parent, root);
149                                 parent = node;
150                         }
151
152                         rb_set_black(parent);
153                         rb_set_red(gparent);
154                         __rb_rotate_left(gparent, root);
155                         break;
156                 }
157         }
158 }
159 EXPORT_SYMBOL(rb_insert_color);
160
161 static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
162                              struct rb_root *root)
163 {
164         struct rb_node *other;
165
166         while ((!node || rb_is_black(node)) && node != root->rb_node)
167         {
168                 if (parent->rb_left == node)
169                 {
170                         other = parent->rb_right;
171                         if (rb_is_red(other))
172                         {
173                                 rb_set_black(other);
174                                 rb_set_red(parent);
175                                 __rb_rotate_left(parent, root);
176                                 other = parent->rb_right;
177                         }
178                         if ((!other->rb_left || rb_is_black(other->rb_left)) &&
179                             (!other->rb_right || rb_is_black(other->rb_right)))
180                         {
181                                 rb_set_red(other);
182                                 node = parent;
183                                 parent = rb_parent(node);
184                         }
185                         else
186                         {
187                                 if (!other->rb_right || rb_is_black(other->rb_right))
188                                 {
189                                         rb_set_black(other->rb_left);
190                                         rb_set_red(other);
191                                         __rb_rotate_right(other, root);
192                                         other = parent->rb_right;
193                                 }
194                                 rb_set_color(other, rb_color(parent));
195                                 rb_set_black(parent);
196                                 rb_set_black(other->rb_right);
197                                 __rb_rotate_left(parent, root);
198                                 node = root->rb_node;
199                                 break;
200                         }
201                 }
202                 else
203                 {
204                         other = parent->rb_left;
205                         if (rb_is_red(other))
206                         {
207                                 rb_set_black(other);
208                                 rb_set_red(parent);
209                                 __rb_rotate_right(parent, root);
210                                 other = parent->rb_left;
211                         }
212                         if ((!other->rb_left || rb_is_black(other->rb_left)) &&
213                             (!other->rb_right || rb_is_black(other->rb_right)))
214                         {
215                                 rb_set_red(other);
216                                 node = parent;
217                                 parent = rb_parent(node);
218                         }
219                         else
220                         {
221                                 if (!other->rb_left || rb_is_black(other->rb_left))
222                                 {
223                                         rb_set_black(other->rb_right);
224                                         rb_set_red(other);
225                                         __rb_rotate_left(other, root);
226                                         other = parent->rb_left;
227                                 }
228                                 rb_set_color(other, rb_color(parent));
229                                 rb_set_black(parent);
230                                 rb_set_black(other->rb_left);
231                                 __rb_rotate_right(parent, root);
232                                 node = root->rb_node;
233                                 break;
234                         }
235                 }
236         }
237         if (node)
238                 rb_set_black(node);
239 }
240
241 void rb_erase(struct rb_node *node, struct rb_root *root)
242 {
243         struct rb_node *child, *parent;
244         int color;
245
246         if (!node->rb_left)
247                 child = node->rb_right;
248         else if (!node->rb_right)
249                 child = node->rb_left;
250         else
251         {
252                 struct rb_node *old = node, *left;
253
254                 node = node->rb_right;
255                 while ((left = node->rb_left) != NULL)
256                         node = left;
257
258                 if (rb_parent(old)) {
259                         if (rb_parent(old)->rb_left == old)
260                                 rb_parent(old)->rb_left = node;
261                         else
262                                 rb_parent(old)->rb_right = node;
263                 } else
264                         root->rb_node = node;
265
266                 child = node->rb_right;
267                 parent = rb_parent(node);
268                 color = rb_color(node);
269
270                 if (parent == old) {
271                         parent = node;
272                 } else {
273                         if (child)
274                                 rb_set_parent(child, parent);
275                         parent->rb_left = child;
276
277                         node->rb_right = old->rb_right;
278                         rb_set_parent(old->rb_right, node);
279                 }
280
281                 node->__rb_parent_color = old->__rb_parent_color;
282                 node->rb_left = old->rb_left;
283                 rb_set_parent(old->rb_left, node);
284
285                 goto color;
286         }
287
288         parent = rb_parent(node);
289         color = rb_color(node);
290
291         if (child)
292                 rb_set_parent(child, parent);
293         if (parent)
294         {
295                 if (parent->rb_left == node)
296                         parent->rb_left = child;
297                 else
298                         parent->rb_right = child;
299         }
300         else
301                 root->rb_node = child;
302
303  color:
304         if (color == RB_BLACK)
305                 __rb_erase_color(child, parent, root);
306 }
307 EXPORT_SYMBOL(rb_erase);
308
309 static void rb_augment_path(struct rb_node *node, rb_augment_f func, void *data)
310 {
311         struct rb_node *parent;
312
313 up:
314         func(node, data);
315         parent = rb_parent(node);
316         if (!parent)
317                 return;
318
319         if (node == parent->rb_left && parent->rb_right)
320                 func(parent->rb_right, data);
321         else if (parent->rb_left)
322                 func(parent->rb_left, data);
323
324         node = parent;
325         goto up;
326 }
327
328 /*
329  * after inserting @node into the tree, update the tree to account for
330  * both the new entry and any damage done by rebalance
331  */
332 void rb_augment_insert(struct rb_node *node, rb_augment_f func, void *data)
333 {
334         if (node->rb_left)
335                 node = node->rb_left;
336         else if (node->rb_right)
337                 node = node->rb_right;
338
339         rb_augment_path(node, func, data);
340 }
341 EXPORT_SYMBOL(rb_augment_insert);
342
343 /*
344  * before removing the node, find the deepest node on the rebalance path
345  * that will still be there after @node gets removed
346  */
347 struct rb_node *rb_augment_erase_begin(struct rb_node *node)
348 {
349         struct rb_node *deepest;
350
351         if (!node->rb_right && !node->rb_left)
352                 deepest = rb_parent(node);
353         else if (!node->rb_right)
354                 deepest = node->rb_left;
355         else if (!node->rb_left)
356                 deepest = node->rb_right;
357         else {
358                 deepest = rb_next(node);
359                 if (deepest->rb_right)
360                         deepest = deepest->rb_right;
361                 else if (rb_parent(deepest) != node)
362                         deepest = rb_parent(deepest);
363         }
364
365         return deepest;
366 }
367 EXPORT_SYMBOL(rb_augment_erase_begin);
368
369 /*
370  * after removal, update the tree to account for the removed entry
371  * and any rebalance damage.
372  */
373 void rb_augment_erase_end(struct rb_node *node, rb_augment_f func, void *data)
374 {
375         if (node)
376                 rb_augment_path(node, func, data);
377 }
378 EXPORT_SYMBOL(rb_augment_erase_end);
379
380 /*
381  * This function returns the first node (in sort order) of the tree.
382  */
383 struct rb_node *rb_first(const struct rb_root *root)
384 {
385         struct rb_node  *n;
386
387         n = root->rb_node;
388         if (!n)
389                 return NULL;
390         while (n->rb_left)
391                 n = n->rb_left;
392         return n;
393 }
394 EXPORT_SYMBOL(rb_first);
395
396 struct rb_node *rb_last(const struct rb_root *root)
397 {
398         struct rb_node  *n;
399
400         n = root->rb_node;
401         if (!n)
402                 return NULL;
403         while (n->rb_right)
404                 n = n->rb_right;
405         return n;
406 }
407 EXPORT_SYMBOL(rb_last);
408
409 struct rb_node *rb_next(const struct rb_node *node)
410 {
411         struct rb_node *parent;
412
413         if (RB_EMPTY_NODE(node))
414                 return NULL;
415
416         /* If we have a right-hand child, go down and then left as far
417            as we can. */
418         if (node->rb_right) {
419                 node = node->rb_right; 
420                 while (node->rb_left)
421                         node=node->rb_left;
422                 return (struct rb_node *)node;
423         }
424
425         /* No right-hand children.  Everything down and left is
426            smaller than us, so any 'next' node must be in the general
427            direction of our parent. Go up the tree; any time the
428            ancestor is a right-hand child of its parent, keep going
429            up. First time it's a left-hand child of its parent, said
430            parent is our 'next' node. */
431         while ((parent = rb_parent(node)) && node == parent->rb_right)
432                 node = parent;
433
434         return parent;
435 }
436 EXPORT_SYMBOL(rb_next);
437
438 struct rb_node *rb_prev(const struct rb_node *node)
439 {
440         struct rb_node *parent;
441
442         if (RB_EMPTY_NODE(node))
443                 return NULL;
444
445         /* If we have a left-hand child, go down and then right as far
446            as we can. */
447         if (node->rb_left) {
448                 node = node->rb_left; 
449                 while (node->rb_right)
450                         node=node->rb_right;
451                 return (struct rb_node *)node;
452         }
453
454         /* No left-hand children. Go up till we find an ancestor which
455            is a right-hand child of its parent */
456         while ((parent = rb_parent(node)) && node == parent->rb_left)
457                 node = parent;
458
459         return parent;
460 }
461 EXPORT_SYMBOL(rb_prev);
462
463 void rb_replace_node(struct rb_node *victim, struct rb_node *new,
464                      struct rb_root *root)
465 {
466         struct rb_node *parent = rb_parent(victim);
467
468         /* Set the surrounding nodes to point to the replacement */
469         if (parent) {
470                 if (victim == parent->rb_left)
471                         parent->rb_left = new;
472                 else
473                         parent->rb_right = new;
474         } else {
475                 root->rb_node = new;
476         }
477         if (victim->rb_left)
478                 rb_set_parent(victim->rb_left, new);
479         if (victim->rb_right)
480                 rb_set_parent(victim->rb_right, new);
481
482         /* Copy the pointers/colour from the victim to the replacement */
483         *new = *victim;
484 }
485 EXPORT_SYMBOL(rb_replace_node);