5d24aeb5063a788215eca93a73698f50a68b0bc2
3 (C) 1999 Andrea Arcangeli <andrea@suse.de>
4 (C) 2002 David Woodhouse <dwmw2@infradead.org>
5 (C) 2007 Andre Noll <maan@systemlinux.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /** \file rbtree.c Red-black tree implementation. */
29 static void __rb_rotate_left(struct rb_node
*node
, struct rb_root
*root
)
31 struct rb_node
*right
= node
->rb_right
;
32 struct rb_node
*parent
= rb_parent(node
);
34 if ((node
->rb_right
= right
->rb_left
))
35 rb_set_parent(right
->rb_left
, node
);
36 right
->rb_left
= node
;
38 rb_set_parent(right
, parent
);
42 if (node
== parent
->rb_left
)
43 parent
->rb_left
= right
;
45 parent
->rb_right
= right
;
48 root
->rb_node
= right
;
49 rb_set_parent(node
, right
);
50 right
->size
= node
->size
;
53 node
->size
+= node
->rb_right
->size
;
55 node
->size
+= node
->rb_left
->size
;
58 static void __rb_rotate_right(struct rb_node
*node
, struct rb_root
*root
)
60 struct rb_node
*left
= node
->rb_left
;
61 struct rb_node
*parent
= rb_parent(node
);
63 if ((node
->rb_left
= left
->rb_right
))
64 rb_set_parent(left
->rb_right
, node
);
65 left
->rb_right
= node
;
67 rb_set_parent(left
, parent
);
71 if (node
== parent
->rb_right
)
72 parent
->rb_right
= left
;
74 parent
->rb_left
= left
;
78 rb_set_parent(node
, left
);
79 left
->size
= node
->size
;
82 node
->size
+= node
->rb_right
->size
;
84 node
->size
+= node
->rb_left
->size
;
87 void rb_insert_color(struct rb_node
*node
, struct rb_root
*root
)
89 struct rb_node
*parent
, *gparent
;
91 while ((parent
= rb_parent(node
)) && rb_is_red(parent
))
93 gparent
= rb_parent(parent
);
95 if (parent
== gparent
->rb_left
)
98 register struct rb_node
*uncle
= gparent
->rb_right
;
99 if (uncle
&& rb_is_red(uncle
))
102 rb_set_black(parent
);
109 if (parent
->rb_right
== node
)
111 register struct rb_node
*tmp
;
112 __rb_rotate_left(parent
, root
);
118 rb_set_black(parent
);
120 __rb_rotate_right(gparent
, root
);
123 register struct rb_node
*uncle
= gparent
->rb_left
;
124 if (uncle
&& rb_is_red(uncle
))
127 rb_set_black(parent
);
134 if (parent
->rb_left
== node
)
136 register struct rb_node
*tmp
;
137 __rb_rotate_right(parent
, root
);
143 rb_set_black(parent
);
145 __rb_rotate_left(gparent
, root
);
149 rb_set_black(root
->rb_node
);
152 static void __rb_erase_color(struct rb_node
*node
, struct rb_node
*parent
,
153 struct rb_root
*root
)
155 struct rb_node
*other
;
157 while ((!node
|| rb_is_black(node
)) && node
!= root
->rb_node
)
159 if (parent
->rb_left
== node
)
161 other
= parent
->rb_right
;
162 if (rb_is_red(other
))
166 __rb_rotate_left(parent
, root
);
167 other
= parent
->rb_right
;
169 if ((!other
->rb_left
|| rb_is_black(other
->rb_left
)) &&
170 (!other
->rb_right
|| rb_is_black(other
->rb_right
)))
174 parent
= rb_parent(node
);
178 if (!other
->rb_right
|| rb_is_black(other
->rb_right
))
180 struct rb_node
*o_left
;
181 if ((o_left
= other
->rb_left
))
182 rb_set_black(o_left
);
184 __rb_rotate_right(other
, root
);
185 other
= parent
->rb_right
;
187 rb_set_color(other
, rb_color(parent
));
188 rb_set_black(parent
);
190 rb_set_black(other
->rb_right
);
191 __rb_rotate_left(parent
, root
);
192 node
= root
->rb_node
;
198 other
= parent
->rb_left
;
199 if (rb_is_red(other
))
203 __rb_rotate_right(parent
, root
);
204 other
= parent
->rb_left
;
206 if ((!other
->rb_left
|| rb_is_black(other
->rb_left
)) &&
207 (!other
->rb_right
|| rb_is_black(other
->rb_right
)))
211 parent
= rb_parent(node
);
215 if (!other
->rb_left
|| rb_is_black(other
->rb_left
))
217 register struct rb_node
*o_right
;
218 if ((o_right
= other
->rb_right
))
219 rb_set_black(o_right
);
221 __rb_rotate_left(other
, root
);
222 other
= parent
->rb_left
;
224 rb_set_color(other
, rb_color(parent
));
225 rb_set_black(parent
);
227 rb_set_black(other
->rb_left
);
228 __rb_rotate_right(parent
, root
);
229 node
= root
->rb_node
;
238 void rb_erase(struct rb_node
*node
, struct rb_root
*root
)
240 struct rb_node
*child
, *parent
;
244 child
= node
->rb_right
;
245 else if (!node
->rb_right
)
246 child
= node
->rb_left
;
249 struct rb_node
*old
= node
, *left
;
251 node
= node
->rb_right
;
252 while ((left
= node
->rb_left
) != NULL
)
254 child
= node
->rb_right
;
255 parent
= rb_parent(node
);
256 color
= rb_color(node
);
259 rb_set_parent(child
, parent
);
261 parent
->rb_right
= child
;
264 parent
->rb_left
= child
;
266 node
->rb_parent_color
= old
->rb_parent_color
;
267 node
->rb_right
= old
->rb_right
;
268 node
->rb_left
= old
->rb_left
;
269 node
->size
= old
->size
;
273 if (rb_parent(old
)->rb_left
== old
)
274 rb_parent(old
)->rb_left
= node
;
276 rb_parent(old
)->rb_right
= node
;
278 root
->rb_node
= node
;
280 rb_set_parent(old
->rb_left
, node
);
282 rb_set_parent(old
->rb_right
, node
);
286 parent
= rb_parent(node
);
287 color
= rb_color(node
);
290 rb_set_parent(child
, parent
);
293 if (parent
->rb_left
== node
)
294 parent
->rb_left
= child
;
296 parent
->rb_right
= child
;
299 root
->rb_node
= child
;
302 if (color
== RB_BLACK
)
303 __rb_erase_color(child
, parent
, root
);
307 * This function returns the first node (in sort order) of the tree.
309 struct rb_node
*rb_first(struct rb_root
*root
)
321 struct rb_node
*rb_last(struct rb_root
*root
)
333 struct rb_node
*rb_next(struct rb_node
*node
)
335 struct rb_node
*parent
;
337 if (rb_parent(node
) == node
)
340 /* If we have a right-hand child, go down and then left as far
342 if (node
->rb_right
) {
343 node
= node
->rb_right
;
344 while (node
->rb_left
)
349 /* No right-hand children. Everything down and left is
350 smaller than us, so any 'next' node must be in the general
351 direction of our parent. Go up the tree; any time the
352 ancestor is a right-hand child of its parent, keep going
353 up. First time it's a left-hand child of its parent, said
354 parent is our 'next' node. */
355 while ((parent
= rb_parent(node
)) && node
== parent
->rb_right
)
361 struct rb_node
*rb_prev(struct rb_node
*node
)
363 struct rb_node
*parent
;
365 if (rb_parent(node
) == node
)
368 /* If we have a left-hand child, go down and then right as far
371 node
= node
->rb_left
;
372 while (node
->rb_right
)
377 /* No left-hand children. Go up till we find an ancestor which
378 is a right-hand child of its parent */
379 while ((parent
= rb_parent(node
)) && node
== parent
->rb_left
)
385 void rb_replace_node(struct rb_node
*victim
, struct rb_node
*new,
386 struct rb_root
*root
)
388 struct rb_node
*parent
= rb_parent(victim
);
390 /* Set the surrounding nodes to point to the replacement */
392 if (victim
== parent
->rb_left
)
393 parent
->rb_left
= new;
395 parent
->rb_right
= new;
400 rb_set_parent(victim
->rb_left
, new);
401 if (victim
->rb_right
)
402 rb_set_parent(victim
->rb_right
, new);
404 /* Copy the pointers/colour from the victim to the replacement */
409 * Get the n-th node (in sort order) of the tree.
411 * \param node The root of the subtree to consider.
412 * \param n The order statistic to compute.
414 * \return Pointer to the \a n th greatest node on success, \p NULL on errors.
416 struct rb_node
*rb_nth(struct rb_node
*node
, unsigned n
)
423 size
+= node
->rb_left
->size
;
427 return rb_nth(node
->rb_left
, n
);
428 return rb_nth(node
->rb_right
, n
- size
);
432 * Get the rank of a node in O(log n) time.
434 * \param node The node to get the rank of.
435 * \param rank Result pointer.
437 * \return Positive on success, -1 on errors.
439 int rb_rank(struct rb_node
*node
, unsigned *rank
)
442 struct rb_node
*parent
;
447 *rank
+= node
->rb_left
->size
;
448 while ((parent
= rb_parent(node
))) {
449 if (node
== parent
->rb_right
) {
452 *rank
+= parent
->rb_left
->size
;